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 "timer.h"
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
|
|
||||||
|
int nmi = 0;
|
||||||
|
|
||||||
int nextcyc=0;
|
int nextcyc=0;
|
||||||
int cycdiff;
|
int cycdiff;
|
||||||
int is8086=0;
|
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];
|
char name[50];
|
||||||
void *(*init)();
|
void *(*init)();
|
||||||
void (*close)(void *priv);
|
void (*close)(void *p);
|
||||||
void (*speed_changed)(void *priv);
|
void (*speed_changed)(void *p);
|
||||||
|
int (*add_status_info)(char *s, int max_len, void *p);
|
||||||
} device_t;
|
} device_t;
|
||||||
|
|
||||||
void device_init();
|
void device_init();
|
||||||
void device_add(device_t *d);
|
void device_add(device_t *d);
|
||||||
void device_close_all();
|
void device_close_all();
|
||||||
void device_speed_changed();
|
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))
|
/* 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;
|
// if (val==0x29 && pc==0xD25) output=1;
|
||||||
// }
|
// }
|
||||||
dmapages[addr&0xF]=val;
|
dmapages[addr&0xF]=val;
|
||||||
|
|
@ -258,12 +258,12 @@ uint8_t _dma_read(uint32_t addr)
|
||||||
{
|
{
|
||||||
switch (addr&0xFFFF8000)
|
switch (addr&0xFFFF8000)
|
||||||
{
|
{
|
||||||
case 0xA0000: case 0xA8000:
|
/* case 0xA0000: case 0xA8000:
|
||||||
return video_read_a000(addr, NULL);
|
return video_read_a000(addr, NULL);
|
||||||
case 0xB0000:
|
case 0xB0000:
|
||||||
return video_read_b000(addr, NULL);
|
return video_read_b000(addr, NULL);
|
||||||
case 0xB8000:
|
case 0xB8000:
|
||||||
return video_read_b800(addr, NULL);
|
return video_read_b800(addr, NULL);*/
|
||||||
}
|
}
|
||||||
if (isram[addr>>16]) return ram[addr];
|
if (isram[addr>>16]) return ram[addr];
|
||||||
return 0xff;
|
return 0xff;
|
||||||
|
|
@ -271,9 +271,10 @@ uint8_t _dma_read(uint32_t addr)
|
||||||
|
|
||||||
void _dma_write(uint32_t addr, uint8_t val)
|
void _dma_write(uint32_t addr, uint8_t val)
|
||||||
{
|
{
|
||||||
|
pclog("_dma_write %08X %02X\n", addr, val);
|
||||||
switch (addr&0xFFFF8000)
|
switch (addr&0xFFFF8000)
|
||||||
{
|
{
|
||||||
case 0xA0000: case 0xA8000:
|
/* case 0xA0000: case 0xA8000:
|
||||||
video_write_a000(addr,val, NULL);
|
video_write_a000(addr,val, NULL);
|
||||||
return;
|
return;
|
||||||
case 0xB0000:
|
case 0xB0000:
|
||||||
|
|
@ -284,7 +285,7 @@ void _dma_write(uint32_t addr, uint8_t val)
|
||||||
return;
|
return;
|
||||||
case 0xC0000: case 0xC8000: case 0xD0000: case 0xD8000:
|
case 0xC0000: case 0xC8000: case 0xD0000: case 0xD8000:
|
||||||
case 0xE0000: case 0xE8000: case 0xF0000: case 0xF8000:
|
case 0xE0000: case 0xE8000: case 0xF0000: case 0xF8000:
|
||||||
return;
|
return;*/
|
||||||
}
|
}
|
||||||
if (isram[addr >> 16])
|
if (isram[addr >> 16])
|
||||||
ram[addr] = val;
|
ram[addr] = val;
|
||||||
|
|
|
||||||
269
src/ega.c
269
src/ega.c
|
|
@ -1,217 +1,10 @@
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
#include "video.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()
|
void dumpegaregs()
|
||||||
{
|
{
|
||||||
int c;
|
/* int c;
|
||||||
printf("CRTC :");
|
printf("CRTC :");
|
||||||
for (c=0;c<0x20;c++) printf(" %02X",crtc[c]);
|
for (c=0;c<0x20;c++) printf(" %02X",crtc[c]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
@ -234,64 +27,6 @@ void dumpegaregs()
|
||||||
for (c=0;c<0x10;c++) printf(" %02X",gdcreg[c]);
|
for (c=0;c<0x10;c++) printf(" %02X",gdcreg[c]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
// printf("OLD CTRL2 = %02X NEW CTRL2 = %02X DAC = %02X 3C2 = %02X\n",tridentoldctrl2,tridentnewctrl2,tridentdac,ega3c2);
|
// 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 float isa_timing, bus_timing;
|
||||||
|
|
||||||
extern int frame;
|
extern int frame;
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t *vramp;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "keyboard_amstrad.h"
|
#include "keyboard_amstrad.h"
|
||||||
|
|
@ -31,6 +32,7 @@ static uint8_t amstrad_systemstat_1, amstrad_systemstat_2;
|
||||||
|
|
||||||
void keyboard_amstrad_poll()
|
void keyboard_amstrad_poll()
|
||||||
{
|
{
|
||||||
|
keybsenddelay += (1000 * TIMER_USEC);
|
||||||
if (keyboard_amstrad.wantirq)
|
if (keyboard_amstrad.wantirq)
|
||||||
{
|
{
|
||||||
keyboard_amstrad.wantirq = 0;
|
keyboard_amstrad.wantirq = 0;
|
||||||
|
|
@ -166,4 +168,6 @@ void keyboard_amstrad_init()
|
||||||
keyboard_amstrad_reset();
|
keyboard_amstrad_reset();
|
||||||
keyboard_send = keyboard_amstrad_adddata;
|
keyboard_send = keyboard_amstrad_adddata;
|
||||||
keyboard_poll = keyboard_amstrad_poll;
|
keyboard_poll = keyboard_amstrad_poll;
|
||||||
|
|
||||||
|
timer_add(keyboard_amstrad_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "keyboard_olim24.h"
|
#include "keyboard_olim24.h"
|
||||||
|
|
@ -38,6 +39,7 @@ static uint8_t mouse_scancodes[7];
|
||||||
|
|
||||||
void keyboard_olim24_poll()
|
void keyboard_olim24_poll()
|
||||||
{
|
{
|
||||||
|
keybsenddelay += (1000 * TIMER_USEC);
|
||||||
//pclog("poll %i\n", keyboard_olim24.wantirq);
|
//pclog("poll %i\n", keyboard_olim24.wantirq);
|
||||||
if (keyboard_olim24.wantirq)
|
if (keyboard_olim24.wantirq)
|
||||||
{
|
{
|
||||||
|
|
@ -283,4 +285,6 @@ void keyboard_olim24_init()
|
||||||
keyboard_send = keyboard_olim24_adddata;
|
keyboard_send = keyboard_olim24_adddata;
|
||||||
keyboard_poll = keyboard_olim24_poll;
|
keyboard_poll = keyboard_olim24_poll;
|
||||||
mouse_poll = mouse_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();
|
// sb_reset();
|
||||||
|
|
||||||
ali1429_reset();
|
ali1429_reset();
|
||||||
et4000w32_reset();
|
|
||||||
|
|
||||||
// video_init();
|
// video_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -209,8 +207,8 @@ void initpc()
|
||||||
|
|
||||||
initvideo();
|
initvideo();
|
||||||
mem_init();
|
mem_init();
|
||||||
loadbios();
|
|
||||||
mem_load_video_bios();
|
mem_load_video_bios();
|
||||||
|
loadbios();
|
||||||
|
|
||||||
loaddisc(0,discfns[0]);
|
loaddisc(0,discfns[0]);
|
||||||
loaddisc(1,discfns[1]);
|
loaddisc(1,discfns[1]);
|
||||||
|
|
@ -221,10 +219,8 @@ void initpc()
|
||||||
|
|
||||||
//loadfont();
|
//loadfont();
|
||||||
loadnvr();
|
loadnvr();
|
||||||
resetvideo();
|
|
||||||
sound_init();
|
sound_init();
|
||||||
inithdc();
|
inithdc();
|
||||||
initega();
|
|
||||||
resetide();
|
resetide();
|
||||||
ioctl_open(cdrom_drive);
|
ioctl_open(cdrom_drive);
|
||||||
model_init();
|
model_init();
|
||||||
|
|
@ -244,7 +240,6 @@ void initpc()
|
||||||
/* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed();
|
/* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed();
|
||||||
mem_updatecache();
|
mem_updatecache();
|
||||||
ali1429_reset();
|
ali1429_reset();
|
||||||
et4000w32_reset();
|
|
||||||
// CPUID=(is486 && (cpuspeed==7 || cpuspeed>=9));
|
// CPUID=(is486 && (cpuspeed==7 || cpuspeed>=9));
|
||||||
// pclog("Init - CPUID %i %i\n",CPUID,cpuspeed);
|
// pclog("Init - CPUID %i %i\n",CPUID,cpuspeed);
|
||||||
shadowbios=0;
|
shadowbios=0;
|
||||||
|
|
@ -330,6 +325,7 @@ void runpc()
|
||||||
framecount++;
|
framecount++;
|
||||||
if (framecountx>=100)
|
if (framecountx>=100)
|
||||||
{
|
{
|
||||||
|
pclog("onesec\n");
|
||||||
framecountx=0;
|
framecountx=0;
|
||||||
mips=(float)insc/1000000.0f;
|
mips=(float)insc/1000000.0f;
|
||||||
insc=0;
|
insc=0;
|
||||||
|
|
@ -404,7 +400,6 @@ void closepc()
|
||||||
{
|
{
|
||||||
atapi->exit();
|
atapi->exit();
|
||||||
// ioctl_close();
|
// ioctl_close();
|
||||||
dumpegaregs();
|
|
||||||
dumppic();
|
dumppic();
|
||||||
// output=7;
|
// output=7;
|
||||||
// setpitclock(clocks[0][0][0]);
|
// 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_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_COMBOSND,62,136,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||||
COMBOBOX IDC_COMBOMEM,62,152,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 "CMS / 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 "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 "Machine :",IDC_STATIC,15,16,40,10
|
||||||
LTEXT "Video :",IDC_STATIC,15,36,34,10
|
LTEXT "Video :",IDC_STATIC,15,36,34,10
|
||||||
LTEXT "CPU type :",IDC_STATIC,15,56,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 "6",IDC_STEXT6,16,76,180,10
|
||||||
LTEXT "7",IDC_STEXT7,16,88,180,10
|
LTEXT "7",IDC_STEXT7,16,88,180,10
|
||||||
LTEXT "8",IDC_STEXT8,16,100,180,10
|
LTEXT "8",IDC_STEXT8,16,100,180,10
|
||||||
LTEXT "9",IDC_STEXT9,16,112,180,10
|
LTEXT "9",IDC_STEXT_DEVICE,16,112,180,1000
|
||||||
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
|
|
||||||
END
|
END
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,15 @@ void setpitclock(float clock)
|
||||||
cpuclock=clock;
|
cpuclock=clock;
|
||||||
PITCONST=clock/1193182.0;
|
PITCONST=clock/1193182.0;
|
||||||
CGACONST=(clock/(19687500.0/11.0));
|
CGACONST=(clock/(19687500.0/11.0));
|
||||||
MDACONST=(clock/1813000.0);
|
MDACONST=(clock/2032125.0);
|
||||||
VGACONST1=(clock/25175000.0);
|
VGACONST1=(clock/25175000.0);
|
||||||
VGACONST2=(clock/28322000.0);
|
VGACONST2=(clock/28322000.0);
|
||||||
isa_timing = clock/8000000.0;
|
isa_timing = clock/8000000.0;
|
||||||
bus_timing = clock/(double)cpu_busspeed;
|
bus_timing = clock/(double)cpu_busspeed;
|
||||||
video_updatetiming();
|
video_updatetiming();
|
||||||
// pclog("egacycles %i egacycles2 %i temp %f clock %f\n",egacycles,egacycles2,temp,clock);
|
// 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;
|
RTCCONST=clock/32768.0;
|
||||||
TIMER_USEC = (int)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT));
|
TIMER_USEC = (int)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT));
|
||||||
device_speed_changed();
|
device_speed_changed();
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,4 @@
|
||||||
#define IDC_STEXT6 1105
|
#define IDC_STEXT6 1105
|
||||||
#define IDC_STEXT7 1106
|
#define IDC_STEXT7 1106
|
||||||
#define IDC_STEXT8 1107
|
#define IDC_STEXT8 1107
|
||||||
#define IDC_STEXT9 1108
|
#define IDC_STEXT_DEVICE 1108
|
||||||
#define IDC_STEXT10 1109
|
|
||||||
#define IDC_STEXT11 1110
|
|
||||||
#define IDC_STEXT12 1111
|
|
||||||
#define IDC_STEXT13 1112
|
|
||||||
|
|
|
||||||
|
|
@ -58,5 +58,6 @@ device_t adlib_device =
|
||||||
"AdLib",
|
"AdLib",
|
||||||
adlib_init,
|
adlib_init,
|
||||||
adlib_close,
|
adlib_close,
|
||||||
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -593,5 +593,6 @@ device_t adgold_device =
|
||||||
"AdLib Gold",
|
"AdLib Gold",
|
||||||
adgold_init,
|
adgold_init,
|
||||||
adgold_close,
|
adgold_close,
|
||||||
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -175,5 +175,6 @@ device_t cms_device =
|
||||||
"Creative Music System / Game Blaster",
|
"Creative Music System / Game Blaster",
|
||||||
cms_init,
|
cms_init,
|
||||||
cms_close,
|
cms_close,
|
||||||
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1103,5 +1103,6 @@ device_t gus_device =
|
||||||
"Gravis UltraSound",
|
"Gravis UltraSound",
|
||||||
gus_init,
|
gus_init,
|
||||||
gus_close,
|
gus_close,
|
||||||
gus_speed_changed
|
gus_speed_changed,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -749,5 +749,6 @@ device_t pas16_device =
|
||||||
"Pro Audio Spectrum 16",
|
"Pro Audio Spectrum 16",
|
||||||
pas16_init,
|
pas16_init,
|
||||||
pas16_close,
|
pas16_close,
|
||||||
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -376,40 +376,46 @@ device_t sb_1_device =
|
||||||
"Sound Blaster v1.0",
|
"Sound Blaster v1.0",
|
||||||
sb_1_init,
|
sb_1_init,
|
||||||
sb_close,
|
sb_close,
|
||||||
sb_speed_changed
|
sb_speed_changed,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
device_t sb_15_device =
|
device_t sb_15_device =
|
||||||
{
|
{
|
||||||
"Sound Blaster v1.5",
|
"Sound Blaster v1.5",
|
||||||
sb_15_init,
|
sb_15_init,
|
||||||
sb_close,
|
sb_close,
|
||||||
sb_speed_changed
|
sb_speed_changed,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
device_t sb_2_device =
|
device_t sb_2_device =
|
||||||
{
|
{
|
||||||
"Sound Blaster v2.0",
|
"Sound Blaster v2.0",
|
||||||
sb_2_init,
|
sb_2_init,
|
||||||
sb_close,
|
sb_close,
|
||||||
sb_speed_changed
|
sb_speed_changed,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
device_t sb_pro_v1_device =
|
device_t sb_pro_v1_device =
|
||||||
{
|
{
|
||||||
"Sound Blaster Pro v1",
|
"Sound Blaster Pro v1",
|
||||||
sb_pro_v1_init,
|
sb_pro_v1_init,
|
||||||
sb_close,
|
sb_close,
|
||||||
sb_speed_changed
|
sb_speed_changed,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
device_t sb_pro_v2_device =
|
device_t sb_pro_v2_device =
|
||||||
{
|
{
|
||||||
"Sound Blaster Pro v2",
|
"Sound Blaster Pro v2",
|
||||||
sb_pro_v2_init,
|
sb_pro_v2_init,
|
||||||
sb_close,
|
sb_close,
|
||||||
sb_speed_changed
|
sb_speed_changed,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
device_t sb_16_device =
|
device_t sb_16_device =
|
||||||
{
|
{
|
||||||
"Sound Blaster 16",
|
"Sound Blaster 16",
|
||||||
sb_16_init,
|
sb_16_init,
|
||||||
sb_close,
|
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);
|
pclog("sb_exec_command : SB command %02X\n", dsp->sb_command);
|
||||||
switch (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*/
|
case 0x10: /*8-bit direct mode*/
|
||||||
dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8;
|
dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -194,5 +194,6 @@ device_t sn76489_device =
|
||||||
"TI SN74689 PSG",
|
"TI SN74689 PSG",
|
||||||
sn76489_init,
|
sn76489_init,
|
||||||
sn76489_close,
|
sn76489_close,
|
||||||
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -303,5 +303,6 @@ device_t wss_device =
|
||||||
"Windows Sound System",
|
"Windows Sound System",
|
||||||
wss_init,
|
wss_init,
|
||||||
wss_close,
|
wss_close,
|
||||||
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,142 +1,163 @@
|
||||||
/*ATI 18800 emulation (VGA Edge-16)*/
|
/*ATI 18800 emulation (VGA Edge-16)*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
#include "vid_ati18800.h"
|
||||||
#include "vid_ati_eeprom.h"
|
#include "vid_ati_eeprom.h"
|
||||||
#include "vid_svga.h"
|
#include "vid_svga.h"
|
||||||
|
|
||||||
static uint8_t ati_regs[256];
|
typedef struct ati18800_t
|
||||||
static int ati_index;
|
|
||||||
|
|
||||||
void ati18800_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
|
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;
|
uint8_t old;
|
||||||
|
|
||||||
pclog("ati18800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc);
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x1ce:
|
case 0x1ce:
|
||||||
ati_index = val;
|
ati18800->index = val;
|
||||||
break;
|
break;
|
||||||
case 0x1cf:
|
case 0x1cf:
|
||||||
ati_regs[ati_index] = val;
|
ati18800->regs[ati18800->index] = val;
|
||||||
switch (ati_index)
|
switch (ati18800->index)
|
||||||
{
|
{
|
||||||
case 0xb2:
|
case 0xb2:
|
||||||
case 0xbe:
|
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;
|
svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000;
|
||||||
svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
|
svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000;
|
||||||
}
|
}
|
||||||
else /*Single bank mode*/
|
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;
|
break;
|
||||||
case 0xb3:
|
case 0xb3:
|
||||||
ati_eeprom_write(val & 8, val & 2, val & 1);
|
ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
crtcreg = val & 0x3f;
|
svga->crtcreg = val & 0x3f;
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
||||||
old=crtc[crtcreg];
|
old = svga->crtc[svga->crtcreg];
|
||||||
crtc[crtcreg]=val;
|
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;
|
fullchange = changeframecount;
|
||||||
svga_recalctimings();
|
svga_recalctimings(svga);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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;
|
uint8_t temp;
|
||||||
|
|
||||||
if (addr != 0x3da) pclog("ati18800_in : %04X ", addr);
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x1ce:
|
case 0x1ce:
|
||||||
temp = ati_index;
|
temp = ati18800->index;
|
||||||
break;
|
break;
|
||||||
case 0x1cf:
|
case 0x1cf:
|
||||||
switch (ati_index)
|
switch (ati18800->index)
|
||||||
{
|
{
|
||||||
case 0xb7:
|
case 0xb7:
|
||||||
temp = ati_regs[ati_index] & ~8;
|
temp = ati18800->regs[ati18800->index] & ~8;
|
||||||
if (ati_eeprom_read())
|
if (ati_eeprom_read(&ati18800->eeprom))
|
||||||
temp |= 8;
|
temp |= 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
temp = ati_regs[ati_index];
|
temp = ati18800->regs[ati18800->index];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
temp = crtcreg;
|
temp = svga->crtcreg;
|
||||||
break;
|
break;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
temp = crtc[crtcreg];
|
temp = svga->crtc[svga->crtcreg];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
temp = svga_in(addr, NULL);
|
temp = svga_in(addr, svga);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ati18800_init()
|
void *ati18800_init()
|
||||||
{
|
{
|
||||||
svga_recalctimings_ex = NULL;
|
ati18800_t *ati18800 = malloc(sizeof(ati18800_t));
|
||||||
svga_vram_limit = 1 << 19; /*512kb*/
|
memset(ati18800, 0, sizeof(ati18800_t));
|
||||||
vrammask = 0x7ffff;
|
|
||||||
svgawbank = svgarbank = 0;
|
|
||||||
bpp = 8;
|
|
||||||
svga_miscout = 1;
|
|
||||||
|
|
||||||
io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, NULL);
|
svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/
|
||||||
|
NULL,
|
||||||
|
ati18800_in, ati18800_out,
|
||||||
|
NULL);
|
||||||
|
|
||||||
ati_eeprom_load("ati18800.nvr", 0);
|
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);
|
||||||
|
|
||||||
return svga_init();
|
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,
|
ati18800_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
ati18800_close,
|
||||||
ati18800_out,
|
ati18800_speed_changed,
|
||||||
ati18800_in,
|
svga_add_status_info
|
||||||
/*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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
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)*/
|
/*ATI 28800 emulation (VGA Charger)*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
#include "vid_ati28800.h"
|
||||||
#include "vid_ati_eeprom.h"
|
#include "vid_ati_eeprom.h"
|
||||||
#include "vid_svga.h"
|
#include "vid_svga.h"
|
||||||
#include "vid_svga_render.h"
|
#include "vid_svga_render.h"
|
||||||
|
|
||||||
static uint8_t ati_regs[256];
|
typedef struct ati28800_t
|
||||||
static int ati_index;
|
|
||||||
|
|
||||||
void ati28800_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
|
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;
|
uint8_t old;
|
||||||
|
|
||||||
pclog("ati28800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc);
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x1ce:
|
case 0x1ce:
|
||||||
ati_index = val;
|
ati28800->index = val;
|
||||||
break;
|
break;
|
||||||
case 0x1cf:
|
case 0x1cf:
|
||||||
ati_regs[ati_index] = val;
|
ati28800->regs[ati28800->index] = val;
|
||||||
switch (ati_index)
|
switch (ati28800->index)
|
||||||
{
|
{
|
||||||
case 0xb2:
|
case 0xb2:
|
||||||
case 0xbe:
|
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;
|
svga->read_bank = ((ati28800->regs[0xb2] >> 5) & 7) * 0x10000;
|
||||||
svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
|
svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000;
|
||||||
}
|
}
|
||||||
else /*Single bank mode*/
|
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;
|
break;
|
||||||
case 0xb3:
|
case 0xb3:
|
||||||
ati_eeprom_write(val & 8, val & 2, val & 1);
|
ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
crtcreg = val & 0x3f;
|
svga->crtcreg = val & 0x3f;
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
||||||
old=crtc[crtcreg];
|
old = svga->crtc[svga->crtcreg];
|
||||||
crtc[crtcreg]=val;
|
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;
|
fullchange = changeframecount;
|
||||||
svga_recalctimings();
|
svga_recalctimings(svga);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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;
|
uint8_t temp;
|
||||||
|
|
||||||
if (addr != 0x3da) pclog("ati28800_in : %04X ", addr);
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x1ce:
|
case 0x1ce:
|
||||||
temp = ati_index;
|
temp = ati28800->index;
|
||||||
break;
|
break;
|
||||||
case 0x1cf:
|
case 0x1cf:
|
||||||
switch (ati_index)
|
switch (ati28800->index)
|
||||||
{
|
{
|
||||||
case 0xb7:
|
case 0xb7:
|
||||||
temp = ati_regs[ati_index] & ~8;
|
temp = ati28800->regs[ati28800->index] & ~8;
|
||||||
if (ati_eeprom_read())
|
if (ati_eeprom_read(&ati28800->eeprom))
|
||||||
temp |= 8;
|
temp |= 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
temp = ati_regs[ati_index];
|
temp = ati28800->regs[ati28800->index];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3c2:
|
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;
|
temp = 0;
|
||||||
else
|
else
|
||||||
temp = 0x10;
|
temp = 0x10;
|
||||||
break;
|
break;
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
temp = crtcreg;
|
temp = svga->crtcreg;
|
||||||
break;
|
break;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
temp = crtc[crtcreg];
|
temp = svga->crtc[svga->crtcreg];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
temp = svga_in(addr, NULL);
|
temp = svga_in(addr, svga);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ati28800_recalctimings()
|
void ati28800_recalctimings(svga_t *svga)
|
||||||
{
|
{
|
||||||
|
ati28800_t *ati28800 = (ati28800_t *)svga->p;
|
||||||
pclog("ati28800_recalctimings\n");
|
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");
|
pclog("8bpp_highres\n");
|
||||||
svga_render = svga_render_8bpp_highres;
|
svga->render = svga_render_8bpp_highres;
|
||||||
svga_rowoffset <<= 1;
|
svga->rowoffset <<= 1;
|
||||||
svga_ma <<= 1;
|
svga->ma <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ati28800_init()
|
void *ati28800_init()
|
||||||
{
|
{
|
||||||
svga_recalctimings_ex = ati28800_recalctimings;
|
ati28800_t *ati28800 = malloc(sizeof(ati28800_t));
|
||||||
svga_vram_limit = 1 << 19; /*512kb*/
|
memset(ati28800, 0, sizeof(ati28800_t));
|
||||||
vrammask = 0x7ffff;
|
|
||||||
svgawbank = svgarbank = 0;
|
|
||||||
bpp = 8;
|
|
||||||
svga_miscout = 1;
|
|
||||||
|
|
||||||
io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, NULL);
|
svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/
|
||||||
|
ati28800_recalctimings,
|
||||||
|
ati28800_in, ati28800_out,
|
||||||
|
NULL);
|
||||||
|
|
||||||
ati_eeprom_load("ati28800.nvr", 0);
|
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);
|
||||||
|
|
||||||
return svga_init();
|
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,
|
ati28800_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
ati28800_close,
|
||||||
ati28800_out,
|
ati28800_speed_changed,
|
||||||
ati28800_in,
|
svga_add_status_info
|
||||||
/*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
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
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_svga.h"
|
||||||
#include "vid_ati68860_ramdac.h"
|
#include "vid_ati68860_ramdac.h"
|
||||||
|
|
||||||
static uint8_t ramdac_regs[16];
|
void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga)
|
||||||
void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
// pclog("ati68860_out : addr %04X val %02X %04X:%04X\n", addr, val, CS,pc);
|
// pclog("ati68860_out : addr %04X val %02X %04X:%04X\n", addr, val, CS,pc);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
svga_out(0x3c8, val, NULL);
|
svga_out(0x3c8, val, svga);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
svga_out(0x3c9, val, NULL);
|
svga_out(0x3c9, val, svga);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
svga_out(0x3c6, val, NULL);
|
svga_out(0x3c6, val, svga);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
svga_out(0x3c7, val, NULL);
|
svga_out(0x3c7, val, svga);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ramdac_regs[addr & 0xf] = val;
|
ramdac->regs[addr & 0xf] = val;
|
||||||
break;
|
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;
|
uint8_t ret = 0;
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
ret = svga_in(0x3c8, NULL);
|
ret = svga_in(0x3c8, svga);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
ret = svga_in(0x3c9, NULL);
|
ret = svga_in(0x3c9, svga);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ret = svga_in(0x3c6, NULL);
|
ret = svga_in(0x3c6, svga);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
ret = svga_in(0x3c7, NULL);
|
ret = svga_in(0x3c7, svga);
|
||||||
break;
|
break;
|
||||||
case 4: case 8:
|
case 4: case 8:
|
||||||
ret = 2;
|
ret = 2;
|
||||||
|
|
@ -75,7 +74,7 @@ uint8_t ati68860_ramdac_in(uint16_t addr, void *priv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = ramdac_regs[addr & 0xf];
|
ret = ramdac->regs[addr & 0xf];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// pclog("ati68860_in : addr %04X ret %02X %04X:%04X\n", addr, ret, CS,pc);
|
// 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);
|
typedef struct ati68860_ramdac_t
|
||||||
uint8_t ati68860_ramdac_in(uint16_t addr, void *priv);
|
{
|
||||||
|
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 "ibm.h"
|
||||||
#include "vid_ati_eeprom.h"
|
#include "vid_ati_eeprom.h"
|
||||||
|
|
||||||
static uint16_t eeprom[256];
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
EEPROM_IDLE,
|
EEPROM_IDLE,
|
||||||
|
|
@ -29,201 +28,193 @@ enum
|
||||||
EEPROM_OP_EWEN = 3
|
EEPROM_OP_EWEN = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
static int oldclk, oldena;
|
void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
eeprom_type = type;
|
eeprom->type = type;
|
||||||
strcpy(eeprom_fn, fn);
|
strcpy(eeprom->fn, fn);
|
||||||
f = romfopen(eeprom_fn, "rb");
|
f = romfopen(eeprom->fn, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
memset(eeprom, 0, type ? 512 : 128);
|
memset(eeprom->data, 0, eeprom->type ? 512 : 128);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fread(eeprom, 1, type ? 512 : 128, f);
|
fread(eeprom->data, 1, eeprom->type ? 512 : 128, f);
|
||||||
fclose(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;
|
if (!f) return;
|
||||||
fwrite(eeprom, 1, eeprom_type ? 512 : 128, f);
|
fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f);
|
||||||
fclose(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;
|
int c;
|
||||||
pclog("EEPROM write %i %i %i\n", ena, clk, dat);
|
pclog("EEPROM write %i %i %i\n", ena, clk, dat);
|
||||||
if (!ena)
|
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->state = EEPROM_WAIT;
|
||||||
eeprom_opcode = 0;
|
eeprom->opcode = 0;
|
||||||
eeprom_count = 3;
|
eeprom->count = 3;
|
||||||
eeprom_out = 1;
|
eeprom->out = 1;
|
||||||
}
|
}
|
||||||
else if (ena)
|
else if (ena)
|
||||||
{
|
{
|
||||||
pclog("EEPROM receive %i %i %i\n", ena, clk, dat);
|
pclog("EEPROM receive %i %i %i\n", ena, clk, dat);
|
||||||
switch (eeprom_state)
|
switch (eeprom->state)
|
||||||
{
|
{
|
||||||
case EEPROM_WAIT:
|
case EEPROM_WAIT:
|
||||||
if (!dat)
|
if (!dat)
|
||||||
break;
|
break;
|
||||||
eeprom_state = EEPROM_OPCODE;
|
eeprom->state = EEPROM_OPCODE;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case EEPROM_OPCODE:
|
case EEPROM_OPCODE:
|
||||||
eeprom_opcode = (eeprom_opcode << 1) | (dat ? 1 : 0);
|
eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0);
|
||||||
eeprom_count--;
|
eeprom->count--;
|
||||||
if (!eeprom_count)
|
if (!eeprom->count)
|
||||||
{
|
{
|
||||||
pclog("EEPROM opcode - %i\n", eeprom_opcode);
|
pclog("EEPROM opcode - %i\n", eeprom->opcode);
|
||||||
switch (eeprom_opcode)
|
switch (eeprom->opcode)
|
||||||
{
|
{
|
||||||
case EEPROM_OP_WRITE:
|
case EEPROM_OP_WRITE:
|
||||||
eeprom_count = eeprom_type ? 24 : 22;
|
eeprom->count = eeprom->type ? 24 : 22;
|
||||||
eeprom_state = EEPROM_INPUT;
|
eeprom->state = EEPROM_INPUT;
|
||||||
eeprom_dat = 0;
|
eeprom->dat = 0;
|
||||||
break;
|
break;
|
||||||
case EEPROM_OP_READ:
|
case EEPROM_OP_READ:
|
||||||
eeprom_count = eeprom_type ? 8 : 6;
|
eeprom->count = eeprom->type ? 8 : 6;
|
||||||
eeprom_state = EEPROM_INPUT;
|
eeprom->state = EEPROM_INPUT;
|
||||||
eeprom_dat = 0;
|
eeprom->dat = 0;
|
||||||
break;
|
break;
|
||||||
case EEPROM_OP_EW:
|
case EEPROM_OP_EW:
|
||||||
eeprom_count = 2;
|
eeprom->count = 2;
|
||||||
eeprom_state = EEPROM_INPUT;
|
eeprom->state = EEPROM_INPUT;
|
||||||
eeprom_dat = 0;
|
eeprom->dat = 0;
|
||||||
break;
|
break;
|
||||||
case EEPROM_OP_ERASE:
|
case EEPROM_OP_ERASE:
|
||||||
eeprom_count = eeprom_type ? 8 : 6;
|
eeprom->count = eeprom->type ? 8 : 6;
|
||||||
eeprom_state = EEPROM_INPUT;
|
eeprom->state = EEPROM_INPUT;
|
||||||
eeprom_dat = 0;
|
eeprom->dat = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EEPROM_INPUT:
|
case EEPROM_INPUT:
|
||||||
eeprom_dat = (eeprom_dat << 1) | (dat ? 1 : 0);
|
eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0);
|
||||||
eeprom_count--;
|
eeprom->count--;
|
||||||
if (!eeprom_count)
|
if (!eeprom->count)
|
||||||
{
|
{
|
||||||
pclog("EEPROM dat - %02X\n", eeprom_dat);
|
pclog("EEPROM dat - %02X\n", eeprom->dat);
|
||||||
switch (eeprom_opcode)
|
switch (eeprom->opcode)
|
||||||
{
|
{
|
||||||
case EEPROM_OP_WRITE:
|
case EEPROM_OP_WRITE:
|
||||||
pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom_dat >> 16) & (eeprom_type ? 255 : 63), eeprom_dat & 0xffff);
|
pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom->dat >> 16) & (eeprom->type ? 255 : 63), eeprom->dat & 0xffff);
|
||||||
if (!eeprom_wp)
|
if (!eeprom->wp)
|
||||||
{
|
{
|
||||||
eeprom[(eeprom_dat >> 16) & (eeprom_type ? 255 : 63)] = eeprom_dat & 0xffff;
|
eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff;
|
||||||
ati_eeprom_save();
|
ati_eeprom_save(eeprom);
|
||||||
}
|
}
|
||||||
eeprom_state = EEPROM_IDLE;
|
eeprom->state = EEPROM_IDLE;
|
||||||
eeprom_out = 1;
|
eeprom->out = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EEPROM_OP_READ:
|
case EEPROM_OP_READ:
|
||||||
eeprom_count = 17;
|
eeprom->count = 17;
|
||||||
eeprom_state = EEPROM_OUTPUT;
|
eeprom->state = EEPROM_OUTPUT;
|
||||||
eeprom_dat = eeprom[eeprom_dat];
|
eeprom->dat = eeprom->data[eeprom->dat];
|
||||||
pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom_dat);
|
pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom->dat);
|
||||||
break;
|
break;
|
||||||
case EEPROM_OP_EW:
|
case EEPROM_OP_EW:
|
||||||
pclog("EEPROM_OP_EW %i\n", eeprom_dat);
|
pclog("EEPROM_OP_EW %i\n", eeprom->dat);
|
||||||
switch (eeprom_dat)
|
switch (eeprom->dat)
|
||||||
{
|
{
|
||||||
case EEPROM_OP_EWDS:
|
case EEPROM_OP_EWDS:
|
||||||
eeprom_wp = 1;
|
eeprom->wp = 1;
|
||||||
break;
|
break;
|
||||||
case EEPROM_OP_WRAL:
|
case EEPROM_OP_WRAL:
|
||||||
opcode = EEPROM_OP_WRALMAIN;
|
eeprom->opcode = EEPROM_OP_WRALMAIN;
|
||||||
eeprom_count = 20;
|
eeprom->count = 20;
|
||||||
break;
|
break;
|
||||||
case EEPROM_OP_ERAL:
|
case EEPROM_OP_ERAL:
|
||||||
if (!eeprom_wp)
|
if (!eeprom->wp)
|
||||||
{
|
{
|
||||||
memset(eeprom, 0xff, 128);
|
memset(eeprom->data, 0xff, 128);
|
||||||
ati_eeprom_save();
|
ati_eeprom_save(eeprom);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EEPROM_OP_EWEN:
|
case EEPROM_OP_EWEN:
|
||||||
eeprom_wp = 0;
|
eeprom->wp = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
eeprom_state = EEPROM_IDLE;
|
eeprom->state = EEPROM_IDLE;
|
||||||
eeprom_out = 1;
|
eeprom->out = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EEPROM_OP_ERASE:
|
case EEPROM_OP_ERASE:
|
||||||
pclog("EEPROM_OP_ERASE %i\n", eeprom_dat);
|
pclog("EEPROM_OP_ERASE %i\n", eeprom->dat);
|
||||||
if (!eeprom_wp)
|
if (!eeprom->wp)
|
||||||
{
|
{
|
||||||
eeprom[eeprom_dat] = 0xffff;
|
eeprom->data[eeprom->dat] = 0xffff;
|
||||||
ati_eeprom_save();
|
ati_eeprom_save(eeprom);
|
||||||
}
|
}
|
||||||
eeprom_state = EEPROM_IDLE;
|
eeprom->state = EEPROM_IDLE;
|
||||||
eeprom_out = 1;
|
eeprom->out = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EEPROM_OP_WRALMAIN:
|
case EEPROM_OP_WRALMAIN:
|
||||||
pclog("EEPROM_OP_WRAL %04X\n", eeprom_dat);
|
pclog("EEPROM_OP_WRAL %04X\n", eeprom->dat);
|
||||||
if (!eeprom_wp)
|
if (!eeprom->wp)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 256; c++)
|
for (c = 0; c < 256; c++)
|
||||||
eeprom[c] = eeprom_dat;
|
eeprom->data[c] = eeprom->dat;
|
||||||
ati_eeprom_save();
|
ati_eeprom_save(eeprom);
|
||||||
}
|
}
|
||||||
eeprom_state = EEPROM_IDLE;
|
eeprom->state = EEPROM_IDLE;
|
||||||
eeprom_out = 1;
|
eeprom->out = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
oldena = ena;
|
eeprom->oldena = ena;
|
||||||
}
|
}
|
||||||
else if (!clk && oldclk)
|
else if (!clk && eeprom->oldclk)
|
||||||
{
|
{
|
||||||
if (ena)
|
if (ena)
|
||||||
{
|
{
|
||||||
switch (eeprom_state)
|
switch (eeprom->state)
|
||||||
{
|
{
|
||||||
case EEPROM_OUTPUT:
|
case EEPROM_OUTPUT:
|
||||||
eeprom_out = (eeprom_dat & 0x10000) ? 1 : 0;
|
eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0;
|
||||||
eeprom_dat <<= 1;
|
eeprom->dat <<= 1;
|
||||||
pclog("EEPROM_OUTPUT - data %i\n", eeprom_out);
|
pclog("EEPROM_OUTPUT - data %i\n", eeprom->out);
|
||||||
eeprom_count--;
|
eeprom->count--;
|
||||||
if (!eeprom_count)
|
if (!eeprom->count)
|
||||||
{
|
{
|
||||||
pclog("EEPROM_OUTPUT complete\n");
|
pclog("EEPROM_OUTPUT complete\n");
|
||||||
eeprom_state = EEPROM_IDLE;
|
eeprom->state = EEPROM_IDLE;
|
||||||
}
|
}
|
||||||
break;
|
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);
|
typedef struct ati_eeprom_t
|
||||||
void ati_eeprom_write(int ena, int clk, int dat);
|
{
|
||||||
int ati_eeprom_read();
|
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);
|
||||||
|
|
|
||||||
1211
src/vid_ati_mach64.c
1211
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;
|
||||||
417
src/vid_cga.c
417
src/vid_cga.c
|
|
@ -1,110 +1,115 @@
|
||||||
/*CGA emulation*/
|
/*CGA emulation*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vid_cga.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;
|
uint8_t old;
|
||||||
// pclog("CGA_OUT %04X %02X\n", addr, val);
|
// pclog("CGA_OUT %04X %02X\n", addr, val);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
crtcreg=val&31;
|
cga->crtcreg = val & 31;
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
old=crtc[crtcreg];
|
old = cga->crtc[cga->crtcreg];
|
||||||
crtc[crtcreg]=val&crtcmask[crtcreg];
|
cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
|
||||||
if (old != val)
|
if (old != val)
|
||||||
{
|
{
|
||||||
if (crtcreg<0xE || crtcreg>0x10)
|
if (cga->crtcreg < 0xe || cga->crtcreg > 0x10)
|
||||||
{
|
{
|
||||||
fullchange = changeframecount;
|
fullchange = changeframecount;
|
||||||
cga_recalctimings();
|
cga_recalctimings(cga);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x3D8:
|
case 0x3D8:
|
||||||
cgamode=val;
|
cga->cgamode = val;
|
||||||
return;
|
return;
|
||||||
case 0x3D9:
|
case 0x3D9:
|
||||||
cgacol=val;
|
cga->cgacol = val;
|
||||||
return;
|
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);
|
// pclog("CGA_IN %04X\n", addr);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
return crtcreg;
|
return cga->crtcreg;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
return crtc[crtcreg];
|
return cga->crtc[cga->crtcreg];
|
||||||
case 0x3DA:
|
case 0x3DA:
|
||||||
return cgastat;
|
return cga->cgastat;
|
||||||
}
|
}
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern uint8_t charbuffer[256];
|
void cga_write(uint32_t addr, uint8_t val, void *p)
|
||||||
|
|
||||||
void cga_write(uint32_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
|
cga_t *cga = (cga_t *)p;
|
||||||
// pclog("CGA_WRITE %04X %02X\n", addr, val);
|
// pclog("CGA_WRITE %04X %02X\n", addr, val);
|
||||||
vram[addr&0x3FFF]=val;
|
cga->vram[addr & 0x3fff] = val;
|
||||||
charbuffer[ ((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc] = val;
|
cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = val;
|
||||||
charbuffer[(((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val;
|
cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val;
|
||||||
cycles -= 4;
|
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;
|
cycles -= 4;
|
||||||
charbuffer[ ((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc] = vram[addr&0x3FFF];
|
cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = cga->vram[addr & 0x3fff];
|
||||||
charbuffer[(((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc) | 1] = vram[addr&0x3FFF];
|
cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = cga->vram[addr & 0x3fff];
|
||||||
// pclog("CGA_READ %04X\n", addr);
|
// 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;
|
double _dispontime, _dispofftime;
|
||||||
pclog("Recalc - %i %i %i\n", crtc[0], crtc[1], cgamode & 1);
|
pclog("Recalc - %i %i %i\n", cga->crtc[0], cga->crtc[1], cga->cgamode & 1);
|
||||||
if (cgamode&1)
|
if (cga->cgamode & 1)
|
||||||
{
|
{
|
||||||
disptime=crtc[0]+1;
|
disptime = cga->crtc[0] + 1;
|
||||||
_dispontime=crtc[1];
|
_dispontime = cga->crtc[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
disptime=(crtc[0]+1)<<1;
|
disptime = (cga->crtc[0] + 1) << 1;
|
||||||
_dispontime=crtc[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]);
|
// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
|
||||||
_dispontime *= CGACONST;
|
_dispontime *= CGACONST;
|
||||||
_dispofftime *= 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);
|
// 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));
|
cga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||||
dispofftime = (int)(_dispofftime * (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]=
|
static int ntsc_col[8][8]=
|
||||||
{
|
{
|
||||||
{0,0,0,0,0,0,0,0}, /*Black*/
|
{0,0,0,0,0,0,0,0}, /*Black*/
|
||||||
|
|
@ -117,12 +122,10 @@ static int ntsc_col[8][8]=
|
||||||
{1,1,1,1,1,1,1,1} /*White*/
|
{1,1,1,1,1,1,1,1} /*White*/
|
||||||
};
|
};
|
||||||
|
|
||||||
int i_filt[8],q_filt[8];
|
void cga_poll(void *p)
|
||||||
|
|
||||||
|
|
||||||
void cga_poll()
|
|
||||||
{
|
{
|
||||||
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 drawcursor;
|
||||||
int x, c;
|
int x, c;
|
||||||
int oldvc;
|
int oldvc;
|
||||||
|
|
@ -135,49 +138,50 @@ void cga_poll()
|
||||||
int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_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 q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot;
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
if (!linepos)
|
if (!cga->linepos)
|
||||||
{
|
{
|
||||||
vidtime+=dispofftime;
|
cga->vidtime += cga->dispofftime;
|
||||||
cgastat|=1;
|
cga->cgastat |= 1;
|
||||||
linepos=1;
|
cga->linepos = 1;
|
||||||
oldsc=sc;
|
oldsc = cga->sc;
|
||||||
if ((crtc[8] & 3) == 3)
|
if ((cga->crtc[8] & 3) == 3)
|
||||||
sc = ((sc << 1) + oddeven) & 7;
|
cga->sc = ((cga->sc << 1) + cga->oddeven) & 7;
|
||||||
if (cgadispon)
|
if (cga->cgadispon)
|
||||||
{
|
{
|
||||||
if (displine<firstline)
|
if (cga->displine < cga->firstline)
|
||||||
{
|
{
|
||||||
firstline=displine;
|
cga->firstline = cga->displine;
|
||||||
// printf("Firstline %i\n",firstline);
|
// printf("Firstline %i\n",firstline);
|
||||||
}
|
}
|
||||||
lastline=displine;
|
cga->lastline = cga->displine;
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
{
|
{
|
||||||
if ((cgamode&0x12)==0x12)
|
if ((cga->cgamode & 0x12) == 0x12)
|
||||||
{
|
{
|
||||||
buffer->line[displine][c]=0;
|
buffer->line[cga->displine][c] = 0;
|
||||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
|
if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = 0;
|
||||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=0;
|
else buffer->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buffer->line[displine][c]=(cgacol&15)+16;
|
buffer->line[cga->displine][c] = (cga->cgacol & 15) + 16;
|
||||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16;
|
if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16;
|
||||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=(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];
|
chr = cga->charbuffer[x << 1];
|
||||||
attr=charbuffer[(x<<1)+1];
|
attr = cga->charbuffer[(x << 1) + 1];
|
||||||
drawcursor=((ma==ca) && con && cursoron);
|
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||||
if (cgamode&0x20)
|
if (cga->cgamode & 0x20)
|
||||||
{
|
{
|
||||||
cols[1] = (attr & 15) + 16;
|
cols[1] = (attr & 15) + 16;
|
||||||
cols[0] = ((attr >> 4) & 7) + 16;
|
cols[0] = ((attr >> 4) & 7) + 16;
|
||||||
if ((cgablink&8) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
|
if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor)
|
||||||
|
cols[1] = cols[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -187,58 +191,58 @@ void cga_poll()
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15;
|
buffer->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
|
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)];
|
chr = cga->vram[((cga->ma << 1) & 0x3fff)];
|
||||||
attr=vram[(((ma<<1)+1)&0x3FFF)];
|
attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)];
|
||||||
drawcursor=((ma==ca) && con && cursoron);
|
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||||
if (cgamode&0x20)
|
if (cga->cgamode & 0x20)
|
||||||
{
|
{
|
||||||
cols[1] = (attr & 15) + 16;
|
cols[1] = (attr & 15) + 16;
|
||||||
cols[0] = ((attr >> 4) & 7) + 16;
|
cols[0] = ((attr >> 4) & 7) + 16;
|
||||||
if ((cgablink&8) && (attr&0x80)) cols[1]=cols[0];
|
if ((cga->cgablink & 8) && (attr & 0x80)) cols[1] = cols[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cols[1] = (attr & 15) + 16;
|
cols[1] = (attr & 15) + 16;
|
||||||
cols[0] = (attr >> 4) + 16;
|
cols[0] = (attr >> 4) + 16;
|
||||||
}
|
}
|
||||||
ma++;
|
cga->ma++;
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
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;
|
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
|
else
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
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];
|
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;
|
cols[0] = (cga->cgacol & 15) | 16;
|
||||||
col=(cgacol&16)?24:16;
|
col = (cga->cgacol & 16) ? 24 : 16;
|
||||||
if (cgamode&4)
|
if (cga->cgamode & 4)
|
||||||
{
|
{
|
||||||
cols[1] = col | 3;
|
cols[1] = col | 3;
|
||||||
cols[2] = col | 4;
|
cols[2] = col | 4;
|
||||||
cols[3] = col | 7;
|
cols[3] = col | 7;
|
||||||
}
|
}
|
||||||
else if (cgacol&32)
|
else if (cga->cgacol & 32)
|
||||||
{
|
{
|
||||||
cols[1] = col | 3;
|
cols[1] = col | 3;
|
||||||
cols[2] = col | 5;
|
cols[2] = col | 5;
|
||||||
|
|
@ -250,28 +254,28 @@ void cga_poll()
|
||||||
cols[2] = col | 4;
|
cols[2] = col | 4;
|
||||||
cols[3] = col | 6;
|
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];
|
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||||
ma++;
|
cga->ma++;
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
{
|
{
|
||||||
buffer->line[displine][(x<<4)+(c<<1)+8]=
|
buffer->line[cga->displine][(x << 4) + (c << 1) + 8] =
|
||||||
buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
|
buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||||
dat <<= 2;
|
dat <<= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cols[0]=0; cols[1]=(cgacol&15)+16;
|
cols[0] = 0; cols[1] = (cga->cgacol & 15) + 16;
|
||||||
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];
|
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||||
ma++;
|
cga->ma++;
|
||||||
for (c = 0; c < 16; c++)
|
for (c = 0; c < 16; c++)
|
||||||
{
|
{
|
||||||
buffer->line[displine][(x<<4)+c+8]=cols[dat>>15];
|
buffer->line[cga->displine][(x << 4) + c + 8] = cols[dat >> 15];
|
||||||
dat <<= 1;
|
dat <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -279,19 +283,19 @@ void cga_poll()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16;
|
cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16;
|
||||||
if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
|
if (cga->cgamode & 1) hline(buffer, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]);
|
||||||
else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
|
else hline(buffer, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cgamode&1) x=(crtc[1]<<3)+16;
|
if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
|
||||||
else x=(crtc[1]<<4)+16;
|
else x = (cga->crtc[1] << 4) + 16;
|
||||||
if (cga_comp)
|
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] = ntsc_col[buffer->line[cga->displine][c] & 7][(c << 1) & 6] ? 0x6000 : 0;
|
||||||
y_buf[(c<<1)&6]+=(buffer->line[displine][c]&8)?0x3000: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];
|
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];
|
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];
|
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];
|
||||||
|
|
@ -312,8 +316,8 @@ void cga_poll()
|
||||||
g = (y_val - 70*i_val - 166*q_val) >> 16;
|
g = (y_val - 70*i_val - 166*q_val) >> 16;
|
||||||
b = (y_val - 283*i_val + 436*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] = ntsc_col[buffer->line[cga->displine][c] & 7][((c << 1) & 6) + 1] ? 0x6000 : 0;
|
||||||
y_buf[((c<<1)&6)+1]+=(buffer->line[displine][c]&8)?0x3000: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];
|
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];
|
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];
|
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];
|
||||||
|
|
@ -330,84 +334,90 @@ void cga_poll()
|
||||||
if (q_val > 34249) q_val = 34249;
|
if (q_val > 34249) q_val = 34249;
|
||||||
if (q_val < -34249) q_val = -34249;
|
if (q_val < -34249) q_val = -34249;
|
||||||
|
|
||||||
r+=(y_val+249*i_val+159*q_val)>>16;
|
r = (y_val + 249*i_val + 159*q_val) >> 16;
|
||||||
g+=(y_val-70*i_val-166*q_val)>>16;
|
g = (y_val - 70*i_val - 166*q_val) >> 16;
|
||||||
b+=(y_val-283*i_val+436*q_val)>>16;
|
b = (y_val - 283*i_val + 436*q_val) >> 16;
|
||||||
if (r > 511) r = 511;
|
if (r > 511) r = 511;
|
||||||
if (g > 511) g = 511;
|
if (g > 511) g = 511;
|
||||||
if (b > 511) b = 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;
|
cga->sc = oldsc;
|
||||||
if (vc==crtc[7] && !sc)
|
if (cga->vc == cga->crtc[7] && !cga->sc)
|
||||||
cgastat|=8;
|
cga->cgastat |= 8;
|
||||||
displine++;
|
cga->displine++;
|
||||||
if (displine>=360) displine=0;
|
if (cga->displine >= 360)
|
||||||
|
cga->displine = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vidtime+=dispontime;
|
cga->vidtime += cga->dispontime;
|
||||||
if (cgadispon) cgastat&=~1;
|
if (cga->cgadispon) cga->cgastat &= ~1;
|
||||||
linepos=0;
|
cga->linepos = 0;
|
||||||
if (vsynctime)
|
if (cga->vsynctime)
|
||||||
{
|
{
|
||||||
vsynctime--;
|
cga->vsynctime--;
|
||||||
if (!vsynctime)
|
if (!cga->vsynctime)
|
||||||
cgastat&=~8;
|
cga->cgastat &= ~8;
|
||||||
}
|
}
|
||||||
if (sc==(crtc[11]&31) || ((crtc[8]&3)==3 && sc==((crtc[11]&31)>>1))) { con=0; coff=1; }
|
if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1)))
|
||||||
if ((crtc[8] & 3) == 3 && sc == (crtc[9] >> 1))
|
|
||||||
maback = ma;
|
|
||||||
if (vadj)
|
|
||||||
{
|
{
|
||||||
sc++;
|
cga->con = 0;
|
||||||
sc&=31;
|
cga->coff = 1;
|
||||||
ma=maback;
|
}
|
||||||
vadj--;
|
if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1))
|
||||||
if (!vadj)
|
cga->maback = cga->ma;
|
||||||
|
if (cga->vadj)
|
||||||
{
|
{
|
||||||
cgadispon=1;
|
cga->sc++;
|
||||||
ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
cga->sc &= 31;
|
||||||
sc=0;
|
cga->ma = cga->maback;
|
||||||
|
cga->vadj--;
|
||||||
|
if (!cga->vadj)
|
||||||
|
{
|
||||||
|
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;
|
cga->maback = cga->ma;
|
||||||
sc=0;
|
cga->sc = 0;
|
||||||
oldvc=vc;
|
oldvc = cga->vc;
|
||||||
vc++;
|
cga->vc++;
|
||||||
vc&=127;
|
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;
|
cga->vc = 0;
|
||||||
vadj=crtc[5];
|
cga->vadj = cga->crtc[5];
|
||||||
if (!vadj) cgadispon=1;
|
if (!cga->vadj) cga->cgadispon = 1;
|
||||||
if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
if (!cga->vadj) cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||||
if ((crtc[10]&0x60)==0x20) cursoron=0;
|
if ((cga->crtc[10] & 0x60) == 0x20) cga->cursoron = 0;
|
||||||
else cursoron=cgablink&8;
|
else cga->cursoron = cga->cgablink & 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vc==crtc[7])
|
if (cga->vc == cga->crtc[7])
|
||||||
{
|
{
|
||||||
cgadispon=0;
|
cga->cgadispon = 0;
|
||||||
displine=0;
|
cga->displine = 0;
|
||||||
vsynctime=(crtc[3]>>4)+1;
|
cga->vsynctime = (cga->crtc[3] >> 4) + 1;
|
||||||
if (crtc[7])
|
if (cga->crtc[7])
|
||||||
{
|
{
|
||||||
if (cgamode&1) x=(crtc[1]<<3)+16;
|
if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
|
||||||
else x=(crtc[1]<<4)+16;
|
else x = (cga->crtc[1] << 4) + 16;
|
||||||
lastline++;
|
cga->lastline++;
|
||||||
if (x!=xsize || (lastline-firstline)!=ysize)
|
if (x != xsize || (cga->lastline - cga->firstline) != ysize)
|
||||||
{
|
{
|
||||||
xsize = x;
|
xsize = x;
|
||||||
ysize=lastline-firstline;
|
ysize = cga->lastline - cga->firstline;
|
||||||
if (xsize < 64) xsize = 656;
|
if (xsize < 64) xsize = 656;
|
||||||
if (ysize < 32) ysize = 200;
|
if (ysize < 32) ysize = 200;
|
||||||
updatewindowsize(xsize, (ysize << 1) + 16);
|
updatewindowsize(xsize, (ysize << 1) + 16);
|
||||||
|
|
@ -415,28 +425,28 @@ void cga_poll()
|
||||||
|
|
||||||
startblit();
|
startblit();
|
||||||
if (cga_comp)
|
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
|
else
|
||||||
video_blit_memtoscreen_8(0, firstline-4, xsize, (lastline-firstline)+8);
|
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);
|
if (readflash) rectfill(screen, winsizex - 40, 8, winsizex - 8, 14, 0xffffffff);
|
||||||
readflash = 0;
|
readflash = 0;
|
||||||
frames++;
|
frames++;
|
||||||
endblit();
|
endblit();
|
||||||
video_res_x = xsize - 16;
|
video_res_x = xsize - 16;
|
||||||
video_res_y = ysize;
|
video_res_y = ysize;
|
||||||
if (cgamode & 1)
|
if (cga->cgamode & 1)
|
||||||
{
|
{
|
||||||
video_res_x /= 8;
|
video_res_x /= 8;
|
||||||
video_res_y /= crtc[9] + 1;
|
video_res_y /= cga->crtc[9] + 1;
|
||||||
video_bpp = 0;
|
video_bpp = 0;
|
||||||
}
|
}
|
||||||
else if (!(cgamode & 2))
|
else if (!(cga->cgamode & 2))
|
||||||
{
|
{
|
||||||
video_res_x /= 16;
|
video_res_x /= 16;
|
||||||
video_res_y /= crtc[9] + 1;
|
video_res_y /= cga->crtc[9] + 1;
|
||||||
video_bpp = 0;
|
video_bpp = 0;
|
||||||
}
|
}
|
||||||
else if (!(cgamode&16))
|
else if (!(cga->cgamode & 16))
|
||||||
{
|
{
|
||||||
video_res_x /= 2;
|
video_res_x /= 2;
|
||||||
video_bpp = 2;
|
video_bpp = 2;
|
||||||
|
|
@ -446,59 +456,72 @@ endblit();
|
||||||
video_bpp = 1;
|
video_bpp = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
firstline=1000;
|
cga->firstline = 1000;
|
||||||
lastline=0;
|
cga->lastline = 0;
|
||||||
cgablink++;
|
cga->cgablink++;
|
||||||
oddeven ^= 1;
|
cga->oddeven ^= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sc++;
|
cga->sc++;
|
||||||
sc&=31;
|
cga->sc &= 31;
|
||||||
ma=maback;
|
cga->ma = cga->maback;
|
||||||
}
|
}
|
||||||
if ((sc==(crtc[10]&31) || ((crtc[8]&3)==3 && sc==((crtc[10]&31)>>1)))) con=1;
|
if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))))
|
||||||
if (cgadispon && (cgamode&1))
|
cga->con = 1;
|
||||||
|
if (cga->cgadispon && (cga->cgamode & 1))
|
||||||
{
|
{
|
||||||
for (x=0;x<(crtc[1]<<1);x++)
|
for (x = 0; x < (cga->crtc[1] << 1); x++)
|
||||||
charbuffer[x]=vram[(((ma<<1)+x)&0x3FFF)];
|
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 c;
|
||||||
int cga_tint = -2;
|
int cga_tint = -2;
|
||||||
|
cga_t *cga = malloc(sizeof(cga_t));
|
||||||
|
memset(cga, 0, sizeof(cga_t));
|
||||||
|
|
||||||
|
cga->vram = malloc(0x4000);
|
||||||
|
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
{
|
{
|
||||||
i_filt[c] = 512.0 * cos((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);
|
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);
|
timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
|
||||||
return 0;
|
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,
|
cga_t *cga = (cga_t *)p;
|
||||||
/*IO at 3Cx/3Dx*/
|
|
||||||
cga_out,
|
|
||||||
cga_in,
|
|
||||||
/*IO at 3Ax/3Bx*/
|
|
||||||
video_out_null,
|
|
||||||
video_in_null,
|
|
||||||
|
|
||||||
cga_poll,
|
free(cga->vram);
|
||||||
cga_recalctimings,
|
free(cga);
|
||||||
|
}
|
||||||
|
|
||||||
video_write_null,
|
void cga_speed_changed(void *p)
|
||||||
video_write_null,
|
{
|
||||||
cga_write,
|
cga_t *cga = (cga_t *)p;
|
||||||
|
|
||||||
video_read_null,
|
cga_recalctimings(cga);
|
||||||
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();
|
typedef struct cga_t
|
||||||
void cga_out(uint16_t addr, uint8_t val, void *priv);
|
{
|
||||||
uint8_t cga_in(uint16_t addr, void *priv);
|
int crtcreg;
|
||||||
void cga_poll();
|
uint8_t crtc[32];
|
||||||
void cga_write(uint32_t addr, uint8_t val, void *priv);
|
|
||||||
uint8_t cga_read(uint32_t addr, void *priv);
|
uint8_t cgastat;
|
||||||
void cga_recalctimings();
|
|
||||||
|
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;
|
||||||
|
|
|
||||||
758
src/vid_cl5429.c
758
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;
|
||||||
896
src/vid_ega.c
896
src/vid_ega.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,71 @@
|
||||||
int ega_init();
|
typedef struct ega_t
|
||||||
void ega_out(uint16_t addr, uint8_t val, void *priv);
|
{
|
||||||
uint8_t ega_in(uint16_t addr, void *priv);
|
uint8_t crtcreg;
|
||||||
void ega_poll();
|
uint8_t crtc[32];
|
||||||
void ega_recalctimings();
|
uint8_t gdcreg[16];
|
||||||
void ega_write(uint32_t addr, uint8_t val, void *priv);
|
int gdcaddr;
|
||||||
uint8_t ega_read(uint32_t addr, void *priv);
|
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;
|
||||||
|
|
|
||||||
163
src/vid_et4000.c
163
src/vid_et4000.c
|
|
@ -1,141 +1,156 @@
|
||||||
/*ET4000 emulation*/
|
/*ET4000 emulation*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vid_svga.h"
|
#include "vid_svga.h"
|
||||||
#include "vid_unk_ramdac.h"
|
#include "vid_unk_ramdac.h"
|
||||||
|
|
||||||
int et4k_b8000;
|
#include "vid_et4000.h"
|
||||||
|
|
||||||
|
typedef struct et4000_t
|
||||||
void et4000_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
|
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;
|
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);
|
pclog("ET4000 out %04X %02X\n", addr, val);
|
||||||
|
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||||
unk_ramdac_out(addr, val, NULL);
|
unk_ramdac_out(addr, val, &et4000->ramdac, svga);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x3CD: /*Banking*/
|
case 0x3CD: /*Banking*/
|
||||||
svgawbank=(val&0xF)*65536;
|
svga->write_bank = (val & 0xf) * 0x10000;
|
||||||
svgarbank=((val>>4)&0xF)*65536;
|
svga->read_bank = ((val >> 4) & 0xf) * 0x10000;
|
||||||
svgaseg=val;
|
et4000->banking = val;
|
||||||
pclog("Banking write %08X %08X %02X\n", svgawbank, svgarbank, val);
|
pclog("Banking write %08X %08X %02X\n", svga->write_bank, svga->read_bank, val);
|
||||||
return;
|
return;
|
||||||
case 0x3CF:
|
|
||||||
switch (gdcaddr&15)
|
|
||||||
{
|
|
||||||
case 6:
|
|
||||||
et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
crtcreg = val & 0x3f;
|
svga->crtcreg = val & 0x3f;
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
||||||
old=crtc[crtcreg];
|
old = svga->crtc[svga->crtcreg];
|
||||||
crtc[crtcreg]=val;
|
svga->crtc[svga->crtcreg] = val;
|
||||||
et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4);
|
|
||||||
if (old != val)
|
if (old != val)
|
||||||
{
|
{
|
||||||
if (crtcreg<0xE || crtcreg>0x10)
|
if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
|
||||||
{
|
{
|
||||||
fullchange = changeframecount;
|
fullchange = changeframecount;
|
||||||
svga_recalctimings();
|
svga_recalctimings(svga);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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);
|
if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr);
|
||||||
|
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3C5:
|
case 0x3C5:
|
||||||
if ((seqaddr&0xF)==7) return seqregs[seqaddr&0xF]|4;
|
if ((svga->seqaddr & 0xf) == 7) return svga->seqregs[svga->seqaddr & 0xf] | 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
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*/
|
case 0x3CD: /*Banking*/
|
||||||
return svgaseg;
|
return et4000->banking;
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
return crtcreg;
|
return svga->crtcreg;
|
||||||
case 0x3D5:
|
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;
|
et4000_t *et4000 = (et4000_t *)svga->p;
|
||||||
if (crtc[0x35]&2) svga_vtotal+=0x400;
|
|
||||||
if (crtc[0x35]&4) svga_dispend+=0x400;
|
svga->ma_latch |= (svga->crtc[0x33]&3)<<16;
|
||||||
if (crtc[0x35]&8) svga_vsyncstart+=0x400;
|
if (svga->crtc[0x35] & 2) svga->vtotal += 0x400;
|
||||||
if (crtc[0x35]&0x10) svga_split+=0x400;
|
if (svga->crtc[0x35] & 4) svga->dispend += 0x400;
|
||||||
if (!svga_rowoffset) svga_rowoffset=0x100;
|
if (svga->crtc[0x35] & 8) svga->vsyncstart += 0x400;
|
||||||
// if (crtc[0x3F]&0x80) svga_rowoffset+=0x100;
|
if (svga->crtc[0x35] & 0x10) svga->split += 0x400;
|
||||||
if (crtc[0x3F]&1) svga_htotal+=256;
|
if (!svga->rowoffset) svga->rowoffset = 0x100;
|
||||||
if (attrregs[0x16]&0x20) svga_hdisp<<=1;
|
if (svga->crtc[0x3f] & 1) svga->htotal += 256;
|
||||||
|
if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1;
|
||||||
|
|
||||||
// pclog("Rowoffset %i\n",svga_rowoffset);
|
// 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 0: case 1: break;
|
||||||
case 3: svga_clock = cpuclock/40000000.0; break;
|
case 3: svga->clock = cpuclock / 40000000.0; break;
|
||||||
case 5: svga_clock = cpuclock/65000000.0; break;
|
case 5: svga->clock = cpuclock / 65000000.0; break;
|
||||||
default: svga_clock = cpuclock/36000000.0; break;
|
default: svga->clock = cpuclock / 36000000.0; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int et4000_init()
|
void *et4000_init()
|
||||||
{
|
{
|
||||||
svga_recalctimings_ex = et4000_recalctimings;
|
et4000_t *et4000 = malloc(sizeof(et4000_t));
|
||||||
svga_vram_limit = 1 << 20; /*1mb*/
|
memset(et4000, 0, sizeof(et4000_t));
|
||||||
vrammask = 0xfffff;
|
|
||||||
return svga_init();
|
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,
|
et4000_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
et4000_close,
|
||||||
et4000_out,
|
et4000_speed_changed,
|
||||||
et4000_in,
|
svga_add_status_info
|
||||||
/*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
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
src/vid_et4000.h
Normal file
1
src/vid_et4000.h
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
extern device_t et4000_device;
|
||||||
1267
src/vid_et4000w32.c
1267
src/vid_et4000w32.c
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1 @@
|
||||||
|
extern device_t et4000w32p_device;
|
||||||
|
|
@ -1,94 +1,117 @@
|
||||||
/*Hercules emulation*/
|
/*Hercules emulation*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
#include "vid_hercules.h"
|
||||||
|
|
||||||
void hercules_recalctimings();
|
typedef struct hercules_t
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
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);
|
// pclog("Herc out %04X %02X\n",addr,val);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
|
case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
|
||||||
crtcmreg = val & 31;
|
hercules->crtcreg = val & 31;
|
||||||
return;
|
return;
|
||||||
case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
|
case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
|
||||||
crtcm[crtcmreg] = val;
|
hercules->crtc[hercules->crtcreg] = val;
|
||||||
if (crtcm[10]==6 && crtcm[11]==7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
if (hercules->crtc[10] == 6 && hercules->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
||||||
{
|
{
|
||||||
crtcm[10]=0xB;
|
hercules->crtc[10] = 0xb;
|
||||||
crtcm[11]=0xC;
|
hercules->crtc[11] = 0xc;
|
||||||
}
|
}
|
||||||
hercules_recalctimings();
|
hercules_recalctimings(hercules);
|
||||||
return;
|
return;
|
||||||
case 0x3B8:
|
case 0x3b8:
|
||||||
hercules_ctrl = val;
|
hercules->ctrl = val;
|
||||||
return;
|
return;
|
||||||
case 0x3BF:
|
case 0x3bf:
|
||||||
hercules_ctrl2 = val;
|
hercules->ctrl2 = val;
|
||||||
video_write_b800 = (val&2) ? hercules_write : video_write_null;
|
mem_removehandler(0xb8000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, hercules);
|
||||||
video_read_b800 = (val&2) ? hercules_read : video_read_null;
|
if (val & 2)
|
||||||
|
mem_sethandler(0xb8000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, hercules);
|
||||||
return;
|
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);
|
// pclog("Herc in %04X %02X %04X:%04X %04X\n",addr,(hercules_stat & 0xF) | ((hercules_stat & 8) << 4),CS,pc,CX);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
|
case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
|
||||||
return crtcmreg;
|
return hercules->crtcreg;
|
||||||
case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
|
case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
|
||||||
return crtcm[crtcmreg];
|
return hercules->crtc[hercules->crtcreg];
|
||||||
case 0x3BA:
|
case 0x3ba:
|
||||||
return (hercules_stat & 0xF) | ((hercules_stat & 8) << 4);
|
return (hercules->stat & 0xf) | ((hercules->stat & 8) << 4);
|
||||||
}
|
}
|
||||||
return 0xff;
|
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);
|
// 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;
|
double _dispontime, _dispofftime;
|
||||||
disptime=crtc[0]+1;
|
disptime = hercules->crtc[0] + 1;
|
||||||
_dispontime=crtc[1];
|
_dispontime = hercules->crtc[1];
|
||||||
_dispofftime = disptime - _dispontime;
|
_dispofftime = disptime - _dispontime;
|
||||||
_dispontime *= MDACONST;
|
_dispontime *= MDACONST;
|
||||||
_dispofftime *= MDACONST;
|
_dispofftime *= MDACONST;
|
||||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
hercules->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
hercules->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
int mdacols[256][2][2];
|
void hercules_poll(void *p)
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
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 drawcursor;
|
||||||
int x, c;
|
int x, c;
|
||||||
int oldvc;
|
int oldvc;
|
||||||
|
|
@ -97,200 +120,239 @@ void hercules_poll()
|
||||||
int cols[4];
|
int cols[4];
|
||||||
int oldsc;
|
int oldsc;
|
||||||
int blink;
|
int blink;
|
||||||
if (!linepos)
|
if (!hercules->linepos)
|
||||||
{
|
{
|
||||||
//pclog("Poll %i %i\n",vc,sc);
|
//pclog("Poll %i %i\n",vc,sc);
|
||||||
vidtime+=dispofftime;
|
hercules->vidtime += hercules->dispofftime;
|
||||||
hercules_stat|=1;
|
hercules->stat |= 1;
|
||||||
linepos=1;
|
hercules->linepos = 1;
|
||||||
oldsc=sc;
|
oldsc = hercules->sc;
|
||||||
if ((crtcm[8]&3)==3) sc=(sc<<1)&7;
|
if ((hercules->crtc[8] & 3) == 3)
|
||||||
if (cgadispon)
|
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;
|
hercules->lastline = hercules->displine;
|
||||||
cols[0] = 0;
|
cols[0] = 0;
|
||||||
cols[1] = 7;
|
cols[1] = 7;
|
||||||
if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1))
|
if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1))
|
||||||
{
|
{
|
||||||
ca=(sc&3)*0x2000;
|
ca = (hercules->sc & 3) * 0x2000;
|
||||||
if ((hercules_ctrl & 0x80) && (hercules_ctrl2 & 2)) ca+=0x8000;
|
if ((hercules->ctrl & 0x80) && (hercules->ctrl2 & 2))
|
||||||
|
ca += 0x8000;
|
||||||
// printf("Draw herc %04X\n",ca);
|
// 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];
|
dat = (hercules->vram[((hercules->ma << 1) & 0x1fff) + ca] << 8) | hercules->vram[((hercules->ma << 1) & 0x1fff) + ca + 1];
|
||||||
ma++;
|
hercules->ma++;
|
||||||
for (c = 0; c < 16; c++)
|
for (c = 0; c < 16; c++)
|
||||||
buffer->line[displine][(x<<4)+c]=(dat&(32768>>c))?7:0;
|
buffer->line[hercules->displine][(x << 4) + c] = (dat & (32768 >> c)) ? 7 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (x=0;x<crtcm[1];x++)
|
for (x = 0; x < hercules->crtc[1]; x++)
|
||||||
{
|
{
|
||||||
chr=vram[(ma<<1)&0x3FFF];
|
chr = hercules->vram[(hercules->ma << 1) & 0x3fff];
|
||||||
attr=vram[((ma<<1)+1)&0x3FFF];
|
attr = hercules->vram[((hercules->ma << 1) + 1) & 0x3fff];
|
||||||
drawcursor=((ma==ca) && con && cursoron);
|
drawcursor = ((hercules->ma == ca) && hercules->con && hercules->cursoron);
|
||||||
blink=((cgablink&16) && (hercules_ctrl&0x20) && (attr&0x80) && !drawcursor);
|
blink = ((hercules->blink & 16) && (hercules->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||||
if (sc==12 && ((attr&7)==1))
|
if (hercules->sc == 12 && ((attr & 7) == 1))
|
||||||
{
|
{
|
||||||
for (c = 0; c < 9; c++)
|
for (c = 0; c < 9; c++)
|
||||||
buffer->line[displine][(x*9)+c]=mdacols[attr][blink][1];
|
buffer->line[hercules->displine][(x * 9) + c] = mdacols[attr][blink][1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
buffer->line[displine][(x*9)+c]=mdacols[attr][blink][(fontdatm[chr][sc]&(1<<(c^7)))?1:0];
|
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[displine][(x*9)+8]=mdacols[attr][blink][fontdatm[chr][sc]&1];
|
if ((chr & ~0x1f) == 0xc0) buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][hercules->sc] & 1];
|
||||||
else buffer->line[displine][(x*9)+8]=mdacols[attr][blink][0];
|
else buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][0];
|
||||||
}
|
}
|
||||||
ma++;
|
hercules->ma++;
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 9; c++)
|
for (c = 0; c < 9; c++)
|
||||||
buffer->line[displine][(x*9)+c]^=mdacols[attr][0][1];
|
buffer->line[hercules->displine][(x * 9) + c] ^= mdacols[attr][0][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sc=oldsc;
|
hercules->sc = oldsc;
|
||||||
if (vc==crtcm[7] && !sc)
|
if (hercules->vc == hercules->crtc[7] && !hercules->sc)
|
||||||
{
|
{
|
||||||
hercules_stat|=8;
|
hercules->stat |= 8;
|
||||||
// printf("VSYNC on %i %i\n",vc,sc);
|
// printf("VSYNC on %i %i\n",vc,sc);
|
||||||
}
|
}
|
||||||
displine++;
|
hercules->displine++;
|
||||||
if (displine>=500) displine=0;
|
if (hercules->displine >= 500)
|
||||||
|
hercules->displine = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vidtime+=dispontime;
|
hercules->vidtime += hercules->dispontime;
|
||||||
if (cgadispon) hercules_stat&=~1;
|
if (hercules->dispon)
|
||||||
linepos=0;
|
hercules->stat &= ~1;
|
||||||
if (vsynctime)
|
hercules->linepos = 0;
|
||||||
|
if (hercules->vsynctime)
|
||||||
{
|
{
|
||||||
vsynctime--;
|
hercules->vsynctime--;
|
||||||
if (!vsynctime)
|
if (!hercules->vsynctime)
|
||||||
{
|
{
|
||||||
hercules_stat&=~8;
|
hercules->stat &= ~8;
|
||||||
// printf("VSYNC off %i %i\n",vc,sc);
|
// 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 (hercules->sc == (hercules->crtc[11] & 31) || ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[11] & 31) >> 1)))
|
||||||
if (vadj)
|
|
||||||
{
|
{
|
||||||
sc++;
|
hercules->con = 0;
|
||||||
sc&=31;
|
hercules->coff = 1;
|
||||||
ma=maback;
|
}
|
||||||
vadj--;
|
if (hercules->vadj)
|
||||||
if (!vadj)
|
|
||||||
{
|
{
|
||||||
cgadispon=1;
|
hercules->sc++;
|
||||||
ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
|
hercules->sc &= 31;
|
||||||
sc=0;
|
hercules->ma = hercules->maback;
|
||||||
|
hercules->vadj--;
|
||||||
|
if (!hercules->vadj)
|
||||||
|
{
|
||||||
|
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;
|
hercules->maback = hercules->ma;
|
||||||
sc=0;
|
hercules->sc = 0;
|
||||||
oldvc=vc;
|
oldvc = hercules->vc;
|
||||||
vc++;
|
hercules->vc++;
|
||||||
vc&=127;
|
hercules->vc &= 127;
|
||||||
if (vc==crtcm[6]) cgadispon=0;
|
if (hercules->vc == hercules->crtc[6])
|
||||||
if (oldvc==crtcm[4])
|
hercules->dispon = 0;
|
||||||
|
if (oldvc == hercules->crtc[4])
|
||||||
{
|
{
|
||||||
// printf("Display over at %i\n",displine);
|
// printf("Display over at %i\n",displine);
|
||||||
vc=0;
|
hercules->vc = 0;
|
||||||
vadj=crtcm[5];
|
hercules->vadj = hercules->crtc[5];
|
||||||
if (!vadj) cgadispon=1;
|
if (!hercules->vadj) hercules->dispon=1;
|
||||||
if (!vadj) ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
|
if (!hercules->vadj) hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff;
|
||||||
if ((crtcm[10]&0x60)==0x20) cursoron=0;
|
if ((hercules->crtc[10] & 0x60) == 0x20) hercules->cursoron = 0;
|
||||||
else cursoron=cgablink&16;
|
else hercules->cursoron = hercules->blink & 16;
|
||||||
}
|
}
|
||||||
if (vc==crtcm[7])
|
if (hercules->vc == hercules->crtc[7])
|
||||||
{
|
{
|
||||||
cgadispon=0;
|
hercules->dispon = 0;
|
||||||
displine=0;
|
hercules->displine = 0;
|
||||||
vsynctime=16;//(crtcm[3]>>4)+1;
|
hercules->vsynctime = 16;//(crtcm[3]>>4)+1;
|
||||||
if (crtcm[7])
|
if (hercules->crtc[7])
|
||||||
{
|
{
|
||||||
// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline);
|
// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline);
|
||||||
if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1)) x = crtcm[1] << 4;
|
if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) x = hercules->crtc[1] << 4;
|
||||||
else x = crtcm[1] * 9;
|
else x = hercules->crtc[1] * 9;
|
||||||
lastline++;
|
hercules->lastline++;
|
||||||
if (x!=xsize || (lastline-firstline)!=ysize)
|
if (x != xsize || (hercules->lastline - hercules->firstline) != ysize)
|
||||||
{
|
{
|
||||||
xsize = x;
|
xsize = x;
|
||||||
ysize=lastline-firstline;
|
ysize = hercules->lastline - hercules->firstline;
|
||||||
// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]);
|
// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]);
|
||||||
if (xsize < 64) xsize = 656;
|
if (xsize < 64) xsize = 656;
|
||||||
if (ysize < 32) ysize = 200;
|
if (ysize < 32) ysize = 200;
|
||||||
updatewindowsize(xsize, ysize);
|
updatewindowsize(xsize, ysize);
|
||||||
}
|
}
|
||||||
startblit();
|
startblit();
|
||||||
video_blit_memtoscreen_8(0, firstline, xsize, ysize);
|
video_blit_memtoscreen_8(0, hercules->firstline, xsize, ysize);
|
||||||
endblit();
|
endblit();
|
||||||
frames++;
|
frames++;
|
||||||
if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1))
|
if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1))
|
||||||
{
|
{
|
||||||
video_res_x = crtcm[1] * 16;
|
video_res_x = hercules->crtc[1] * 16;
|
||||||
video_res_y = crtcm[6] * 4;
|
video_res_y = hercules->crtc[6] * 4;
|
||||||
video_bpp = 1;
|
video_bpp = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
video_res_x = crtcm[1];
|
video_res_x = hercules->crtc[1];
|
||||||
video_res_y = crtcm[6];
|
video_res_y = hercules->crtc[6];
|
||||||
video_bpp = 0;
|
video_bpp = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
firstline=1000;
|
hercules->firstline = 1000;
|
||||||
lastline=0;
|
hercules->lastline = 0;
|
||||||
cgablink++;
|
hercules->blink++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sc++;
|
hercules->sc++;
|
||||||
sc&=31;
|
hercules->sc &= 31;
|
||||||
ma=maback;
|
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]);
|
// 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);
|
int c;
|
||||||
return 0;
|
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,
|
hercules_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
hercules_close,
|
||||||
video_out_null,
|
hercules_speed_changed,
|
||||||
video_in_null,
|
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
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
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 "ibm.h"
|
||||||
#include "vid_icd2061.h"
|
#include "vid_icd2061.h"
|
||||||
|
|
||||||
static int icd2061_state;
|
void icd2061_write(icd2061_t *icd2061, int val)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
int q, p, m, i, a;
|
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);
|
pclog("ICD2061 write %02X %i %08X %i\n", val, icd2061->unlock, icd2061->data, icd2061->pos);
|
||||||
if (!icd2061_status)
|
if (!icd2061->status)
|
||||||
{
|
{
|
||||||
if (val & 2) icd2061_unlock++;
|
if (val & 2)
|
||||||
|
icd2061->unlock++;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (icd2061_unlock >= 5)
|
if (icd2061->unlock >= 5)
|
||||||
{
|
{
|
||||||
icd2061_status = 1;
|
icd2061->status = 1;
|
||||||
icd2061_pos = 0;
|
icd2061->pos = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
icd2061_unlock = 0;
|
icd2061->unlock = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (val & 1)
|
else if (val & 1)
|
||||||
{
|
{
|
||||||
icd2061_data = (icd2061_data >> 1) | (((val & 2) ? 1 : 0) << 24);
|
icd2061->data = (icd2061->data >> 1) | (((val & 2) ? 1 : 0) << 24);
|
||||||
icd2061_pos++;
|
icd2061->pos++;
|
||||||
if (icd2061_pos == 26)
|
if (icd2061->pos == 26)
|
||||||
{
|
{
|
||||||
pclog("ICD2061 data - %08X\n", icd2061_data);
|
pclog("ICD2061 data - %08X\n", icd2061->data);
|
||||||
a = (icd2061_data >> 21) & 0x7;
|
a = (icd2061->data >> 21) & 0x7;
|
||||||
if (!(a & 4))
|
if (!(a & 4))
|
||||||
{
|
{
|
||||||
q = (icd2061_data & 0x7f) - 2;
|
q = (icd2061->data & 0x7f) - 2;
|
||||||
m = 1 << ((icd2061_data >> 7) & 0x7);
|
m = 1 << ((icd2061->data >> 7) & 0x7);
|
||||||
p = ((icd2061_data >> 10) & 0x7f) - 3;
|
p = ((icd2061->data >> 10) & 0x7f) - 3;
|
||||||
i = (icd2061_data >> 17) & 0xf;
|
i = (icd2061->data >> 17) & 0xf;
|
||||||
pclog("p %i q %i m %i\n", p, q, m);
|
pclog("p %i q %i m %i\n", p, q, m);
|
||||||
if (icd2061_ctrl & (1 << a))
|
if (icd2061->ctrl & (1 << a))
|
||||||
p <<= 1;
|
p <<= 1;
|
||||||
icd2061_freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m;
|
icd2061->freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m;
|
||||||
pclog("ICD2061 freq %i = %f\n", a, icd2061_freq[a]);
|
pclog("ICD2061 freq %i = %f\n", a, icd2061->freq[a]);
|
||||||
}
|
}
|
||||||
else if (a == 6)
|
else if (a == 6)
|
||||||
{
|
{
|
||||||
icd2061_ctrl = val;
|
icd2061->ctrl = val;
|
||||||
pclog("ICD2061 ctrl = %08X\n", val);
|
pclog("ICD2061 ctrl = %08X\n", val);
|
||||||
}
|
}
|
||||||
icd2061_unlock = icd2061_data = 0;
|
icd2061->unlock = icd2061->data = 0;
|
||||||
icd2061_status = 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]);
|
pclog("Return freq %f\n", icd2061->freq[i]);
|
||||||
return icd2061_freq[i];
|
return icd2061->freq[i];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,14 @@
|
||||||
void icd2061_write(int val);
|
typedef struct icd2061_t
|
||||||
double icd2061_getfreq(int i);
|
{
|
||||||
|
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
|
enum
|
||||||
{
|
{
|
||||||
ICS2595_IDLE,
|
ICS2595_IDLE = 0,
|
||||||
ICS2595_WRITE,
|
ICS2595_WRITE,
|
||||||
ICS2595_READ
|
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 int ics2595_div[4] = {8, 4, 2, 1};
|
||||||
|
|
||||||
static double ics2595_clocks[16];
|
void ics2595_write(ics2595_t *ics2595, int strobe, int dat)
|
||||||
double ics2595_output_clock;
|
|
||||||
|
|
||||||
void ics2595_write(int strobe, int dat)
|
|
||||||
{
|
{
|
||||||
pclog("ics2595_write : %i %i\n", strobe, dat);
|
pclog("ics2595_write : %i %i\n", strobe, dat);
|
||||||
if (strobe)
|
if (strobe)
|
||||||
{
|
{
|
||||||
if ((dat & 8) && !ics2595_oldfs3) /*Data clock*/
|
if ((dat & 8) && !ics2595->oldfs3) /*Data clock*/
|
||||||
{
|
{
|
||||||
pclog(" - new dat %i\n", dat & 4);
|
pclog(" - new dat %i\n", dat & 4);
|
||||||
switch (ics2595_state)
|
switch (ics2595->state)
|
||||||
{
|
{
|
||||||
case ICS2595_IDLE:
|
case ICS2595_IDLE:
|
||||||
ics2595_state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE;
|
ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE;
|
||||||
ics2595_pos = 0;
|
ics2595->pos = 0;
|
||||||
break;
|
break;
|
||||||
case ICS2595_WRITE:
|
case ICS2595_WRITE:
|
||||||
ics2595_dat = (ics2595_dat >> 1);
|
ics2595->dat = (ics2595->dat >> 1);
|
||||||
if (dat & 4)
|
if (dat & 4)
|
||||||
ics2595_dat |= (1 << 19);
|
ics2595->dat |= (1 << 19);
|
||||||
ics2595_pos++;
|
ics2595->pos++;
|
||||||
if (ics2595_pos == 20)
|
if (ics2595->pos == 20)
|
||||||
{
|
{
|
||||||
int d, n, l;
|
int d, n, l;
|
||||||
pclog("ICS2595_WRITE : dat %08X\n", ics2595_dat);
|
pclog("ICS2595_WRITE : dat %08X\n", ics2595->dat);
|
||||||
l = (ics2595_dat >> 2) & 31;
|
l = (ics2595->dat >> 2) & 0xf;
|
||||||
n = ((ics2595_dat >> 7) & 255) + 257;
|
n = ((ics2595->dat >> 7) & 255) + 257;
|
||||||
d = ics2595_div[(ics2595_dat >> 16) & 3];
|
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);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ics2595_oldfs2 = dat & 4;
|
ics2595->oldfs2 = dat & 4;
|
||||||
ics2595_oldfs3 = dat & 8;
|
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);
|
typedef struct ics2595_t
|
||||||
extern double ics2595_output_clock;
|
{
|
||||||
|
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);
|
||||||
|
|
|
||||||
343
src/vid_mda.c
343
src/vid_mda.c
|
|
@ -1,85 +1,105 @@
|
||||||
/*MDA emulation*/
|
/*MDA emulation*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
#include "vid_mda.h"
|
||||||
|
|
||||||
void mda_recalctimings();
|
typedef struct mda_t
|
||||||
|
|
||||||
static uint8_t mda_ctrl,mda_stat;
|
|
||||||
uint8_t crtcm[32],crtcmreg;
|
|
||||||
|
|
||||||
void mda_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
|
case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
|
||||||
crtcmreg = val & 31;
|
mda->crtcreg = val & 31;
|
||||||
return;
|
return;
|
||||||
case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
|
case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
|
||||||
crtcm[crtcmreg] = val;
|
mda->crtc[mda->crtcreg] = val;
|
||||||
if (crtcm[10]==6 && crtcm[11]==7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
||||||
{
|
{
|
||||||
crtcm[10]=0xB;
|
mda->crtc[10] = 0xb;
|
||||||
crtcm[11]=0xC;
|
mda->crtc[11] = 0xc;
|
||||||
}
|
}
|
||||||
mda_recalctimings();
|
mda_recalctimings(mda);
|
||||||
return;
|
return;
|
||||||
case 0x3B8:
|
case 0x3b8:
|
||||||
mda_ctrl = val;
|
mda->ctrl = val;
|
||||||
return;
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
|
case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
|
||||||
return crtcmreg;
|
return mda->crtcreg;
|
||||||
case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
|
case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
|
||||||
return crtcm[crtcmreg];
|
return mda->crtc[mda->crtcreg];
|
||||||
case 0x3BA:
|
case 0x3ba:
|
||||||
return mda_stat | 0xF0;
|
return mda->stat | 0xF0;
|
||||||
}
|
}
|
||||||
return 0xff;
|
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;
|
double _dispontime, _dispofftime, disptime;
|
||||||
disptime=crtc[0]+1;
|
disptime = mda->crtc[0] + 1;
|
||||||
_dispontime=crtc[1];
|
_dispontime = mda->crtc[1];
|
||||||
_dispofftime = disptime - _dispontime;
|
_dispofftime = disptime - _dispontime;
|
||||||
_dispontime *= MDACONST;
|
_dispontime *= MDACONST;
|
||||||
_dispofftime *= MDACONST;
|
_dispofftime *= MDACONST;
|
||||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
mda->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
mda->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
int mdacols[256][2][2];
|
void mda_poll(void *p)
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
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 drawcursor;
|
||||||
int x, c;
|
int x, c;
|
||||||
int oldvc;
|
int oldvc;
|
||||||
|
|
@ -87,173 +107,210 @@ void mda_poll()
|
||||||
int cols[4];
|
int cols[4];
|
||||||
int oldsc;
|
int oldsc;
|
||||||
int blink;
|
int blink;
|
||||||
if (!linepos)
|
if (!mda->linepos)
|
||||||
{
|
{
|
||||||
vidtime+=dispofftime;
|
mda->vidtime += mda->dispofftime;
|
||||||
mda_stat|=1;
|
mda->stat |= 1;
|
||||||
linepos=1;
|
mda->linepos = 1;
|
||||||
oldsc=sc;
|
oldsc = mda->sc;
|
||||||
if ((crtcm[8]&3)==3) sc=(sc<<1)&7;
|
if ((mda->crtc[8] & 3) == 3)
|
||||||
if (cgadispon)
|
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;
|
mda->lastline = mda->displine;
|
||||||
cols[0] = 0;
|
cols[0] = 0;
|
||||||
cols[1] = 7;
|
cols[1] = 7;
|
||||||
for (x=0;x<crtcm[1];x++)
|
for (x = 0; x < mda->crtc[1]; x++)
|
||||||
{
|
{
|
||||||
chr=vram[(ma<<1)&0x3FFF];
|
chr = mda->vram[(mda->ma << 1) & 0x3fff];
|
||||||
attr=vram[((ma<<1)+1)&0x3FFF];
|
attr = mda->vram[((mda->ma << 1) + 1) & 0x3fff];
|
||||||
drawcursor=((ma==ca) && con && cursoron);
|
drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron);
|
||||||
blink=((cgablink&16) && (mda_ctrl&0x20) && (attr&0x80) && !drawcursor);
|
blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||||
if (sc==12 && ((attr&7)==1))
|
if (mda->sc == 12 && ((attr & 7) == 1))
|
||||||
{
|
{
|
||||||
for (c = 0; c < 9; c++)
|
for (c = 0; c < 9; c++)
|
||||||
buffer->line[displine][(x*9)+c]=mdacols[attr][blink][1];
|
buffer->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
buffer->line[displine][(x*9)+c]=mdacols[attr][blink][(fontdatm[chr][sc]&(1<<(c^7)))?1:0];
|
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[displine][(x*9)+8]=mdacols[attr][blink][fontdatm[chr][sc]&1];
|
if ((chr & ~0x1f) == 0xc0) buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1];
|
||||||
else buffer->line[displine][(x*9)+8]=mdacols[attr][blink][0];
|
else buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0];
|
||||||
}
|
}
|
||||||
ma++;
|
mda->ma++;
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 9; c++)
|
for (c = 0; c < 9; c++)
|
||||||
buffer->line[displine][(x*9)+c]^=mdacols[attr][0][1];
|
buffer->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sc=oldsc;
|
mda->sc = oldsc;
|
||||||
if (vc==crtcm[7] && !sc)
|
if (mda->vc == mda->crtc[7] && !mda->sc)
|
||||||
{
|
{
|
||||||
mda_stat|=8;
|
mda->stat |= 8;
|
||||||
// printf("VSYNC on %i %i\n",vc,sc);
|
// printf("VSYNC on %i %i\n",vc,sc);
|
||||||
}
|
}
|
||||||
displine++;
|
mda->displine++;
|
||||||
if (displine>=500) displine=0;
|
if (mda->displine >= 500)
|
||||||
|
mda->displine=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vidtime+=dispontime;
|
mda->vidtime += mda->dispontime;
|
||||||
if (cgadispon) mda_stat&=~1;
|
if (mda->dispon) mda->stat&=~1;
|
||||||
linepos=0;
|
mda->linepos=0;
|
||||||
if (vsynctime)
|
if (mda->vsynctime)
|
||||||
{
|
{
|
||||||
vsynctime--;
|
mda->vsynctime--;
|
||||||
if (!vsynctime)
|
if (!mda->vsynctime)
|
||||||
{
|
{
|
||||||
mda_stat&=~8;
|
mda->stat&=~8;
|
||||||
// printf("VSYNC off %i %i\n",vc,sc);
|
// 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 (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1)))
|
||||||
if (vadj)
|
|
||||||
{
|
{
|
||||||
sc++;
|
mda->con = 0;
|
||||||
sc&=31;
|
mda->coff = 1;
|
||||||
ma=maback;
|
}
|
||||||
vadj--;
|
if (mda->vadj)
|
||||||
if (!vadj)
|
|
||||||
{
|
{
|
||||||
cgadispon=1;
|
mda->sc++;
|
||||||
ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
|
mda->sc &= 31;
|
||||||
sc=0;
|
mda->ma = mda->maback;
|
||||||
|
mda->vadj--;
|
||||||
|
if (!mda->vadj)
|
||||||
|
{
|
||||||
|
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;
|
mda->maback = mda->ma;
|
||||||
sc=0;
|
mda->sc = 0;
|
||||||
oldvc=vc;
|
oldvc = mda->vc;
|
||||||
vc++;
|
mda->vc++;
|
||||||
vc&=127;
|
mda->vc &= 127;
|
||||||
if (vc==crtcm[6]) cgadispon=0;
|
if (mda->vc == mda->crtc[6])
|
||||||
if (oldvc==crtcm[4])
|
mda->dispon=0;
|
||||||
|
if (oldvc == mda->crtc[4])
|
||||||
{
|
{
|
||||||
// printf("Display over at %i\n",displine);
|
// printf("Display over at %i\n",displine);
|
||||||
vc=0;
|
mda->vc = 0;
|
||||||
vadj=crtcm[5];
|
mda->vadj = mda->crtc[5];
|
||||||
if (!vadj) cgadispon=1;
|
if (!mda->vadj) mda->dispon = 1;
|
||||||
if (!vadj) ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
|
if (!mda->vadj) mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
|
||||||
if ((crtcm[10]&0x60)==0x20) cursoron=0;
|
if ((mda->crtc[10] & 0x60) == 0x20) mda->cursoron = 0;
|
||||||
else cursoron=cgablink&16;
|
else mda->cursoron = mda->blink & 16;
|
||||||
}
|
}
|
||||||
if (vc==crtcm[7])
|
if (mda->vc == mda->crtc[7])
|
||||||
{
|
{
|
||||||
cgadispon=0;
|
mda->dispon = 0;
|
||||||
displine=0;
|
mda->displine = 0;
|
||||||
vsynctime=16;//(crtcm[3]>>4)+1;
|
mda->vsynctime = 16;
|
||||||
if (crtcm[7])
|
if (mda->crtc[7])
|
||||||
{
|
{
|
||||||
// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline);
|
// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline);
|
||||||
x=crtcm[1]*9;
|
x = mda->crtc[1] * 9;
|
||||||
lastline++;
|
mda->lastline++;
|
||||||
if (x!=xsize || (lastline-firstline)!=ysize)
|
if (x != xsize || (mda->lastline - mda->firstline) != ysize)
|
||||||
{
|
{
|
||||||
xsize = x;
|
xsize = x;
|
||||||
ysize=lastline-firstline;
|
ysize = mda->lastline - mda->firstline;
|
||||||
// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]);
|
// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]);
|
||||||
if (xsize < 64) xsize = 656;
|
if (xsize < 64) xsize = 656;
|
||||||
if (ysize < 32) ysize = 200;
|
if (ysize < 32) ysize = 200;
|
||||||
updatewindowsize(xsize, ysize);
|
updatewindowsize(xsize, ysize);
|
||||||
}
|
}
|
||||||
startblit();
|
startblit();
|
||||||
video_blit_memtoscreen_8(0, firstline, xsize, lastline - firstline);
|
video_blit_memtoscreen_8(0, mda->firstline, xsize, mda->lastline - mda->firstline);
|
||||||
endblit();
|
endblit();
|
||||||
frames++;
|
frames++;
|
||||||
video_res_x = crtcm[1];
|
video_res_x = mda->crtc[1];
|
||||||
video_res_y = crtcm[6];
|
video_res_y = mda->crtc[6];
|
||||||
video_bpp = 0;
|
video_bpp = 0;
|
||||||
}
|
}
|
||||||
firstline=1000;
|
mda->firstline = 1000;
|
||||||
lastline=0;
|
mda->lastline = 0;
|
||||||
cgablink++;
|
mda->blink++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sc++;
|
mda->sc++;
|
||||||
sc&=31;
|
mda->sc &= 31;
|
||||||
ma=maback;
|
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]);
|
// 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);
|
int c;
|
||||||
return 0;
|
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,
|
mda_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
mda_close,
|
||||||
video_out_null,
|
mda_speed_changed,
|
||||||
video_in_null,
|
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
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
src/vid_mda.h
Normal file
1
src/vid_mda.h
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
extern device_t mda_device;
|
||||||
|
|
@ -1,110 +1,140 @@
|
||||||
/*Olivetti M24 video emulation
|
/*Olivetti M24 video emulation
|
||||||
Essentially double-res CGA*/
|
Essentially double-res CGA*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
#include "vid_olivetti_m24.h"
|
||||||
|
|
||||||
void m24_recalctimings();
|
typedef struct m24_t
|
||||||
|
|
||||||
static uint8_t m24_ctrl;
|
|
||||||
static uint32_t m24_base;
|
|
||||||
|
|
||||||
void m24_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
|
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;
|
uint8_t old;
|
||||||
|
pclog("m24_out %04X %02X\n", addr, val);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3d4:
|
||||||
crtcreg = val & 31;
|
m24->crtcreg = val & 31;
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3d5:
|
||||||
old = crtc[crtcreg];
|
old = m24->crtc[m24->crtcreg];
|
||||||
crtc[crtcreg] = val & crtcmask[crtcreg];
|
m24->crtc[m24->crtcreg] = val & crtcmask[m24->crtcreg];
|
||||||
if (old != val)
|
if (old != val)
|
||||||
{
|
{
|
||||||
if (crtcreg < 0xE || crtcreg > 0x10)
|
if (m24->crtcreg < 0xe || m24->crtcreg > 0x10)
|
||||||
{
|
{
|
||||||
fullchange = changeframecount;
|
fullchange = changeframecount;
|
||||||
m24_recalctimings();
|
m24_recalctimings(m24);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x3D8:
|
case 0x3d8:
|
||||||
cgamode = val;
|
m24->cgamode = val;
|
||||||
return;
|
return;
|
||||||
case 0x3D9:
|
case 0x3d9:
|
||||||
cgacol = val;
|
m24->cgacol = val;
|
||||||
return;
|
return;
|
||||||
case 0x3de:
|
case 0x3de:
|
||||||
m24_ctrl = val;
|
m24->ctrl = val;
|
||||||
m24_base = (val & 0x08) ? 0x4000 : 0;
|
m24->base = (val & 0x08) ? 0x4000 : 0;
|
||||||
return;
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3d4:
|
||||||
return crtcreg;
|
return m24->crtcreg;
|
||||||
case 0x3D5:
|
case 0x3d5:
|
||||||
return crtc[crtcreg];
|
return m24->crtc[m24->crtcreg];
|
||||||
case 0x3DA:
|
case 0x3da:
|
||||||
return cgastat;
|
return m24->stat;
|
||||||
}
|
}
|
||||||
return 0xFF;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t charbuffer[256];
|
void m24_write(uint32_t addr, uint8_t val, void *p)
|
||||||
|
|
||||||
void m24_write(uint32_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
vram[addr & 0x7FFF]=val;
|
m24_t *m24 = (m24_t *)p;
|
||||||
charbuffer[ ((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val;
|
m24->vram[addr & 0x7FFF]=val;
|
||||||
charbuffer[(((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = 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;
|
double _dispontime, _dispofftime, disptime;
|
||||||
if (cgamode & 1)
|
if (m24->cgamode & 1)
|
||||||
{
|
{
|
||||||
disptime = crtc[0] + 1;
|
disptime = m24->crtc[0] + 1;
|
||||||
_dispontime = crtc[1];
|
_dispontime = m24->crtc[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
disptime = (crtc[0] + 1) << 1;
|
disptime = (m24->crtc[0] + 1) << 1;
|
||||||
_dispontime = crtc[1] << 1;
|
_dispontime = m24->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]);
|
// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
|
||||||
_dispontime *= CGACONST / 2;
|
_dispontime *= CGACONST / 2;
|
||||||
_dispofftime *= 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);
|
// 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));
|
m24->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
m24->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int linepos,displine;
|
void m24_poll(void *p)
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
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 drawcursor;
|
||||||
int x, c;
|
int x, c;
|
||||||
int oldvc;
|
int oldvc;
|
||||||
|
|
@ -113,49 +143,52 @@ void m24_poll()
|
||||||
int cols[4];
|
int cols[4];
|
||||||
int col;
|
int col;
|
||||||
int oldsc;
|
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);
|
// pclog("Line poll %i %i %i %i - %04X %i %i %i\n", m24_lineff, vc, sc, vadj, ma, firstline, lastline, displine);
|
||||||
vidtime+=dispofftime;
|
m24->vidtime += m24->dispofftime;
|
||||||
cgastat|=1;
|
m24->stat |= 1;
|
||||||
linepos=1;
|
m24->linepos = 1;
|
||||||
oldsc=sc;
|
oldsc = m24->sc;
|
||||||
if ((crtc[8]&3)==3) sc=(sc<<1)&7;
|
if ((m24->crtc[8] & 3) == 3)
|
||||||
if (cgadispon)
|
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);
|
// printf("Firstline %i\n",firstline);
|
||||||
}
|
}
|
||||||
lastline=displine;
|
m24->lastline = m24->displine;
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
{
|
{
|
||||||
if ((cgamode&0x12)==0x12)
|
if ((m24->cgamode & 0x12) == 0x12)
|
||||||
{
|
{
|
||||||
buffer->line[displine][c]=0;
|
buffer->line[m24->displine][c] = 0;
|
||||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
|
if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = 0;
|
||||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=0;
|
else buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buffer->line[displine][c]=(cgacol&15)+16;
|
buffer->line[m24->displine][c] = (m24->cgacol & 15) + 16;
|
||||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16;
|
if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = (m24->cgacol & 15) + 16;
|
||||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=(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];
|
chr = m24->charbuffer[ x << 1];
|
||||||
attr = charbuffer[(x << 1) + 1];
|
attr = m24->charbuffer[(x << 1) + 1];
|
||||||
drawcursor=((ma==ca) && con && cursoron);
|
drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron);
|
||||||
if (cgamode&0x20)
|
if (m24->cgamode & 0x20)
|
||||||
{
|
{
|
||||||
cols[1] = (attr & 15) + 16;
|
cols[1] = (attr & 15) + 16;
|
||||||
cols[0] = ((attr >> 4) & 7) + 16;
|
cols[0] = ((attr >> 4) & 7) + 16;
|
||||||
if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
|
if ((m24->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||||
|
cols[1] = cols[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -165,58 +198,61 @@ void m24_poll()
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
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;
|
buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
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];
|
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];
|
chr = m24->vram[((m24->ma << 1) & 0x3fff) + m24->base];
|
||||||
attr=vram[(((ma<<1)+1)&0x3FFF) + m24_base];
|
attr = m24->vram[(((m24->ma << 1) + 1) & 0x3fff) + m24->base];
|
||||||
drawcursor=((ma==ca) && con && cursoron);
|
drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron);
|
||||||
if (cgamode&0x20)
|
if (m24->cgamode & 0x20)
|
||||||
{
|
{
|
||||||
cols[1] = (attr & 15) + 16;
|
cols[1] = (attr & 15) + 16;
|
||||||
cols[0] = ((attr >> 4) & 7) + 16;
|
cols[0] = ((attr >> 4) & 7) + 16;
|
||||||
if ((cgablink&16) && (attr&0x80)) cols[1]=cols[0];
|
if ((m24->blink & 16) && (attr & 0x80))
|
||||||
|
cols[1] = cols[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cols[1] = (attr & 15) + 16;
|
cols[1] = (attr & 15) + 16;
|
||||||
cols[0] = (attr >> 4) + 16;
|
cols[0] = (attr >> 4) + 16;
|
||||||
}
|
}
|
||||||
ma++;
|
m24->ma++;
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
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;
|
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
|
else
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
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];
|
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;
|
cols[0] = (m24->cgacol & 15) | 16;
|
||||||
col=(cgacol&16)?24:16;
|
col = (m24->cgacol & 16) ? 24 : 16;
|
||||||
if (cgamode&4)
|
if (m24->cgamode & 4)
|
||||||
{
|
{
|
||||||
cols[1] = col | 3;
|
cols[1] = col | 3;
|
||||||
cols[2] = col | 4;
|
cols[2] = col | 4;
|
||||||
cols[3] = col | 7;
|
cols[3] = col | 7;
|
||||||
}
|
}
|
||||||
else if (cgacol&32)
|
else if (m24->cgacol & 32)
|
||||||
{
|
{
|
||||||
cols[1] = col | 3;
|
cols[1] = col | 3;
|
||||||
cols[2] = col | 5;
|
cols[2] = col | 5;
|
||||||
|
|
@ -228,38 +264,38 @@ void m24_poll()
|
||||||
cols[2] = col | 4;
|
cols[2] = col | 4;
|
||||||
cols[3] = col | 6;
|
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];
|
dat = (m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + m24->base] << 8) |
|
||||||
ma++;
|
m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + 1 + m24->base];
|
||||||
|
m24->ma++;
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
{
|
{
|
||||||
buffer->line[displine][(x<<4)+(c<<1)+8]=
|
buffer->line[m24->displine][(x << 4) + (c << 1) + 8] =
|
||||||
buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
|
buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||||
dat <<= 2;
|
dat <<= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (m24->ctrl & 1)
|
||||||
if (m24_ctrl & 1)
|
|
||||||
{
|
{
|
||||||
dat2 = ((sc & 1) * 0x4000) | (m24_lineff * 0x2000);
|
dat2 = ((m24->sc & 1) * 0x4000) | (m24->lineff * 0x2000);
|
||||||
cols[0]=0; cols[1]=/*(cgacol&15)*/15+16;
|
cols[0] = 0; cols[1] = /*(m24->cgacol & 15)*/15 + 16;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dat2 = (sc & 1) * 0x2000;
|
dat2 = (m24->sc & 1) * 0x2000;
|
||||||
cols[0]=0; cols[1]=(cgacol&15)+16;
|
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];
|
dat = (m24->vram[((m24->ma << 1) & 0x1fff) + dat2] << 8) | m24->vram[((m24->ma << 1) & 0x1fff) + dat2 + 1];
|
||||||
ma++;
|
m24->ma++;
|
||||||
for (c = 0; c < 16; c++)
|
for (c = 0; c < 16; c++)
|
||||||
{
|
{
|
||||||
buffer->line[displine][(x<<4)+c+8]=cols[dat>>15];
|
buffer->line[m24->displine][(x << 4) + c + 8] = cols[dat >> 15];
|
||||||
dat <<= 1;
|
dat <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -267,170 +303,185 @@ void m24_poll()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16;
|
cols[0] = ((m24->cgamode & 0x12) == 0x12) ? 0 : (m24->cgacol & 15) + 16;
|
||||||
if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
|
if (m24->cgamode & 1) hline(buffer, 0, m24->displine, (m24->crtc[1] << 3) + 16, cols[0]);
|
||||||
else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
|
else hline(buffer, 0, m24->displine, (m24->crtc[1] << 4) + 16, cols[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cgamode&1) x=(crtc[1]<<3)+16;
|
if (m24->cgamode & 1) x = (m24->crtc[1] << 3) + 16;
|
||||||
else x=(crtc[1]<<4)+16;
|
else x = (m24->crtc[1] << 4) + 16;
|
||||||
|
|
||||||
sc=oldsc;
|
m24->sc = oldsc;
|
||||||
if (vc==crtc[7] && !sc)
|
if (m24->vc == m24->crtc[7] && !m24->sc)
|
||||||
cgastat|=8;
|
m24->stat |= 8;
|
||||||
displine++;
|
m24->displine++;
|
||||||
if (displine>=720) displine=0;
|
if (m24->displine >= 720) m24->displine = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// pclog("Line poll %i %i %i %i\n", m24_lineff, vc, sc, vadj);
|
// pclog("Line poll %i %i %i %i\n", m24_lineff, vc, sc, vadj);
|
||||||
vidtime+=dispontime;
|
m24->vidtime += m24->dispontime;
|
||||||
if (cgadispon) cgastat&=~1;
|
if (m24->dispon) m24->stat &= ~1;
|
||||||
linepos=0;
|
m24->linepos = 0;
|
||||||
m24_lineff ^= 1;
|
m24->lineff ^= 1;
|
||||||
if (m24_lineff)
|
if (m24->lineff)
|
||||||
{
|
{
|
||||||
ma = maback;
|
m24->ma = m24->maback;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (vsynctime)
|
if (m24->vsynctime)
|
||||||
{
|
{
|
||||||
vsynctime--;
|
m24->vsynctime--;
|
||||||
if (!vsynctime)
|
if (!m24->vsynctime)
|
||||||
cgastat&=~8;
|
m24->stat &= ~8;
|
||||||
}
|
}
|
||||||
if (sc==(crtc[11]&31) || ((crtc[8]&3)==3 && sc==((crtc[11]&31)>>1))) { con=0; coff=1; }
|
if (m24->sc == (m24->crtc[11] & 31) || ((m24->crtc[8] & 3) == 3 && m24->sc == ((m24->crtc[11] & 31) >> 1)))
|
||||||
if (vadj)
|
|
||||||
{
|
{
|
||||||
sc++;
|
m24->con = 0;
|
||||||
sc&=31;
|
m24->coff = 1;
|
||||||
ma=maback;
|
}
|
||||||
vadj--;
|
if (m24->vadj)
|
||||||
if (!vadj)
|
|
||||||
{
|
{
|
||||||
cgadispon=1;
|
m24->sc++;
|
||||||
ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
m24->sc &= 31;
|
||||||
sc=0;
|
m24->ma = m24->maback;
|
||||||
|
m24->vadj--;
|
||||||
|
if (!m24->vadj)
|
||||||
|
{
|
||||||
|
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;
|
m24->maback = m24->ma;
|
||||||
sc=0;
|
m24->sc = 0;
|
||||||
oldvc=vc;
|
oldvc = m24->vc;
|
||||||
vc++;
|
m24->vc++;
|
||||||
vc&=127;
|
m24->vc &= 127;
|
||||||
|
|
||||||
if (vc==crtc[6])
|
if (m24->vc == m24->crtc[6])
|
||||||
cgadispon=0;
|
m24->dispon=0;
|
||||||
|
|
||||||
if (oldvc==crtc[4])
|
if (oldvc == m24->crtc[4])
|
||||||
{
|
{
|
||||||
vc=0;
|
m24->vc = 0;
|
||||||
vadj=crtc[5];
|
m24->vadj = m24->crtc[5];
|
||||||
if (!vadj) cgadispon=1;
|
if (!m24->vadj) m24->dispon = 1;
|
||||||
if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
if (!m24->vadj) m24->ma = m24->maback = (m24->crtc[13] | (m24->crtc[12] << 8)) & 0x3fff;
|
||||||
if ((crtc[10]&0x60)==0x20) cursoron=0;
|
if ((m24->crtc[10] & 0x60) == 0x20) m24->cursoron = 0;
|
||||||
else cursoron=cgablink&16;
|
else m24->cursoron = m24->blink & 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vc==crtc[7])
|
if (m24->vc == m24->crtc[7])
|
||||||
{
|
{
|
||||||
cgadispon=0;
|
m24->dispon = 0;
|
||||||
displine=0;
|
m24->displine = 0;
|
||||||
vsynctime=(crtc[3]>>4)+1;
|
m24->vsynctime = (m24->crtc[3] >> 4) + 1;
|
||||||
if (crtc[7])
|
if (m24->crtc[7])
|
||||||
{
|
{
|
||||||
if (cgamode&1) x=(crtc[1]<<3)+16;
|
if (m24->cgamode & 1) x = (m24->crtc[1] << 3) + 16;
|
||||||
else x=(crtc[1]<<4)+16;
|
else x = (m24->crtc[1] << 4) + 16;
|
||||||
lastline++;
|
m24->lastline++;
|
||||||
if (x!=xsize || (lastline-firstline)!=ysize)
|
if (x != xsize || (m24->lastline - m24->firstline) != ysize)
|
||||||
{
|
{
|
||||||
xsize = x;
|
xsize = x;
|
||||||
ysize=lastline-firstline;
|
ysize = m24->lastline - m24->firstline;
|
||||||
if (xsize < 64) xsize = 656;
|
if (xsize < 64) xsize = 656;
|
||||||
if (ysize < 32) ysize = 200;
|
if (ysize < 32) ysize = 200;
|
||||||
updatewindowsize(xsize, ysize + 16);
|
updatewindowsize(xsize, ysize + 16);
|
||||||
}
|
}
|
||||||
startblit();
|
startblit();
|
||||||
video_blit_memtoscreen_8(0, firstline - 8, xsize, (lastline - firstline) + 16);
|
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);
|
if (readflash) rectfill(screen, winsizex - 40, 8, winsizex - 8, 14, 0xFFFFFFFF);
|
||||||
readflash = 0;
|
readflash = 0;
|
||||||
frames++;
|
frames++;
|
||||||
endblit();
|
endblit();
|
||||||
video_res_x = xsize - 16;
|
video_res_x = xsize - 16;
|
||||||
video_res_y = ysize;
|
video_res_y = ysize;
|
||||||
if (cgamode & 1)
|
if (m24->cgamode & 1)
|
||||||
{
|
{
|
||||||
video_res_x /= 8;
|
video_res_x /= 8;
|
||||||
video_res_y /= (crtc[9] + 1) * 2;
|
video_res_y /= (m24->crtc[9] + 1) * 2;
|
||||||
video_bpp = 0;
|
video_bpp = 0;
|
||||||
}
|
}
|
||||||
else if (!(cgamode & 2))
|
else if (!(m24->cgamode & 2))
|
||||||
{
|
{
|
||||||
video_res_x /= 16;
|
video_res_x /= 16;
|
||||||
video_res_y /= (crtc[9] + 1) * 2;
|
video_res_y /= (m24->crtc[9] + 1) * 2;
|
||||||
video_bpp = 0;
|
video_bpp = 0;
|
||||||
}
|
}
|
||||||
else if (!(cgamode&16))
|
else if (!(m24->cgamode & 16))
|
||||||
{
|
{
|
||||||
video_res_x /= 2;
|
video_res_x /= 2;
|
||||||
video_res_y /= 2;
|
video_res_y /= 2;
|
||||||
video_bpp = 2;
|
video_bpp = 2;
|
||||||
}
|
}
|
||||||
else if (!(m24_ctrl & 1))
|
else if (!(m24->ctrl & 1))
|
||||||
{
|
{
|
||||||
video_res_y /= 2;
|
video_res_y /= 2;
|
||||||
video_bpp = 1;
|
video_bpp = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
firstline=1000;
|
m24->firstline = 1000;
|
||||||
lastline=0;
|
m24->lastline = 0;
|
||||||
cgablink++;
|
m24->blink++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sc++;
|
m24->sc++;
|
||||||
sc&=31;
|
m24->sc &= 31;
|
||||||
ma=maback;
|
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++)
|
for (x = 0; x < (m24->crtc[1] << 1); x++)
|
||||||
charbuffer[x]=vram[(((ma<<1)+x)&0x3FFF) + m24_base];
|
m24->charbuffer[x] = m24->vram[(((m24->ma << 1) + x) & 0x3fff) + m24->base];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *m24_init()
|
||||||
int m24_init()
|
|
||||||
{
|
{
|
||||||
mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, NULL);
|
int c;
|
||||||
return 0;
|
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,
|
m24_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
m24_close,
|
||||||
m24_out,
|
m24_speed_changed,
|
||||||
m24_in,
|
NULL
|
||||||
/*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
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
extern device_t m24_device;
|
||||||
137
src/vid_oti067.c
137
src/vid_oti067.c
|
|
@ -1,126 +1,151 @@
|
||||||
/*Oak OTI067 emulation*/
|
/*Oak OTI067 emulation*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
#include "vid_oti067.h"
|
||||||
#include "vid_svga.h"
|
#include "vid_svga.h"
|
||||||
|
|
||||||
static int oti067_index;
|
typedef struct oti067_t
|
||||||
static uint8_t oti067_regs[32];
|
|
||||||
|
|
||||||
void oti067_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
|
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;
|
uint8_t old;
|
||||||
|
|
||||||
// pclog("oti067_out : %04X %02X %02X %i\n", addr, val, ram[0x489], ins);
|
// 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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
crtcreg=val&31;
|
svga->crtcreg = val & 31;
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
||||||
old=crtc[crtcreg];
|
old = svga->crtc[svga->crtcreg];
|
||||||
crtc[crtcreg]=val;
|
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;
|
fullchange = changeframecount;
|
||||||
svga_recalctimings();
|
svga_recalctimings(svga);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3DE: oti067_index=val&0x1F; return;
|
case 0x3DE:
|
||||||
|
oti067->index = val & 0x1f;
|
||||||
|
return;
|
||||||
case 0x3DF:
|
case 0x3DF:
|
||||||
oti067_regs[oti067_index]=val;
|
oti067->regs[oti067->index] = val;
|
||||||
switch (oti067_index)
|
switch (oti067->index)
|
||||||
{
|
{
|
||||||
case 0xD:
|
case 0xD:
|
||||||
vrammask=(val&0xC)?0x7FFFF:0x3FFFF;
|
svga->vrammask = (val & 0xc) ? 0x7ffff : 0x3ffff;
|
||||||
break;
|
break;
|
||||||
case 0x11:
|
case 0x11:
|
||||||
svgarbank=(val&0xF)*65536;
|
svga->read_bank = (val & 0xf) * 65536;
|
||||||
svgawbank=(val>>4)*65536;
|
svga->write_bank = (val >> 4) * 65536;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
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;
|
uint8_t temp;
|
||||||
|
|
||||||
// if (addr != 0x3da && addr != 0x3ba) pclog("oti067_in : %04X ", addr);
|
// 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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
temp = crtcreg;
|
temp = svga->crtcreg;
|
||||||
break;
|
break;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
temp = crtc[crtcreg];
|
temp = svga->crtc[svga->crtcreg];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3DE:
|
case 0x3DE:
|
||||||
temp = oti067_index|(2<<5);
|
temp = oti067->index | (2 << 5);
|
||||||
break;
|
break;
|
||||||
case 0x3DF:
|
case 0x3DF:
|
||||||
if (oti067_index==0x10) temp = 0x18;
|
if (oti067->index==0x10) temp = 0x18;
|
||||||
else if (oti067_index==0xD) temp = oti067_regs[oti067_index]|0xC0;
|
else if (oti067->index==0xD) temp = oti067->regs[oti067->index]|0xC0;
|
||||||
else temp = oti067_regs[oti067_index];
|
else temp = oti067->regs[oti067->index];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
temp = svga_in(addr, NULL);
|
temp = svga_in(addr, svga);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
// if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void oti067_recalctimings()
|
void oti067_recalctimings(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (oti067_regs[0x14]&0x08) svga_ma|=0x10000;
|
oti067_t *oti067 = (oti067_t *)svga->p;
|
||||||
if (oti067_regs[0x0D]&0x0C) svga_rowoffset<<=1;
|
|
||||||
svga_interlace = oti067_regs[0x14]&0x80;
|
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;
|
oti067_t *oti067 = malloc(sizeof(oti067_t));
|
||||||
svga_vram_limit = 1 << 19; /*512kb*/
|
memset(oti067, 0, sizeof(oti067_t));
|
||||||
vrammask = 0x7ffff;
|
|
||||||
bpp = 8;
|
svga_init(&oti067->svga, oti067, 1 << 19, /*512kb*/
|
||||||
svga_miscout = 1;
|
oti067_recalctimings,
|
||||||
return svga_init();
|
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,
|
oti067_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
oti067_close,
|
||||||
oti067_out,
|
oti067_speed_changed,
|
||||||
oti067_in,
|
svga_add_status_info
|
||||||
/*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
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
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
|
PC2086, PC3086 use PVGA1A
|
||||||
MegaPC uses W90C11A
|
MegaPC uses W90C11A
|
||||||
*/
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
#include "vid_paradise.h"
|
||||||
#include "vid_svga.h"
|
#include "vid_svga.h"
|
||||||
|
#include "vid_svga_render.h"
|
||||||
#include "vid_unk_ramdac.h"
|
#include "vid_unk_ramdac.h"
|
||||||
|
|
||||||
void paradise_write(uint32_t addr, uint8_t val, void *priv);
|
typedef struct paradise_t
|
||||||
uint8_t paradise_read(uint32_t addr, void *priv);
|
{
|
||||||
void paradise_remap();
|
svga_t svga;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PVGA1A = 0,
|
PVGA1A = 0,
|
||||||
WD90C11
|
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;
|
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;
|
// output = 3;
|
||||||
pclog("Paradise out %04X %02X %04X:%04X\n", addr, val, CS, pc);
|
pclog("Paradise out %04X %02X %04X:%04X\n", addr, val, CS, pc);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3c5:
|
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;
|
return;
|
||||||
seqregs[seqaddr & 0x1f] = val;
|
svga->seqregs[svga->seqaddr & 0x1f] = val;
|
||||||
if (seqaddr == 0x11)
|
if (svga->seqaddr == 0x11)
|
||||||
paradise_remap();
|
paradise_remap(paradise);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3cf:
|
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;
|
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);
|
// pclog("Write mapping %02X\n", val);
|
||||||
switch (val&0xC)
|
switch (val&0xC)
|
||||||
{
|
{
|
||||||
case 0x0: /*128k at A0000*/
|
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;
|
break;
|
||||||
case 0x4: /*64k at A0000*/
|
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;
|
break;
|
||||||
case 0x8: /*32k at B0000*/
|
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;
|
break;
|
||||||
case 0xC: /*32k at B8000*/
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gdcreg[6] = val;
|
svga->gdcreg[6] = val;
|
||||||
paradise_remap();
|
paradise_remap(paradise);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (gdcaddr == 0x9 || gdcaddr == 0xa)
|
if (svga->gdcaddr == 0x9 || svga->gdcaddr == 0xa)
|
||||||
{
|
{
|
||||||
gdcreg[gdcaddr] = val;
|
svga->gdcreg[svga->gdcaddr] = val;
|
||||||
paradise_remap();
|
paradise_remap(paradise);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (gdcaddr == 0xe)
|
if (svga->gdcaddr == 0xe)
|
||||||
{
|
{
|
||||||
gdcreg[0xe] = val;
|
svga->gdcreg[0xe] = val;
|
||||||
paradise_remap();
|
paradise_remap(paradise);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
if (paradise_type == PVGA1A)
|
if (paradise->type == PVGA1A)
|
||||||
crtcreg = val & 0x1f;
|
svga->crtcreg = val & 0x1f;
|
||||||
else
|
else
|
||||||
crtcreg = val & 0x3f;
|
svga->crtcreg = val & 0x3f;
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
if (crtcreg <= 7 && crtc[0x11] & 0x80)
|
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80)
|
||||||
return;
|
return;
|
||||||
if (crtcreg > 0x29 && (crtc[0x29] & 7) != 5)
|
if (svga->crtcreg > 0x29 && (svga->crtc[0x29] & 7) != 5)
|
||||||
return;
|
return;
|
||||||
if (crtcreg >= 0x31 && crtcreg <= 0x37)
|
if (svga->crtcreg >= 0x31 && svga->crtcreg <= 0x37)
|
||||||
return;
|
return;
|
||||||
old=crtc[crtcreg];
|
old = svga->crtc[svga->crtcreg];
|
||||||
crtc[crtcreg]=val;
|
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;
|
fullchange = changeframecount;
|
||||||
svga_recalctimings();
|
svga_recalctimings(¶dise->svga);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
|
case 0x3c2:
|
||||||
|
return 0x10;
|
||||||
|
|
||||||
case 0x3c5:
|
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;
|
return 0xff;
|
||||||
if (seqaddr > 0x12)
|
if (svga->seqaddr > 0x12)
|
||||||
return 0xff;
|
return 0xff;
|
||||||
return seqregs[seqaddr & 0x1f];
|
return svga->seqregs[svga->seqaddr & 0x1f];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3cf:
|
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;
|
return 0xff;
|
||||||
switch (gdcaddr)
|
switch (svga->gdcaddr)
|
||||||
{
|
{
|
||||||
case 0xf:
|
case 0xf:
|
||||||
return (gdcreg[0xf] & 0x17) | 0x80;
|
return (svga->gdcreg[0xf] & 0x17) | 0x80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
return crtcreg;
|
return svga->crtcreg;
|
||||||
case 0x3D5:
|
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 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");
|
// pclog("Remap 1\n");
|
||||||
paradise_bank_r[0] = paradise_bank_r[2] = (gdcreg[0x9] & 0x7f) << 12;
|
paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12;
|
||||||
paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||||
paradise_bank_w[0] = paradise_bank_w[2] = (gdcreg[0xa] & 0x7f) << 12;
|
paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12;
|
||||||
paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0xa] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
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");
|
// pclog("Remap 2\n");
|
||||||
paradise_bank_r[0] = paradise_bank_r[2] = (gdcreg[0xa] & 0x7f) << 12;
|
paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12;
|
||||||
paradise_bank_w[0] = paradise_bank_w[2] = (gdcreg[0xa] & 0x7f) << 12;
|
paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12;
|
||||||
paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||||
paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((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
|
else
|
||||||
{
|
{
|
||||||
// pclog("Remap 3\n");
|
// pclog("Remap 3\n");
|
||||||
paradise_bank_r[0] = paradise_bank_w[0] = (gdcreg[0xa] & 0x7f) << 12;
|
paradise->read_bank[0] = paradise->write_bank[0] = (svga->gdcreg[0xa] & 0x7f) << 12;
|
||||||
paradise_bank_r[1] = paradise_bank_w[1] = ((gdcreg[0xa] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
paradise->read_bank[1] = paradise->write_bank[1] = ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||||
paradise_bank_r[2] = paradise_bank_w[2] = (gdcreg[0x9] & 0x7f) << 12;
|
paradise->read_bank[2] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12;
|
||||||
paradise_bank_r[3] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
paradise->read_bank[3] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// pclog("Remap 4\n");
|
// pclog("Remap 4\n");
|
||||||
paradise_bank_r[0] = paradise_bank_r[2] = (gdcreg[0x9] & 0x7f) << 12;
|
paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12;
|
||||||
paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||||
paradise_bank_w[0] = paradise_bank_w[2] = (gdcreg[0x9] & 0x7f) << 12;
|
paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12;
|
||||||
paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
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 egacycles 1
|
||||||
#define egacycles2 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);
|
// 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);
|
// 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);
|
// 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);
|
// 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_t *paradise = malloc(sizeof(paradise_t));
|
||||||
{
|
svga_t *svga = ¶dise->svga;
|
||||||
paradise_type = PVGA1A;
|
memset(paradise, 0, sizeof(paradise_t));
|
||||||
vrammask = 0x3ffff;
|
|
||||||
pclog("Init PVGA1A\n");
|
io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise);
|
||||||
svga_vram_limit = 1 << 18; /*256kb*/
|
|
||||||
}
|
svga_init(¶dise->svga, paradise, 1 << 18, /*256kb*/
|
||||||
if (romset == ROM_MEGAPC)
|
NULL,
|
||||||
{
|
paradise_in, paradise_out,
|
||||||
paradise_type = WD90C11;
|
NULL);
|
||||||
vrammask = 0x7ffff;
|
|
||||||
crtc[0x36] = '1';
|
svga->crtc[0x31] = 'W';
|
||||||
crtc[0x37] = '1';
|
svga->crtc[0x32] = 'D';
|
||||||
pclog("Init WD90C11\n");
|
svga->crtc[0x33] = '9';
|
||||||
svga_vram_limit = 1 << 19; /*512kb*/
|
svga->crtc[0x34] = '0';
|
||||||
}
|
svga->crtc[0x35] = 'C';
|
||||||
crtc[0x31] = 'W';
|
|
||||||
crtc[0x32] = 'D';
|
svga->bpp = 8;
|
||||||
crtc[0x33] = '9';
|
svga->miscout = 1;
|
||||||
crtc[0x34] = '0';
|
|
||||||
crtc[0x35] = 'C';
|
paradise->type = PVGA1A;
|
||||||
svga_recalctimings_ex = paradise_recalctimings;
|
|
||||||
return svga_init();
|
return paradise;
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXCARD vid_paradise =
|
void *paradise_wd90c11_init()
|
||||||
{
|
{
|
||||||
paradise_init,
|
paradise_t *paradise = malloc(sizeof(paradise_t));
|
||||||
/*IO at 3Cx/3Dx*/
|
svga_t *svga = ¶dise->svga;
|
||||||
paradise_out,
|
memset(paradise, 0, sizeof(paradise_t));
|
||||||
paradise_in,
|
|
||||||
/*IO at 3Ax/3Bx*/
|
|
||||||
video_out_null,
|
|
||||||
video_in_null,
|
|
||||||
|
|
||||||
svga_poll,
|
io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise);
|
||||||
svga_recalctimings,
|
|
||||||
|
|
||||||
paradise_write,
|
svga_init(¶dise->svga, paradise, 1 << 19, /*512kb*/
|
||||||
video_write_null,
|
paradise_recalctimings,
|
||||||
video_write_null,
|
paradise_in, paradise_out,
|
||||||
|
NULL);
|
||||||
|
|
||||||
paradise_read,
|
svga->crtc[0x31] = 'W';
|
||||||
video_read_null,
|
svga->crtc[0x32] = 'D';
|
||||||
video_read_null
|
svga->crtc[0x33] = '9';
|
||||||
|
svga->crtc[0x34] = '0';
|
||||||
|
svga->crtc[0x35] = 'C';
|
||||||
|
svga->crtc[0x36] = '1';
|
||||||
|
svga->crtc[0x37] = '1';
|
||||||
|
|
||||||
|
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;
|
||||||
450
src/vid_pc1512.c
450
src/vid_pc1512.c
|
|
@ -6,122 +6,142 @@
|
||||||
|
|
||||||
The Technical Reference Manual lists the video waitstate time as between 12
|
The Technical Reference Manual lists the video waitstate time as between 12
|
||||||
and 46 cycles. PCem currently always uses the lower number.*/
|
and 46 cycles. PCem currently always uses the lower number.*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vid_cga.h"
|
#include "vid_pc1512.h"
|
||||||
|
|
||||||
static uint8_t pc1512_plane_write,pc1512_plane_read,pc1512_border;
|
typedef struct pc1512_t
|
||||||
|
|
||||||
void pc1512_recalctimings();
|
|
||||||
|
|
||||||
void pc1512_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
|
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;
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3d4:
|
||||||
crtcreg=val&31;
|
pc1512->crtcreg = val & 31;
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3d5:
|
||||||
old=crtc[crtcreg];
|
old = pc1512->crtc[pc1512->crtcreg];
|
||||||
crtc[crtcreg]=val&crtcmask[crtcreg];
|
pc1512->crtc[pc1512->crtcreg] = val & crtcmask[pc1512->crtcreg];
|
||||||
if (old != val)
|
if (old != val)
|
||||||
{
|
{
|
||||||
if (crtcreg<0xE || crtcreg>0x10)
|
if (pc1512->crtcreg < 0xe || pc1512->crtcreg > 0x10)
|
||||||
{
|
{
|
||||||
fullchange = changeframecount;
|
fullchange = changeframecount;
|
||||||
pc1512_recalctimings();
|
pc1512_recalctimings(pc1512);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x3D8:
|
case 0x3d8:
|
||||||
if ((val&0x12)==0x12 && (cgamode&0x12)!=0x12)
|
if ((val & 0x12) == 0x12 && (pc1512->cgamode & 0x12) != 0x12)
|
||||||
{
|
{
|
||||||
pc1512_plane_write=0xF;
|
pc1512->plane_write = 0xf;
|
||||||
pc1512_plane_read =0;
|
pc1512->plane_read = 0;
|
||||||
}
|
}
|
||||||
cgamode=val;
|
pc1512->cgamode = val;
|
||||||
return;
|
return;
|
||||||
case 0x3D9:
|
case 0x3d9:
|
||||||
cgacol=val;
|
pc1512->cgacol = val;
|
||||||
return;
|
return;
|
||||||
case 0x3DD:
|
case 0x3dd:
|
||||||
pc1512_plane_write=val;
|
pc1512->plane_write = val;
|
||||||
return;
|
return;
|
||||||
case 0x3DE:
|
case 0x3de:
|
||||||
pc1512_plane_read=val&3;
|
pc1512->plane_read = val & 3;
|
||||||
return;
|
return;
|
||||||
case 0x3DF:
|
case 0x3df:
|
||||||
pc1512_border=val;
|
pc1512->border = val;
|
||||||
return;
|
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);
|
// pclog("PC1512 in %04X %02X %04X:%04X\n",addr,CS,pc);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3d4:
|
||||||
return crtcreg;
|
return pc1512->crtcreg;
|
||||||
case 0x3D5:
|
case 0x3d5:
|
||||||
return crtc[crtcreg];
|
return pc1512->crtc[pc1512->crtcreg];
|
||||||
case 0x3DA:
|
case 0x3da:
|
||||||
return cgastat;
|
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;
|
||||||
{
|
|
||||||
dumpregs();
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
pclog("PC1512 write %08X %02X %02X %01X %04X:%04X\n",addr,val,cgamode&0x12,pc1512_plane_write,CS,pc);*/
|
|
||||||
cycles -= 12;
|
cycles -= 12;
|
||||||
addr&=0x7FFF;
|
addr &= 0x3fff;
|
||||||
if ((cgamode&0x12)==0x12)
|
|
||||||
|
if ((pc1512->cgamode & 0x12) == 0x12)
|
||||||
{
|
{
|
||||||
if (pc1512_plane_write&1) vram[addr]=val;
|
if (pc1512->plane_write & 1) pc1512->vram[addr] = val;
|
||||||
if (pc1512_plane_write&2) vram[addr|0x10000]=val;
|
if (pc1512->plane_write & 2) pc1512->vram[addr | 0x4000] = val;
|
||||||
if (pc1512_plane_write&4) vram[addr|0x20000]=val;
|
if (pc1512->plane_write & 4) pc1512->vram[addr | 0x8000] = val;
|
||||||
if (pc1512_plane_write&8) vram[addr|0x30000]=val;
|
if (pc1512->plane_write & 8) pc1512->vram[addr | 0xc000] = val;
|
||||||
}
|
}
|
||||||
else
|
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);
|
pc1512_t *pc1512 = (pc1512_t *)p;
|
||||||
|
|
||||||
cycles -= 12;
|
cycles -= 12;
|
||||||
addr&=0x7FFF;
|
addr &= 0x3fff;
|
||||||
if ((cgamode&0x12)==0x12)
|
|
||||||
return vram[addr|(pc1512_plane_read<<16)];
|
if ((pc1512->cgamode & 0x12) == 0x12)
|
||||||
return vram[addr];
|
return pc1512->vram[addr | (pc1512->plane_read << 14)];
|
||||||
|
return pc1512->vram[addr];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int linepos,displine;
|
static void pc1512_recalctimings(pc1512_t *pc1512)
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
double _dispontime, _dispofftime;
|
double _dispontime, _dispofftime, disptime;
|
||||||
disptime = 128; /*Fixed on PC1512*/
|
disptime = 128; /*Fixed on PC1512*/
|
||||||
_dispontime = 80;
|
_dispontime = 80;
|
||||||
_dispofftime = disptime - _dispontime;
|
_dispofftime = disptime - _dispontime;
|
||||||
|
|
@ -129,13 +149,14 @@ void pc1512_recalctimings()
|
||||||
_dispontime *= CGACONST;
|
_dispontime *= CGACONST;
|
||||||
_dispofftime *= 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);
|
// 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));
|
pc1512->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||||
dispofftime = (int)(_dispofftime * (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 drawcursor;
|
||||||
int x, c;
|
int x, c;
|
||||||
int oldvc;
|
int oldvc;
|
||||||
|
|
@ -145,43 +166,45 @@ void pc1512_poll()
|
||||||
int col;
|
int col;
|
||||||
int oldsc;
|
int oldsc;
|
||||||
|
|
||||||
if (!linepos)
|
if (!pc1512->linepos)
|
||||||
{
|
{
|
||||||
vidtime+=dispofftime;
|
pc1512->vidtime += pc1512->dispofftime;
|
||||||
cgastat|=1;
|
pc1512->stat |= 1;
|
||||||
linepos=1;
|
pc1512->linepos = 1;
|
||||||
oldsc=sc;
|
oldsc = pc1512->sc;
|
||||||
if (cgadispon)
|
if (pc1512->dispon)
|
||||||
{
|
{
|
||||||
if (displine<firstline) firstline=displine;
|
if (pc1512->displine < pc1512->firstline)
|
||||||
lastline=displine;
|
pc1512->firstline = pc1512->displine;
|
||||||
|
pc1512->lastline = pc1512->displine;
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
{
|
{
|
||||||
if ((cgamode&0x12)==0x12)
|
if ((pc1512->cgamode & 0x12) == 0x12)
|
||||||
{
|
{
|
||||||
buffer->line[displine][c]=(pc1512_border&15)+16;
|
buffer->line[pc1512->displine][c] = (pc1512->border & 15) + 16;
|
||||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
|
if (pc1512->cgamode & 1) buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 3) + 8] = 0;
|
||||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=0;
|
else buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 4) + 8] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buffer->line[displine][c]=(cgacol&15)+16;
|
buffer->line[pc1512->displine][c] = (pc1512->cgacol & 15) + 16;
|
||||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16;
|
if (pc1512->cgamode & 1) buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 3) + 8] = (pc1512->cgacol & 15) + 16;
|
||||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=(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++)
|
for (x = 0; x < 80; x++)
|
||||||
{
|
{
|
||||||
chr=vram[((ma<<1)&0x3FFF)];
|
chr = pc1512->vram[ ((pc1512->ma << 1) & 0x3fff)];
|
||||||
attr=vram[(((ma<<1)+1)&0x3FFF)];
|
attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)];
|
||||||
drawcursor=((ma==ca) && con && cursoron);
|
drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron);
|
||||||
if (cgamode&0x20)
|
if (pc1512->cgamode & 0x20)
|
||||||
{
|
{
|
||||||
cols[1] = (attr & 15) + 16;
|
cols[1] = (attr & 15) + 16;
|
||||||
cols[0] = ((attr >> 4) & 7) + 16;
|
cols[0] = ((attr >> 4) & 7) + 16;
|
||||||
if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
|
if ((pc1512->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||||
|
cols[1] = cols[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -191,58 +214,61 @@ void pc1512_poll()
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15;
|
buffer->line[pc1512->displine][(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
|
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++)
|
for (x = 0; x < 40; x++)
|
||||||
{
|
{
|
||||||
chr=vram[((ma<<1)&0x3FFF)];
|
chr = pc1512->vram[ ((pc1512->ma << 1) & 0x3fff)];
|
||||||
attr=vram[(((ma<<1)+1)&0x3FFF)];
|
attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)];
|
||||||
drawcursor=((ma==ca) && con && cursoron);
|
drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron);
|
||||||
if (cgamode&0x20)
|
if (pc1512->cgamode & 0x20)
|
||||||
{
|
{
|
||||||
cols[1] = (attr & 15) + 16;
|
cols[1] = (attr & 15) + 16;
|
||||||
cols[0] = ((attr >> 4) & 7) + 16;
|
cols[0] = ((attr >> 4) & 7) + 16;
|
||||||
if ((cgablink&16) && (attr&0x80)) cols[1]=cols[0];
|
if ((pc1512->blink & 16) && (attr & 0x80))
|
||||||
|
cols[1] = cols[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cols[1] = (attr & 15) + 16;
|
cols[1] = (attr & 15) + 16;
|
||||||
cols[0] = (attr >> 4) + 16;
|
cols[0] = (attr >> 4) + 16;
|
||||||
}
|
}
|
||||||
ma++;
|
pc1512->ma++;
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
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;
|
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
|
else
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
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];
|
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;
|
cols[0] = (pc1512->cgacol & 15) | 16;
|
||||||
col=(cgacol&16)?24:16;
|
col = (pc1512->cgacol & 16) ? 24 : 16;
|
||||||
if (cgamode&4)
|
if (pc1512->cgamode & 4)
|
||||||
{
|
{
|
||||||
cols[1] = col | 3;
|
cols[1] = col | 3;
|
||||||
cols[2] = col | 4;
|
cols[2] = col | 4;
|
||||||
cols[3] = col | 7;
|
cols[3] = col | 7;
|
||||||
}
|
}
|
||||||
else if (cgacol&32)
|
else if (pc1512->cgacol & 32)
|
||||||
{
|
{
|
||||||
cols[1] = col | 3;
|
cols[1] = col | 3;
|
||||||
cols[2] = col | 5;
|
cols[2] = col | 5;
|
||||||
|
|
@ -256,12 +282,12 @@ void pc1512_poll()
|
||||||
}
|
}
|
||||||
for (x = 0; x < 40; x++)
|
for (x = 0; x < 40; x++)
|
||||||
{
|
{
|
||||||
dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1];
|
dat = (pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000)] << 8) | pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000) + 1];
|
||||||
ma++;
|
pc1512->ma++;
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
{
|
{
|
||||||
buffer->line[displine][(x<<4)+(c<<1)+8]=
|
buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] =
|
||||||
buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
|
buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||||
dat <<= 2;
|
dat <<= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -270,16 +296,16 @@ void pc1512_poll()
|
||||||
{
|
{
|
||||||
for (x = 0; x < 40; x++)
|
for (x = 0; x < 40; x++)
|
||||||
{
|
{
|
||||||
ca=((ma<<1)&0x1FFF)+((sc&1)*0x2000);
|
ca = ((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000);
|
||||||
dat=(vram[ca]<<8)|vram[ca+1];
|
dat = (pc1512->vram[ca] << 8) | pc1512->vram[ca + 1];
|
||||||
dat2=(vram[ca+0x10000]<<8)|vram[ca+0x10001];
|
dat2 = (pc1512->vram[ca + 0x4000] << 8) | pc1512->vram[ca + 0x4001];
|
||||||
dat3=(vram[ca+0x20000]<<8)|vram[ca+0x20001];
|
dat3 = (pc1512->vram[ca + 0x8000] << 8) | pc1512->vram[ca + 0x8001];
|
||||||
dat4=(vram[ca+0x30000]<<8)|vram[ca+0x30001];
|
dat4 = (pc1512->vram[ca + 0xc000] << 8) | pc1512->vram[ca + 0xc001];
|
||||||
|
|
||||||
ma++;
|
pc1512->ma++;
|
||||||
for (c = 0; c < 16; c++)
|
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;
|
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;
|
dat <<= 1;
|
||||||
dat2 <<= 1;
|
dat2 <<= 1;
|
||||||
dat3 <<= 1;
|
dat3 <<= 1;
|
||||||
|
|
@ -290,80 +316,88 @@ void pc1512_poll()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16;
|
cols[0] = ((pc1512->cgamode & 0x12) == 0x12) ? 0 : (pc1512->cgacol & 15) + 16;
|
||||||
if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
|
if (pc1512->cgamode & 1) hline(buffer, 0, pc1512->displine, (pc1512->crtc[1] << 3) + 16, cols[0]);
|
||||||
else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
|
else hline(buffer, 0, pc1512->displine, (pc1512->crtc[1] << 4) + 16, cols[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sc=oldsc;
|
pc1512->sc = oldsc;
|
||||||
if (vsynctime)
|
if (pc1512->vsynctime)
|
||||||
cgastat|=8;
|
pc1512->stat |= 8;
|
||||||
displine++;
|
pc1512->displine++;
|
||||||
if (displine>=360) displine=0;
|
if (pc1512->displine >= 360)
|
||||||
|
pc1512->displine = 0;
|
||||||
// pclog("Line %i %i %i %i %i %i\n",displine,cgadispon,firstline,lastline,vc,sc);
|
// pclog("Line %i %i %i %i %i %i\n",displine,cgadispon,firstline,lastline,vc,sc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vidtime+=dispontime;
|
pc1512->vidtime += pc1512->dispontime;
|
||||||
if ((lastline-firstline)==199) cgadispon=0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/
|
if ((pc1512->lastline - pc1512->firstline) == 199)
|
||||||
if (cgadispon) cgastat&=~1;
|
pc1512->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/
|
||||||
linepos=0;
|
if (pc1512->dispon)
|
||||||
if (vsynctime)
|
pc1512->stat &= ~1;
|
||||||
|
pc1512->linepos = 0;
|
||||||
|
if (pc1512->vsynctime)
|
||||||
{
|
{
|
||||||
vsynctime--;
|
pc1512->vsynctime--;
|
||||||
if (!vsynctime)
|
if (!pc1512->vsynctime)
|
||||||
cgastat&=~8;
|
pc1512->stat &= ~8;
|
||||||
}
|
}
|
||||||
if (sc==(crtc[11]&31)) { con=0; coff=1; }
|
if (pc1512->sc == (pc1512->crtc[11] & 31))
|
||||||
if (vadj)
|
|
||||||
{
|
{
|
||||||
sc++;
|
pc1512->con = 0;
|
||||||
sc&=31;
|
pc1512->coff = 1;
|
||||||
ma=maback;
|
}
|
||||||
vadj--;
|
if (pc1512->vadj)
|
||||||
if (!vadj)
|
|
||||||
{
|
{
|
||||||
cgadispon=1;
|
pc1512->sc++;
|
||||||
ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
pc1512->sc &= 31;
|
||||||
sc=0;
|
pc1512->ma = pc1512->maback;
|
||||||
|
pc1512->vadj--;
|
||||||
|
if (!pc1512->vadj)
|
||||||
|
{
|
||||||
|
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;
|
pc1512->maback = pc1512->ma;
|
||||||
sc=0;
|
pc1512->sc = 0;
|
||||||
oldvc=vc;
|
oldvc = pc1512->vc;
|
||||||
vc++;
|
pc1512->vc++;
|
||||||
vc&=127;
|
pc1512->vc &= 127;
|
||||||
|
|
||||||
if (displine == 32)//oldvc == (cgamode & 2) ? 127 : 31)
|
if (pc1512->displine == 32)//oldvc == (cgamode & 2) ? 127 : 31)
|
||||||
{
|
{
|
||||||
vc=0;
|
pc1512->vc = 0;
|
||||||
vadj=6;
|
pc1512->vadj = 6;
|
||||||
if ((crtc[10]&0x60)==0x20) cursoron=0;
|
if ((pc1512->crtc[10] & 0x60) == 0x20) pc1512->cursoron = 0;
|
||||||
else cursoron=cgablink&16;
|
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;
|
pc1512->dispon = 0;
|
||||||
displine=0;
|
pc1512->displine = 0;
|
||||||
vsynctime=46;
|
pc1512->vsynctime = 46;
|
||||||
|
|
||||||
if (cgamode&1) x=(crtc[1]<<3)+16;
|
if (pc1512->cgamode&1) x = (pc1512->crtc[1] << 3) + 16;
|
||||||
else x=(crtc[1]<<4)+16;
|
else x = (pc1512->crtc[1] << 4) + 16;
|
||||||
x = 640 + 16;
|
x = 640 + 16;
|
||||||
lastline++;
|
pc1512->lastline++;
|
||||||
if (x!=xsize || (lastline-firstline)!=ysize)
|
|
||||||
|
if (x != xsize || (pc1512->lastline - pc1512->firstline) != ysize)
|
||||||
{
|
{
|
||||||
xsize = x;
|
xsize = x;
|
||||||
ysize=lastline-firstline;
|
ysize = pc1512->lastline - pc1512->firstline;
|
||||||
if (xsize < 64) xsize = 656;
|
if (xsize < 64) xsize = 656;
|
||||||
if (ysize < 32) ysize = 200;
|
if (ysize < 32) ysize = 200;
|
||||||
updatewindowsize(xsize, (ysize << 1) + 16);
|
updatewindowsize(xsize, (ysize << 1) + 16);
|
||||||
}
|
}
|
||||||
startblit();
|
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);
|
// 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);
|
// 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);
|
// else stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,xsize,((lastline-firstline)<<1)+16+2);
|
||||||
|
|
@ -372,19 +406,19 @@ startblit();
|
||||||
endblit();
|
endblit();
|
||||||
video_res_x = xsize - 16;
|
video_res_x = xsize - 16;
|
||||||
video_res_y = ysize;
|
video_res_y = ysize;
|
||||||
if (cgamode & 1)
|
if (pc1512->cgamode & 1)
|
||||||
{
|
{
|
||||||
video_res_x /= 8;
|
video_res_x /= 8;
|
||||||
video_res_y /= crtc[9] + 1;
|
video_res_y /= pc1512->crtc[9] + 1;
|
||||||
video_bpp = 0;
|
video_bpp = 0;
|
||||||
}
|
}
|
||||||
else if (!(cgamode & 2))
|
else if (!(pc1512->cgamode & 2))
|
||||||
{
|
{
|
||||||
video_res_x /= 16;
|
video_res_x /= 16;
|
||||||
video_res_y /= crtc[9] + 1;
|
video_res_y /= pc1512->crtc[9] + 1;
|
||||||
video_bpp = 0;
|
video_bpp = 0;
|
||||||
}
|
}
|
||||||
else if (!(cgamode&16))
|
else if (!(pc1512->cgamode & 16))
|
||||||
{
|
{
|
||||||
video_res_x /= 2;
|
video_res_x /= 2;
|
||||||
video_bpp = 2;
|
video_bpp = 2;
|
||||||
|
|
@ -394,45 +428,59 @@ endblit();
|
||||||
video_bpp = 4;
|
video_bpp = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
firstline=1000;
|
pc1512->firstline = 1000;
|
||||||
lastline=0;
|
pc1512->lastline = 0;
|
||||||
cgablink++;
|
pc1512->blink++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sc++;
|
pc1512->sc++;
|
||||||
sc&=31;
|
pc1512->sc &= 31;
|
||||||
ma=maback;
|
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);
|
int c;
|
||||||
return 0;
|
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,
|
pc1512_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
pc1512_close,
|
||||||
pc1512_out,
|
pc1512_speed_changed,
|
||||||
pc1512_in,
|
NULL
|
||||||
/*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
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
src/vid_pc1512.h
Normal file
1
src/vid_pc1512.h
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
extern device_t pc1512_device;
|
||||||
144
src/vid_pc1640.c
144
src/vid_pc1640.c
|
|
@ -1,99 +1,145 @@
|
||||||
/*PC1640 video emulation.
|
/*PC1640 video emulation.
|
||||||
Mostly standard EGA, but with CGA & Hercules emulation*/
|
Mostly standard EGA, but with CGA & Hercules emulation*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#include "timer.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vid_cga.h"
|
#include "vid_cga.h"
|
||||||
#include "vid_ega.h"
|
#include "vid_ega.h"
|
||||||
|
#include "vid_pc1640.h"
|
||||||
|
|
||||||
static int pc1640_cga=1;
|
typedef struct pc1640_t
|
||||||
|
|
||||||
void pc1640_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3DB:
|
case 0x3db:
|
||||||
pc1640_cga=val&0x40;
|
pc1640->cga_enabled = val & 0x40;
|
||||||
mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
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, NULL);
|
mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, &pc1640->cga);
|
||||||
if (pc1640_cga)
|
if (pc1640->cga_enabled)
|
||||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, &pc1640->cga);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (gdcreg[6] & 0xC)
|
switch (pc1640->ega.gdcreg[6] & 0xc)
|
||||||
{
|
{
|
||||||
case 0x0: /*128k at A0000*/
|
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;
|
break;
|
||||||
case 0x4: /*64k at A0000*/
|
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;
|
break;
|
||||||
case 0x8: /*32k at B0000*/
|
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;
|
break;
|
||||||
case 0xC: /*32k at B8000*/
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pclog("3DB write %02X\n", val);
|
pclog("3DB write %02X\n", val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pc1640_cga) cga_out(addr, val, NULL);
|
if (pc1640->cga_enabled) cga_out(addr, val, &pc1640->cga);
|
||||||
else ega_out(addr, val, NULL);
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
if (pc1640_cga) return cga_in(addr, NULL);
|
|
||||||
else return ega_in(addr, NULL);
|
if (pc1640->cga_enabled) return cga_in(addr, &pc1640->cga);
|
||||||
|
else return ega_in(addr, &pc1640->ega);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pc1640_recalctimings()
|
void pc1640_recalctimings(pc1640_t *pc1640)
|
||||||
{
|
{
|
||||||
if (pc1640_cga) cga_recalctimings();
|
if (pc1640->cga_enabled)
|
||||||
else ega_recalctimings();
|
{
|
||||||
|
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 pc1640_poll(void *p)
|
||||||
{
|
{
|
||||||
if (pc1640_cga) cga_poll();
|
pc1640_t *pc1640 = (pc1640_t *)p;
|
||||||
else ega_poll();
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pc1640_init()
|
void *pc1640_init()
|
||||||
{
|
{
|
||||||
int r = ega_init();
|
pc1640_t *pc1640 = malloc(sizeof(pc1640_t));
|
||||||
|
cga_t *cga = &pc1640->cga;
|
||||||
|
ega_t *ega = &pc1640->ega;
|
||||||
|
memset(pc1640, 0, sizeof(pc1640_t));
|
||||||
|
|
||||||
pc1640_cga = 1;
|
ega_init(&pc1640->ega);
|
||||||
|
pc1640->cga.vram = pc1640->ega.vram;
|
||||||
|
pc1640->cga_enabled = 1;
|
||||||
|
cga_init(&pc1640->cga);
|
||||||
|
|
||||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
timer_add(pc1640_poll, &pc1640->vidtime, TIMER_ALWAYS_ENABLED, pc1640);
|
||||||
|
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, cga);
|
||||||
return r;
|
io_sethandler(0x03a0, 0x0040, pc1640_in, NULL, NULL, pc1640_out, NULL, NULL, pc1640);
|
||||||
|
return cga;
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXCARD vid_pc1640 =
|
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,
|
pc1640_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
pc1640_close,
|
||||||
pc1640_out,
|
pc1640_speed_changed,
|
||||||
pc1640_in,
|
NULL
|
||||||
/*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
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
src/vid_pc1640.h
Normal file
1
src/vid_pc1640.h
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
extern device_t pc1640_device;
|
||||||
139
src/vid_pc200.c
139
src/vid_pc200.c
|
|
@ -1,104 +1,139 @@
|
||||||
/*PC200 video emulation.
|
/*PC200 video emulation.
|
||||||
CGA with some NMI stuff. But we don't need that as it's only used for TV and
|
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*/
|
LCD displays, and we're emulating a CRT*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#include "timer.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vid_cga.h"
|
#include "vid_cga.h"
|
||||||
|
#include "vid_pc200.h"
|
||||||
|
|
||||||
uint8_t pc200_3dd, pc200_3de, pc200_3df;
|
typedef struct pc200_t
|
||||||
|
|
||||||
void pc200_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
|
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;
|
uint8_t old;
|
||||||
|
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D5:
|
case 0x3d5:
|
||||||
if (!(pc200_3de&0x40) && crtcreg<=11)
|
if (!(pc200->reg_3de & 0x40) && cga->crtcreg <= 11)
|
||||||
{
|
{
|
||||||
if (pc200_3de&0x80) nmi=1;
|
if (pc200->reg_3de & 0x80)
|
||||||
pc200_3dd=0x20|(crtcreg&0x1F);
|
nmi = 1;
|
||||||
pc200_3df=val;
|
|
||||||
|
pc200->reg_3dd = 0x20 | (cga->crtcreg & 0x1f);
|
||||||
|
pc200->reg_3df = val;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
old=crtc[crtcreg];
|
old = cga->crtc[cga->crtcreg];
|
||||||
crtc[crtcreg]=val&crtcmask[crtcreg];
|
cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
|
||||||
if (old != val)
|
if (old != val)
|
||||||
{
|
{
|
||||||
if (crtcreg<0xE || crtcreg>0x10)
|
if (cga->crtcreg < 0xe || cga->crtcreg > 0x10)
|
||||||
{
|
{
|
||||||
fullchange = changeframecount;
|
fullchange = changeframecount;
|
||||||
cga_recalctimings();
|
cga_recalctimings(cga);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x3D8:
|
case 0x3d8:
|
||||||
old = cgamode;
|
old = cga->cgamode;
|
||||||
cgamode=val;
|
cga->cgamode = val;
|
||||||
if ((cgamode ^ old) & 3)
|
if ((cga->cgamode ^ old) & 3)
|
||||||
cga_recalctimings();
|
cga_recalctimings(cga);
|
||||||
pc200_3dd|=0x80;
|
pc200->reg_3dd |= 0x80;
|
||||||
if (pc200_3de&0x80)
|
if (pc200->reg_3de & 0x80)
|
||||||
nmi = 1;
|
nmi = 1;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x3DE:
|
case 0x3de:
|
||||||
pc200_3de=val;
|
pc200->reg_3de = val;
|
||||||
pc200_3dd=0x1F;
|
pc200->reg_3dd = 0x1f;
|
||||||
if (val&0x80) pc200_3dd|=0x40;
|
if (val & 0x80)
|
||||||
|
pc200->reg_3dd |= 0x40;
|
||||||
return;
|
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;
|
uint8_t temp;
|
||||||
|
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D8:
|
case 0x3D8:
|
||||||
return cgamode;
|
return cga->cgamode;
|
||||||
|
|
||||||
case 0x3DD:
|
case 0x3DD:
|
||||||
temp = pc200_3dd;
|
temp = pc200->reg_3dd;
|
||||||
pc200_3dd &= 0x1F;
|
pc200->reg_3dd &= 0x1f;
|
||||||
return temp;
|
return temp;
|
||||||
|
|
||||||
case 0x3DE:
|
case 0x3DE:
|
||||||
return (pc200_3de&0xC7)| 0x18; /*External CGA*/
|
return (pc200->reg_3de & 0xc7) | 0x18; /*External CGA*/
|
||||||
|
|
||||||
case 0x3DF:
|
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);
|
pc200_t *pc200 = malloc(sizeof(pc200_t));
|
||||||
return cga_init();
|
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,
|
pc200_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
pc200_close,
|
||||||
pc200_out,
|
pc200_speed_changed,
|
||||||
pc200_in,
|
NULL
|
||||||
/*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
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
src/vid_pc200.h
Normal file
1
src/vid_pc200.h
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
extern device_t pc200_device;
|
||||||
1695
src/vid_s3.c
1695
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
|
/*S3 ViRGE emulation
|
||||||
|
|
||||||
The SVGA core is largely the same as older S3 chips, but the blitter is totally different*/
|
The SVGA core is largely the same as older S3 chips, but the blitter is totally different*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
#include "vid_s3_virge.h"
|
||||||
#include "vid_svga.h"
|
#include "vid_svga.h"
|
||||||
#include "vid_svga_render.h"
|
#include "vid_svga_render.h"
|
||||||
//#include "vid_sdac_ramdac.h"
|
//#include "vid_sdac_ramdac.h"
|
||||||
|
|
||||||
void s3_virge_updatemapping();
|
typedef struct virge_t
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
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;
|
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);
|
pclog("S3 out %04X %02X %04X:%08X %04X %04X %i\n", addr, val, CS, pc, ES, BX, ins);
|
||||||
|
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3c5:
|
case 0x3c5:
|
||||||
if (seqaddr >= 0x10)
|
if (svga->seqaddr >= 0x10)
|
||||||
{
|
{
|
||||||
seqregs[seqaddr&0x1F]=val;
|
svga->seqregs[svga->seqaddr & 0x1f]=val;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (seqaddr == 4) /*Chain-4 - update banking*/
|
if (svga->seqaddr == 4) /*Chain-4 - update banking*/
|
||||||
{
|
{
|
||||||
if (val & 8) svgawbank = svgarbank = s3_bank << 16;
|
if (val & 8) svga->write_bank = svga->read_bank = virge->bank << 16;
|
||||||
else svgawbank = svgarbank = s3_bank << 14;
|
else svga->write_bank = svga->read_bank = virge->bank << 14;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -54,86 +69,88 @@ void s3_virge_out(uint16_t addr, uint8_t val, void *priv)
|
||||||
//sdac_ramdac_out(addr,val);
|
//sdac_ramdac_out(addr,val);
|
||||||
//return;
|
//return;
|
||||||
|
|
||||||
case 0x3D4:
|
case 0x3d4:
|
||||||
crtcreg=val&0x7f;
|
svga->crtcreg = val & 0x7f;
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3d5:
|
||||||
// if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val);
|
// if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val);
|
||||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80)
|
||||||
if (crtcreg >= 0x20 && crtcreg != 0x38 && (crtc[0x38] & 0xcc) != 0x48) return;
|
return;
|
||||||
old=crtc[crtcreg];
|
if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48)
|
||||||
crtc[crtcreg]=val;
|
return;
|
||||||
switch (crtcreg)
|
old = svga->crtc[svga->crtcreg];
|
||||||
|
svga->crtc[svga->crtcreg] = val;
|
||||||
|
switch (svga->crtcreg)
|
||||||
{
|
{
|
||||||
case 0x31:
|
case 0x31:
|
||||||
s3_ma_ext = (s3_ma_ext & 0x1c) | ((val & 0x30) >> 4);
|
virge->ma_ext = (virge->ma_ext & 0x1c) | ((val & 0x30) >> 4);
|
||||||
vrammask = (val & 8) ? 0x3fffff : 0x3ffff;
|
svga->vrammask = (val & 8) ? 0x3fffff : 0x3ffff;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x50:
|
case 0x50:
|
||||||
switch (crtc[0x50] & 0xc1)
|
switch (svga->crtc[0x50] & 0xc1)
|
||||||
{
|
{
|
||||||
case 0x00: s3_width = (crtc[0x31] & 2) ? 2048 : 1024; break;
|
case 0x00: virge->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; break;
|
||||||
case 0x01: s3_width = 1152; break;
|
case 0x01: virge->width = 1152; break;
|
||||||
case 0x40: s3_width = 640; break;
|
case 0x40: virge->width = 640; break;
|
||||||
case 0x80: s3_width = 800; break;
|
case 0x80: virge->width = 800; break;
|
||||||
case 0x81: s3_width = 1600; break;
|
case 0x81: virge->width = 1600; break;
|
||||||
case 0xc0: s3_width = 1280; break;
|
case 0xc0: virge->width = 1280; break;
|
||||||
}
|
}
|
||||||
s3_bpp = (crtc[0x50] >> 4) & 3;
|
virge->bpp = (svga->crtc[0x50] >> 4) & 3;
|
||||||
break;
|
break;
|
||||||
case 0x69:
|
case 0x69:
|
||||||
s3_ma_ext = val & 0x1f;
|
virge->ma_ext = val & 0x1f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x35:
|
case 0x35:
|
||||||
s3_bank = (s3_bank & 0x70) | (val & 0xf);
|
virge->bank = (virge->bank & 0x70) | (val & 0xf);
|
||||||
// pclog("CRTC write R35 %02X\n", val);
|
// pclog("CRTC write R35 %02X\n", val);
|
||||||
if (chain4) svgawbank = svgarbank = s3_bank << 16;
|
if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16;
|
||||||
else svgawbank = svgarbank = s3_bank << 14;
|
else svga->write_bank = svga->read_bank = virge->bank << 14;
|
||||||
break;
|
break;
|
||||||
case 0x51:
|
case 0x51:
|
||||||
s3_bank = (s3_bank & 0x4f) | ((val & 0xc) << 2);
|
virge->bank = (virge->bank & 0x4f) | ((val & 0xc) << 2);
|
||||||
if (chain4) svgawbank = svgarbank = s3_bank << 16;
|
if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16;
|
||||||
else svgawbank = svgarbank = s3_bank << 14;
|
else svga->write_bank = svga->read_bank = virge->bank << 14;
|
||||||
s3_ma_ext = (s3_ma_ext & ~0xc) | ((val & 3) << 2);
|
virge->ma_ext = (virge->ma_ext & ~0xc) | ((val & 3) << 2);
|
||||||
break;
|
break;
|
||||||
case 0x6a:
|
case 0x6a:
|
||||||
s3_bank = val;
|
virge->bank = val;
|
||||||
// pclog("CRTC write R6a %02X\n", val);
|
// pclog("CRTC write R6a %02X\n", val);
|
||||||
if (chain4) svgawbank = svgarbank = s3_bank << 16;
|
if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16;
|
||||||
else svgawbank = svgarbank = s3_bank << 14;
|
else svga->write_bank = svga->read_bank = virge->bank << 14;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3a:
|
case 0x3a:
|
||||||
if (val & 0x10) gdcreg[5] |= 0x40; /*Horrible cheat*/
|
if (val & 0x10) svga->gdcreg[5] |= 0x40; /*Horrible cheat*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x45:
|
case 0x45:
|
||||||
svga_hwcursor.ena = val & 1;
|
svga->hwcursor.ena = val & 1;
|
||||||
break;
|
break;
|
||||||
case 0x48:
|
case 0x48:
|
||||||
svga_hwcursor.x = ((crtc[0x46] << 8) | crtc[0x47]) & 0x7ff;
|
svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff;
|
||||||
if (bpp == 32) svga_hwcursor.x >>= 1;
|
if (svga->bpp == 32) svga->hwcursor.x >>= 1;
|
||||||
svga_hwcursor.y = ((crtc[0x48] << 8) | crtc[0x49]) & 0x7ff;
|
svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff;
|
||||||
svga_hwcursor.xoff = crtc[0x4e] & 63;
|
svga->hwcursor.xoff = svga->crtc[0x4e] & 63;
|
||||||
svga_hwcursor.yoff = crtc[0x4f] & 63;
|
svga->hwcursor.yoff = svga->crtc[0x4f] & 63;
|
||||||
svga_hwcursor.addr = ((((crtc[0x4c] << 8) | crtc[0x4d]) & 0xfff) * 1024) + (svga_hwcursor.yoff * 16);
|
svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x53:
|
case 0x53:
|
||||||
case 0x58: case 0x59: case 0x5a:
|
case 0x58: case 0x59: case 0x5a:
|
||||||
s3_virge_updatemapping();
|
s3_virge_updatemapping(virge);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x67:
|
case 0x67:
|
||||||
switch (val >> 4)
|
switch (val >> 4)
|
||||||
{
|
{
|
||||||
case 3: bpp = 15; break;
|
case 3: svga->bpp = 15; break;
|
||||||
case 5: bpp = 16; break;
|
case 5: svga->bpp = 16; break;
|
||||||
case 7: bpp = 24; break;
|
case 7: svga->bpp = 24; break;
|
||||||
case 13: bpp = 32; break;
|
case 13: svga->bpp = 32; break;
|
||||||
default: bpp = 8; break;
|
default: svga->bpp = 8; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
//case 0x55: case 0x43:
|
//case 0x55: case 0x43:
|
||||||
|
|
@ -141,20 +158,24 @@ void s3_virge_out(uint16_t addr, uint8_t val, void *priv)
|
||||||
}
|
}
|
||||||
if (old != val)
|
if (old != val)
|
||||||
{
|
{
|
||||||
if (crtcreg<0xE || crtcreg>0x10)
|
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
|
||||||
{
|
{
|
||||||
fullchange = changeframecount;
|
fullchange = changeframecount;
|
||||||
svga_recalctimings();
|
svga_recalctimings(svga);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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);
|
if (addr != 0x3da) pclog("S3 in %04X %04X:%08X\n", addr, CS, pc);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
|
|
@ -164,221 +185,221 @@ uint8_t s3_virge_in(uint16_t addr, void *priv)
|
||||||
//return sdac_ramdac_in(addr);
|
//return sdac_ramdac_in(addr);
|
||||||
|
|
||||||
case 0x3c5:
|
case 0x3c5:
|
||||||
if (seqaddr >= 0x10)
|
if (svga->seqaddr >= 0x10)
|
||||||
return seqregs[seqaddr&0x1F];
|
return svga->seqregs[svga->seqaddr & 0x1f];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
return crtcreg;
|
return svga->crtcreg;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
// pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc);
|
// 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 0x2d: return virge->virge_id_high; /*Extended chip ID*/
|
||||||
case 0x2e: return s3_virge_id_low; /*New chip ID*/
|
case 0x2e: return virge->virge_id_low; /*New chip ID*/
|
||||||
case 0x2f: return s3_virge_rev;
|
case 0x2f: return virge->virge_rev;
|
||||||
case 0x30: return s3_virge_id; /*Chip ID*/
|
case 0x30: return virge->virge_id; /*Chip ID*/
|
||||||
case 0x31: return (crtc[0x31] & 0xcf) | ((s3_ma_ext & 3) << 4);
|
case 0x31: return (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4);
|
||||||
case 0x35: return (crtc[0x35] & 0xf0) | (s3_bank & 0xf);
|
case 0x35: return (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf);
|
||||||
case 0x51: return (crtc[0x51] & 0xf0) | ((s3_bank >> 2) & 0xc) | ((s3_ma_ext >> 2) & 3);
|
case 0x51: return (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3);
|
||||||
case 0x69: return s3_ma_ext;
|
case 0x69: return virge->ma_ext;
|
||||||
case 0x6a: return s3_bank;
|
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");
|
// pclog("recalctimings\n");
|
||||||
svga_ma |= (s3_ma_ext << 16);
|
svga->ma_latch |= (virge->ma_ext << 16);
|
||||||
// pclog("SVGA_MA %08X\n", svga_ma);
|
// pclog("SVGA_MA %08X\n", svga_ma);
|
||||||
// if (gdcreg[5] & 0x40) svga_lowres = !(crtc[0x3a] & 0x10);
|
// 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:
|
case 8:
|
||||||
svga_render = svga_render_8bpp_highres;
|
svga->render = svga_render_8bpp_highres;
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
svga_render = svga_render_15bpp_highres;
|
svga->render = svga_render_15bpp_highres;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
svga_render = svga_render_16bpp_highres;
|
svga->render = svga_render_16bpp_highres;
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
svga_render = svga_render_24bpp_highres;
|
svga->render = svga_render_24bpp_highres;
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
svga_render = svga_render_32bpp_highres;
|
svga->render = svga_render_32bpp_highres;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crtc[0x5d] & 0x01) svga_htotal += 0x100;
|
if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100;
|
||||||
if (crtc[0x5d] & 0x02) svga_hdisp += 0x100;
|
if (svga->crtc[0x5d] & 0x02) svga->hdisp += 0x100;
|
||||||
if (crtc[0x5e] & 0x01) svga_vtotal += 0x400;
|
if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400;
|
||||||
if (crtc[0x5e] & 0x02) svga_dispend += 0x400;
|
if (svga->crtc[0x5e] & 0x02) svga->dispend += 0x400;
|
||||||
if (crtc[0x5e] & 0x10) svga_vsyncstart += 0x400;
|
if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400;
|
||||||
if (crtc[0x5e] & 0x40) svga_split += 0x400;
|
if (svga->crtc[0x5e] & 0x40) svga->split += 0x400;
|
||||||
if (crtc[0x51] & 0x30) svga_rowoffset += (crtc[0x51] & 0x30) << 4;
|
if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4;
|
||||||
else if (crtc[0x43] & 0x04) svga_rowoffset += 0x100;
|
else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
|
||||||
if (!svga_rowoffset) svga_rowoffset = 256;
|
if (!svga->rowoffset) svga->rowoffset = 256;
|
||||||
svga_interlace = crtc[0x42] & 0x20;
|
svga->interlace = svga->crtc[0x42] & 0x20;
|
||||||
if (bpp == 32)
|
if (svga->bpp == 32)
|
||||||
{
|
{
|
||||||
svga_htotal <<= 2;
|
svga->htotal <<= 2;
|
||||||
svga_hdisp <<= 2;
|
svga->hdisp <<= 2;
|
||||||
}
|
}
|
||||||
//svga_clock = cpuclock / sdac_getclock((svga_miscout >> 2) & 3);
|
//svga_clock = cpuclock / sdac_getclock((svga_miscout >> 2) & 3);
|
||||||
// pclog("SVGA_CLOCK = %f %02X %f\n", svga_clock, svga_miscout, cpuclock);
|
// pclog("SVGA_CLOCK = %f %02X %f\n", svga_clock, svga_miscout, cpuclock);
|
||||||
//if (bpp > 8) svga_clock /= 2;
|
//if (bpp > 8) svga_clock /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t s3_linear_base = 0, s3_linear_size = 0;
|
void s3_virge_updatemapping(virge_t *virge)
|
||||||
void s3_virge_updatemapping()
|
|
||||||
{
|
{
|
||||||
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;
|
// 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, 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, 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, virge);
|
||||||
pclog("Update mapping - bank %02X ", gdcreg[6] & 0xc);
|
pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc);
|
||||||
switch (gdcreg[6] & 0xc) /*Banked framebuffer*/
|
switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/
|
||||||
{
|
{
|
||||||
case 0x0: /*128k at A0000*/
|
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;
|
break;
|
||||||
case 0x4: /*64k at A0000*/
|
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;
|
break;
|
||||||
case 0x8: /*32k at B0000*/
|
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;
|
break;
|
||||||
case 0xC: /*32k at B8000*/
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pclog("Linear framebuffer %02X ", crtc[0x58] & 0x10);
|
pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10);
|
||||||
if (crtc[0x58] & 0x10) /*Linear framebuffer*/
|
if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/
|
||||||
{
|
{
|
||||||
s3_linear_base = (crtc[0x5a] << 16) | (crtc[0x59] << 24);
|
virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
|
||||||
switch (crtc[0x58] & 3)
|
switch (svga->crtc[0x58] & 3)
|
||||||
{
|
{
|
||||||
case 0: /*64k*/
|
case 0: /*64k*/
|
||||||
s3_linear_size = 0x10000;
|
virge->linear_size = 0x10000;
|
||||||
break;
|
break;
|
||||||
case 1: /*1mb*/
|
case 1: /*1mb*/
|
||||||
s3_linear_size = 0x100000;
|
virge->linear_size = 0x100000;
|
||||||
break;
|
break;
|
||||||
case 2: /*2mb*/
|
case 2: /*2mb*/
|
||||||
s3_linear_size = 0x200000;
|
virge->linear_size = 0x200000;
|
||||||
break;
|
break;
|
||||||
case 3: /*8mb*/
|
case 3: /*8mb*/
|
||||||
s3_linear_size = 0x400000;
|
virge->linear_size = 0x400000;
|
||||||
break;
|
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("%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);
|
pclog("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size);
|
||||||
if (s3_linear_base == 0xa0000)
|
if (virge->linear_base == 0xa0000)
|
||||||
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);
|
||||||
else
|
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);
|
pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18);
|
||||||
output = 0;
|
if ((svga->crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/
|
||||||
if ((crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/
|
|
||||||
{
|
{
|
||||||
output = 3;
|
if (svga->crtc[0x53] & 0x20)
|
||||||
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, virge);
|
||||||
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);
|
|
||||||
else
|
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);
|
pclog("MMIO readb %08X\n", addr);
|
||||||
return 0xff;
|
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);
|
pclog("MMIO readw %08X\n", addr);
|
||||||
return 0xffff;
|
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);
|
pclog("MMIO readl %08X\n", addr);
|
||||||
return 0xffffffff;
|
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);
|
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);
|
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);
|
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;
|
int x;
|
||||||
uint16_t dat[2];
|
uint16_t dat[2];
|
||||||
int xx;
|
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)
|
for (x = 0; x < 64; x += 16)
|
||||||
{
|
{
|
||||||
dat[0] = (vram[svga_hwcursor_latch.addr] << 8) | vram[svga_hwcursor_latch.addr + 1];
|
dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1];
|
||||||
dat[1] = (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3];
|
dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
|
||||||
for (xx = 0; xx < 16; xx++)
|
for (xx = 0; xx < 16; xx++)
|
||||||
{
|
{
|
||||||
if (offset >= svga_hwcursor_latch.x)
|
if (offset >= svga->hwcursor_latch.x)
|
||||||
{
|
{
|
||||||
if (!(dat[0] & 0x8000))
|
if (!(dat[0] & 0x8000))
|
||||||
((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? 0xffffff : 0;
|
((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? 0xffffff : 0;
|
||||||
else if (dat[1] & 0x8000)
|
else if (dat[1] & 0x8000)
|
||||||
((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff;
|
((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++;
|
offset++;
|
||||||
dat[0] <<= 1;
|
dat[0] <<= 1;
|
||||||
dat[1] <<= 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 *p)
|
||||||
|
|
||||||
uint8_t s3_virge_pci_read(int func, int addr, void *priv)
|
|
||||||
{
|
{
|
||||||
|
virge_t *virge = (virge_t *)p;
|
||||||
|
svga_t *svga = &virge->svga;
|
||||||
// pclog("S3 PCI read %08X\n", addr);
|
// pclog("S3 PCI read %08X\n", addr);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x00: return 0x33; /*'S3'*/
|
case 0x00: return 0x33; /*'S3'*/
|
||||||
case 0x01: return 0x53;
|
case 0x01: return 0x53;
|
||||||
|
|
||||||
case 0x02: return s3_virge_id_low;
|
case 0x02: return virge->virge_id_low;
|
||||||
case 0x03: return s3_virge_id_high;
|
case 0x03: return virge->virge_id_high;
|
||||||
|
|
||||||
case 0x08: return 0; /*Revision ID*/
|
case 0x08: return 0; /*Revision ID*/
|
||||||
case 0x09: return 0; /*Programming interface*/
|
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 0x10: return 0x00; /*Linear frame buffer address*/
|
||||||
case 0x11: return 0x00;
|
case 0x11: return 0x00;
|
||||||
case 0x12: 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 0x30: return 0x01; /*BIOS ROM address*/
|
||||||
case 0x31: return 0x00;
|
case 0x31: return 0x00;
|
||||||
|
|
@ -397,11 +418,14 @@ uint8_t s3_virge_pci_read(int func, int addr, void *priv)
|
||||||
case 0x33: return 0x00;
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
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:
|
case 0x3d: case 0x3e: case 0x3f:
|
||||||
break;
|
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;
|
virge_t *virge = malloc(sizeof(virge_t));
|
||||||
s3_virge_pci_regs[5] = 0;
|
memset(virge, 0, sizeof(virge_t));
|
||||||
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;
|
|
||||||
|
|
||||||
s3_virge_id_high = 0x56;
|
svga_init(&virge->svga, virge, 1 << 22, /*4mb*/
|
||||||
s3_virge_id_low = 0x31;
|
s3_virge_recalctimings,
|
||||||
s3_virge_rev = 0;
|
s3_virge_in, s3_virge_out,
|
||||||
s3_virge_id = 0xe1;
|
s3_virge_hwcursor_draw);
|
||||||
|
|
||||||
svga_recalctimings_ex = s3_virge_recalctimings;
|
io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge);
|
||||||
svga_hwcursor_draw = s3_virge_hwcursor_draw;
|
|
||||||
|
|
||||||
crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
|
virge->pci_regs[4] = 3;
|
||||||
crtc[0x37] = 1 | (7 << 5);
|
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;
|
||||||
|
|
||||||
vrammask = 0x3fffff;
|
virge->virge_id_high = 0x56;
|
||||||
|
virge->virge_id_low = 0x31;
|
||||||
|
virge->virge_rev = 0;
|
||||||
|
virge->virge_id = 0xe1;
|
||||||
|
|
||||||
pci_add(s3_virge_pci_read, s3_virge_pci_write, NULL);
|
virge->svga.crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
|
||||||
|
virge->svga.crtc[0x37] = 1 | (7 << 5);
|
||||||
|
|
||||||
svga_vram_limit = 4 << 20; /*4mb*/
|
pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
|
||||||
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,
|
s3_virge_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
s3_virge_close,
|
||||||
s3_virge_out,
|
s3_virge_speed_changed,
|
||||||
s3_virge_in,
|
svga_add_status_info
|
||||||
/*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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
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_svga.h"
|
||||||
#include "vid_sdac_ramdac.h"
|
#include "vid_sdac_ramdac.h"
|
||||||
|
|
||||||
struct
|
void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
// /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i\n",addr,val,sdac_ramdac.magic_count,CS,pc, sdac_ramdac.rs2);
|
// /*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)
|
switch (addr)
|
||||||
|
|
@ -23,125 +13,125 @@ void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
||||||
case 0x3C6:
|
case 0x3C6:
|
||||||
if (val == 0xff)
|
if (val == 0xff)
|
||||||
{
|
{
|
||||||
sdac_ramdac.rs2 = 0;
|
ramdac->rs2 = 0;
|
||||||
sdac_ramdac.magic_count = 0;
|
ramdac->magic_count = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sdac_ramdac.magic_count < 4) break;
|
if (ramdac->magic_count < 4) break;
|
||||||
if (sdac_ramdac.magic_count == 4)
|
if (ramdac->magic_count == 4)
|
||||||
{
|
{
|
||||||
sdac_ramdac.command = val;
|
ramdac->command = val;
|
||||||
// pclog("RAMDAC command reg now %02X\n", val);
|
// pclog("RAMDAC command reg now %02X\n", val);
|
||||||
switch (val >> 4)
|
switch (val >> 4)
|
||||||
{
|
{
|
||||||
case 2: case 3: case 0xa: bpp = 15; break;
|
case 0x2: case 0x3: case 0xa: svga->bpp = 15; break;
|
||||||
case 4: case 0xe: bpp = 24; break;
|
case 0x4: case 0xe: svga->bpp = 24; break;
|
||||||
case 5: case 6: case 0xc: bpp = 16; break;
|
case 0x5: case 0x6: case 0xc: svga->bpp = 16; break;
|
||||||
case 7: bpp = 32; 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;
|
break;
|
||||||
|
|
||||||
case 0x3C7:
|
case 0x3C7:
|
||||||
sdac_ramdac.magic_count = 0;
|
ramdac->magic_count = 0;
|
||||||
if (sdac_ramdac.rs2)
|
if (ramdac->rs2)
|
||||||
sdac_ramdac.rindex = val;
|
ramdac->rindex = val;
|
||||||
break;
|
break;
|
||||||
case 0x3C8:
|
case 0x3C8:
|
||||||
sdac_ramdac.magic_count = 0;
|
ramdac->magic_count = 0;
|
||||||
if (sdac_ramdac.rs2)
|
if (ramdac->rs2)
|
||||||
sdac_ramdac.windex = val;
|
ramdac->windex = val;
|
||||||
break;
|
break;
|
||||||
case 0x3C9:
|
case 0x3C9:
|
||||||
sdac_ramdac.magic_count = 0;
|
ramdac->magic_count = 0;
|
||||||
if (sdac_ramdac.rs2)
|
if (ramdac->rs2)
|
||||||
{
|
{
|
||||||
if (!sdac_ramdac.reg_ff) sdac_ramdac.regs[sdac_ramdac.windex] = (sdac_ramdac.regs[sdac_ramdac.windex] & 0xff00) | val;
|
if (!ramdac->reg_ff) ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0xff00) | val;
|
||||||
else sdac_ramdac.regs[sdac_ramdac.windex] = (sdac_ramdac.regs[sdac_ramdac.windex] & 0x00ff) | (val << 8);
|
else ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0x00ff) | (val << 8);
|
||||||
sdac_ramdac.reg_ff = !sdac_ramdac.reg_ff;
|
ramdac->reg_ff = !ramdac->reg_ff;
|
||||||
// pclog("RAMDAC reg %02X now %04X\n", sdac_ramdac.windex, sdac_ramdac.regs[sdac_ramdac.windex]);
|
// pclog("RAMDAC reg %02X now %04X\n", ramdac->windex, ramdac->regs[ramdac->windex]);
|
||||||
if (!sdac_ramdac.reg_ff) sdac_ramdac.windex++;
|
if (!ramdac->reg_ff) ramdac->windex++;
|
||||||
}
|
}
|
||||||
break;
|
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;
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3C6:
|
case 0x3C6:
|
||||||
sdac_ramdac.reg_ff = 0;
|
ramdac->reg_ff = 0;
|
||||||
if (sdac_ramdac.magic_count < 5)
|
if (ramdac->magic_count < 5)
|
||||||
sdac_ramdac.magic_count++;
|
ramdac->magic_count++;
|
||||||
if (sdac_ramdac.magic_count == 4)
|
if (ramdac->magic_count == 4)
|
||||||
{
|
{
|
||||||
temp = 0x70; /*SDAC ID*/
|
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;
|
temp = ramdac->command;
|
||||||
sdac_ramdac.magic_count = 0;
|
ramdac->magic_count = 0;
|
||||||
}
|
}
|
||||||
return temp;
|
return temp;
|
||||||
case 0x3C7:
|
case 0x3C7:
|
||||||
// if (sdac_ramdac.magic_count < 4)
|
// if (ramdac->magic_count < 4)
|
||||||
// {
|
// {
|
||||||
sdac_ramdac.magic_count=0;
|
ramdac->magic_count=0;
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
if (sdac_ramdac.rs2) return sdac_ramdac.rindex;
|
if (ramdac->rs2) return ramdac->rindex;
|
||||||
break;
|
break;
|
||||||
case 0x3C8:
|
case 0x3C8:
|
||||||
// if (sdac_ramdac.magic_count < 4)
|
// if (ramdac->magic_count < 4)
|
||||||
// {
|
// {
|
||||||
sdac_ramdac.magic_count=0;
|
ramdac->magic_count=0;
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
if (sdac_ramdac.rs2) return sdac_ramdac.windex;
|
if (ramdac->rs2) return ramdac->windex;
|
||||||
break;
|
break;
|
||||||
case 0x3C9:
|
case 0x3C9:
|
||||||
// if (sdac_ramdac.magic_count < 4)
|
// if (ramdac->magic_count < 4)
|
||||||
// {
|
// {
|
||||||
sdac_ramdac.magic_count=0;
|
ramdac->magic_count=0;
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
if (sdac_ramdac.rs2)
|
if (ramdac->rs2)
|
||||||
{
|
{
|
||||||
if (!sdac_ramdac.reg_ff) temp = sdac_ramdac.regs[sdac_ramdac.rindex] & 0xff;
|
if (!ramdac->reg_ff) temp = ramdac->regs[ramdac->rindex] & 0xff;
|
||||||
else temp = sdac_ramdac.regs[sdac_ramdac.rindex] >> 8;
|
else temp = ramdac->regs[ramdac->rindex] >> 8;
|
||||||
sdac_ramdac.reg_ff = !sdac_ramdac.reg_ff;
|
ramdac->reg_ff = !ramdac->reg_ff;
|
||||||
if (!sdac_ramdac.reg_ff)
|
if (!ramdac->reg_ff)
|
||||||
{
|
{
|
||||||
sdac_ramdac.rindex++;
|
ramdac->rindex++;
|
||||||
sdac_ramdac.magic_count = 0;
|
ramdac->magic_count = 0;
|
||||||
}
|
}
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
break;
|
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;
|
float t;
|
||||||
int m, n1, n2;
|
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 == 0) return 25175000.0;
|
||||||
if (clock == 1) return 28322000.0;
|
if (clock == 1) return 28322000.0;
|
||||||
clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/
|
clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/
|
||||||
m = (sdac_ramdac.regs[clock] & 0x7f) + 2;
|
m = (ramdac->regs[clock] & 0x7f) + 2;
|
||||||
n1 = ((sdac_ramdac.regs[clock] >> 8) & 0x1f) + 2;
|
n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2;
|
||||||
n2 = ((sdac_ramdac.regs[clock] >> 13) & 0x07);
|
n2 = ((ramdac->regs[clock] >> 13) & 0x07);
|
||||||
t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2);
|
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;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,14 @@
|
||||||
void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv);
|
typedef struct sdac_ramdac_t
|
||||||
uint8_t sdac_ramdac_in(uint16_t addr, void *priv);
|
{
|
||||||
|
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_svga.h"
|
||||||
#include "vid_stg_ramdac.h"
|
#include "vid_stg_ramdac.h"
|
||||||
|
|
||||||
struct
|
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 magic_count;
|
|
||||||
uint8_t command;
|
|
||||||
int index;
|
|
||||||
uint8_t regs[256];
|
|
||||||
} stg_ramdac;
|
|
||||||
|
|
||||||
int stg_state_read[2][8]={{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}};
|
void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
int didwrite;
|
int didwrite;
|
||||||
//if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc);
|
//if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3C6:
|
case 0x3c6:
|
||||||
switch (stg_ramdac.magic_count)
|
switch (ramdac->magic_count)
|
||||||
{
|
{
|
||||||
case 0: case 1: case 2: case 3: break;
|
case 0: case 1: case 2: case 3:
|
||||||
case 4: stg_ramdac.command=val; /*pclog("Write RAMDAC command %02X\n",val);*/ break;
|
break;
|
||||||
case 5: stg_ramdac.index=(stg_ramdac.index&0xFF00)|val; break;
|
case 4:
|
||||||
case 6: stg_ramdac.index=(stg_ramdac.index&0xFF)|(val<<8); break;
|
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:
|
case 7:
|
||||||
pclog("Write RAMDAC reg %02X %02X\n", stg_ramdac.index, val);
|
pclog("Write RAMDAC reg %02X %02X\n", ramdac->index, val);
|
||||||
if (stg_ramdac.index<0x100) stg_ramdac.regs[stg_ramdac.index]=val;
|
if (ramdac->index < 0x100)
|
||||||
stg_ramdac.index++;
|
ramdac->regs[ramdac->index] = val;
|
||||||
|
ramdac->index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
didwrite = (stg_ramdac.magic_count>=4);
|
didwrite = (ramdac->magic_count >= 4);
|
||||||
stg_ramdac.magic_count=stg_state_write[stg_ramdac.magic_count&7];
|
ramdac->magic_count = stg_state_write[ramdac->magic_count & 7];
|
||||||
if (stg_ramdac.command&8)
|
if (ramdac->command & 8)
|
||||||
{
|
{
|
||||||
switch (stg_ramdac.regs[3])
|
switch (ramdac->regs[3])
|
||||||
{
|
{
|
||||||
case 0: case 5: case 7: bpp=8; break;
|
case 0: case 5: case 7: svga->bpp = 8; break;
|
||||||
case 1: case 2: case 8: bpp=15; break;
|
case 1: case 2: case 8: svga->bpp = 15; break;
|
||||||
case 3: case 6: bpp=16; break;
|
case 3: case 6: svga->bpp = 16; break;
|
||||||
case 4: case 9: bpp=24; break;
|
case 4: case 9: svga->bpp = 24; break;
|
||||||
default: bpp=8; break;
|
default: svga->bpp = 8; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (stg_ramdac.command>>5)
|
switch (ramdac->command >> 5)
|
||||||
{
|
{
|
||||||
case 0: bpp=8; break;
|
case 0: svga->bpp = 8; break;
|
||||||
case 5: bpp=15; break;
|
case 5: svga->bpp = 15; break;
|
||||||
case 6: bpp=16; break;
|
case 6: svga->bpp = 16; break;
|
||||||
case 7: bpp=24; break;
|
case 7: svga->bpp = 24; break;
|
||||||
default: bpp=8; break;
|
default: svga->bpp = 8; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (didwrite) return;
|
if (didwrite) return;
|
||||||
break;
|
break;
|
||||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
case 0x3c7: case 0x3c8: case 0x3c9:
|
||||||
stg_ramdac.magic_count=0;
|
ramdac->magic_count=0;
|
||||||
break;
|
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;
|
uint8_t temp;
|
||||||
//if (CS!=0xC000) pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc);
|
//if (CS!=0xC000) pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3C6:
|
case 0x3c6:
|
||||||
switch (stg_ramdac.magic_count)
|
switch (ramdac->magic_count)
|
||||||
{
|
{
|
||||||
case 0: case 1: case 2: case 3: temp=0xFF; break;
|
case 0: case 1: case 2: case 3:
|
||||||
case 4: temp=stg_ramdac.command; break;
|
temp = 0xff;
|
||||||
case 5: temp=stg_ramdac.index&0xFF; break;
|
break;
|
||||||
case 6: temp=stg_ramdac.index>>8; break;
|
case 4:
|
||||||
|
temp = ramdac->command;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
temp = ramdac->index & 0xff;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
temp = ramdac->index >> 8;
|
||||||
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
// pclog("Read RAMDAC index %04X\n",stg_ramdac.index);
|
// pclog("Read RAMDAC index %04X\n",stg_ramdac.index);
|
||||||
switch (stg_ramdac.index)
|
switch (ramdac->index)
|
||||||
{
|
{
|
||||||
case 0: temp=0x44; break;
|
case 0:
|
||||||
case 1: temp=0x02; break;
|
temp = 0x44;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
temp = 0x02;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (stg_ramdac.index<0x100) temp=stg_ramdac.regs[stg_ramdac.index];
|
if (ramdac->index < 0x100) temp = ramdac->regs[ramdac->index];
|
||||||
else temp=0xFF;
|
else temp = 0xff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
stg_ramdac.index++;
|
ramdac->index++;
|
||||||
break;
|
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;
|
return temp;
|
||||||
case 0x3C8: case 0x3C9:
|
case 0x3c8: case 0x3c9:
|
||||||
stg_ramdac.magic_count=0;
|
ramdac->magic_count=0;
|
||||||
break;
|
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);
|
typedef struct stg_ramdac_t
|
||||||
uint8_t stg_ramdac_in(uint16_t addr, void *priv);
|
{
|
||||||
|
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);
|
||||||
|
|
|
||||||
1332
src/vid_svga.c
1332
src/vid_svga.c
File diff suppressed because it is too large
Load diff
143
src/vid_svga.h
143
src/vid_svga.h
|
|
@ -1,60 +1,123 @@
|
||||||
/*Vertical timings*/
|
typedef struct svga_t
|
||||||
extern int svga_vtotal, svga_dispend, svga_vsyncstart, svga_split;
|
{
|
||||||
/*Horizontal timings*/
|
uint8_t crtcreg;
|
||||||
extern int svga_hdisp, svga_htotal, svga_hdisp_time, svga_rowoffset;
|
uint8_t crtc[128];
|
||||||
/*Flags - svga_lowres = 1/2 clock in 256+ colour modes, svga_interlace = interlace mode enabled*/
|
uint8_t gdcreg[16];
|
||||||
extern int svga_lowres, svga_interlace;
|
int gdcaddr;
|
||||||
|
uint8_t attrregs[32];
|
||||||
|
int attraddr, attrff;
|
||||||
|
uint8_t seqregs[64];
|
||||||
|
int seqaddr;
|
||||||
|
|
||||||
extern int svga_linedbl, svga_rowcount;
|
uint8_t miscout;
|
||||||
|
int vidclock;
|
||||||
|
|
||||||
/*Status of display on*/
|
uint32_t vram_limit;
|
||||||
extern int svga_hdisp_on;
|
|
||||||
|
|
||||||
extern double svga_clock;
|
uint8_t la, lb, lc, ld;
|
||||||
extern uint32_t svga_ma;
|
|
||||||
extern void (*svga_recalctimings_ex)();
|
|
||||||
|
|
||||||
extern uint8_t svga_miscout;
|
uint8_t dac_mask, dac_status;
|
||||||
|
int dac_read, dac_write, dac_pos;
|
||||||
|
|
||||||
extern int svga_init();
|
uint8_t cgastat;
|
||||||
extern void svga_poll();
|
|
||||||
extern void svga_recalctimings();
|
|
||||||
|
|
||||||
typedef struct
|
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 ena;
|
||||||
int x, y;
|
int x, y;
|
||||||
int xoff, yoff;
|
int xoff, yoff;
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
} SVGA_HWCURSOR;
|
} 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 int svga_hwcursor_on;
|
||||||
extern void (*svga_hwcursor_draw)(int displine);
|
extern void (*svga_hwcursor_draw)(int displine);
|
||||||
|
|
||||||
uint8_t svga_read(uint32_t addr, void *priv);
|
uint8_t svga_read(uint32_t addr, void *p);
|
||||||
uint16_t svga_readw(uint32_t addr, void *priv);
|
uint16_t svga_readw(uint32_t addr, void *p);
|
||||||
uint32_t svga_readl(uint32_t addr, void *priv);
|
uint32_t svga_readl(uint32_t addr, void *p);
|
||||||
void svga_write(uint32_t addr, uint8_t val, void *priv);
|
void svga_write(uint32_t addr, uint8_t val, void *p);
|
||||||
void svga_writew(uint32_t addr, uint16_t val, void *priv);
|
void svga_writew(uint32_t addr, uint16_t val, void *p);
|
||||||
void svga_writel(uint32_t addr, uint32_t val, void *priv);
|
void svga_writel(uint32_t addr, uint32_t val, void *p);
|
||||||
uint8_t svga_read_linear(uint32_t addr, void *priv);
|
uint8_t svga_read_linear(uint32_t addr, void *p);
|
||||||
uint16_t svga_readw_linear(uint32_t addr, void *priv);
|
uint16_t svga_readw_linear(uint32_t addr, void *p);
|
||||||
uint32_t svga_readl_linear(uint32_t addr, void *priv);
|
uint32_t svga_readl_linear(uint32_t addr, void *p);
|
||||||
void svga_write_linear(uint32_t addr, uint8_t val, void *priv);
|
void svga_write_linear(uint32_t addr, uint8_t val, void *p);
|
||||||
void svga_writew_linear(uint32_t addr, uint16_t val, void *priv);
|
void svga_writew_linear(uint32_t addr, uint16_t val, void *p);
|
||||||
void svga_writel_linear(uint32_t addr, uint32_t val, void *priv);
|
void svga_writel_linear(uint32_t addr, uint32_t val, void *p);
|
||||||
|
|
||||||
void svga_doblit(int y1, int y2);
|
int svga_add_status_info(char *s, int max_len, void *p);
|
||||||
|
|
||||||
extern uint32_t svga_vram_limit;
|
|
||||||
|
|
||||||
extern uint8_t svga_rotate[8][256];
|
extern uint8_t svga_rotate[8][256];
|
||||||
|
|
||||||
void svga_out(uint16_t addr, uint8_t val, void *priv);
|
void svga_out(uint16_t addr, uint8_t val, void *p);
|
||||||
uint8_t svga_in(uint16_t addr, void *priv);
|
uint8_t svga_in(uint16_t addr, void *p);
|
||||||
|
|
|
||||||
|
|
@ -3,36 +3,39 @@
|
||||||
#include "vid_svga.h"
|
#include "vid_svga.h"
|
||||||
#include "vid_svga_render.h"
|
#include "vid_svga_render.h"
|
||||||
|
|
||||||
void svga_render_blank()
|
void svga_render_blank(svga_t *svga)
|
||||||
{
|
{
|
||||||
int x, xx;
|
int x, xx;
|
||||||
|
|
||||||
if (firstline_draw == 2000) firstline_draw = displine;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
svga->firstline_draw = svga->displine;
|
||||||
for (x=0;x<svga_hdisp;x++)
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
for (x = 0; x < svga->hdisp; x++)
|
||||||
{
|
{
|
||||||
switch (seqregs[1]&9)
|
switch (svga->seqregs[1] & 9)
|
||||||
{
|
{
|
||||||
case 0:
|
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;
|
break;
|
||||||
case 1:
|
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;
|
break;
|
||||||
case 8:
|
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;
|
break;
|
||||||
case 9:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_text_40()
|
void svga_render_text_40(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (firstline_draw == 2000) firstline_draw = displine;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
svga->firstline_draw = svga->displine;
|
||||||
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
if (fullchange)
|
if (fullchange)
|
||||||
{
|
{
|
||||||
|
|
@ -41,56 +44,59 @@ void svga_render_text_40()
|
||||||
uint8_t chr, attr, dat;
|
uint8_t chr, attr, dat;
|
||||||
uint32_t charaddr;
|
uint32_t charaddr;
|
||||||
int fg, bg;
|
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);
|
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
||||||
chr=vram[(ma<<1)];
|
chr = svga->vram[(svga->ma << 1) & svga->vrammask];
|
||||||
attr=vram[(ma<<1)+4];
|
attr = svga->vram[((svga->ma << 1) + 4) & svga->vrammask];
|
||||||
if (attr&8) charaddr=charsetb+(chr*128);
|
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
||||||
else charaddr=charseta+(chr*128);
|
else charaddr = svga->charseta + (chr * 128);
|
||||||
|
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
bg=pallook[egapal[attr&15]];
|
bg = svga->pallook[svga->egapal[attr & 15]];
|
||||||
fg=pallook[egapal[attr>>4]];
|
fg = svga->pallook[svga->egapal[attr >> 4]];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fg=pallook[egapal[attr&15]];
|
fg = svga->pallook[svga->egapal[attr & 15]];
|
||||||
bg=pallook[egapal[attr>>4]];
|
bg = svga->pallook[svga->egapal[attr >> 4]];
|
||||||
if (attr&0x80 && attrregs[0x10]&8)
|
if (attr & 0x80 && svga->attrregs[0x10] & 8)
|
||||||
{
|
{
|
||||||
bg=pallook[egapal[(attr>>4)&7]];
|
bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
|
||||||
if (cgablink&16) fg=bg;
|
if (svga->blink & 16)
|
||||||
|
fg = bg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dat=vram[charaddr+(sc<<2)];
|
dat = svga->vram[charaddr + (svga->sc << 2)];
|
||||||
if (seqregs[1]&1)
|
if (svga->seqregs[1] & 1)
|
||||||
{
|
{
|
||||||
for (xx = 0; xx < 8; xx++)
|
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;
|
((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
|
else
|
||||||
{
|
{
|
||||||
for (xx = 0; xx < 8; xx++)
|
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;
|
((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 || !(attrregs[0x10]&4))
|
if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4))
|
||||||
((uint32_t *)buffer32->line[displine])[(x+32+16)&2047]=((uint32_t *)buffer32->line[displine])[(x+32+17)&2047]=bg;
|
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 16) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 17) & 2047] = bg;
|
||||||
else
|
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;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
svga->firstline_draw = svga->displine;
|
||||||
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
if (fullchange)
|
if (fullchange)
|
||||||
{
|
{
|
||||||
|
|
@ -99,388 +105,415 @@ void svga_render_text_80()
|
||||||
uint8_t chr, attr, dat;
|
uint8_t chr, attr, dat;
|
||||||
uint32_t charaddr;
|
uint32_t charaddr;
|
||||||
int fg, bg;
|
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);
|
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
||||||
chr=vram[(ma<<1)];
|
chr = svga->vram[(svga->ma << 1) & svga->vrammask];
|
||||||
attr=vram[(ma<<1)+4];
|
attr = svga->vram[((svga->ma << 1) + 4) & svga->vrammask];
|
||||||
if (attr&8) charaddr=charsetb+(chr*128);
|
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
||||||
else charaddr=charseta+(chr*128);
|
else charaddr = svga->charseta + (chr * 128);
|
||||||
|
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
bg=pallook[egapal[attr&15]];
|
bg = svga->pallook[svga->egapal[attr & 15]];
|
||||||
fg=pallook[egapal[attr>>4]];
|
fg = svga->pallook[svga->egapal[attr >> 4]];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fg=pallook[egapal[attr&15]];
|
fg = svga->pallook[svga->egapal[attr & 15]];
|
||||||
bg=pallook[egapal[attr>>4]];
|
bg = svga->pallook[svga->egapal[attr >> 4]];
|
||||||
if (attr&0x80 && attrregs[0x10]&8)
|
if (attr & 0x80 && svga->attrregs[0x10] & 8)
|
||||||
{
|
{
|
||||||
bg=pallook[egapal[(attr>>4)&7]];
|
bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
|
||||||
if (cgablink&16) fg=bg;
|
if (svga->blink & 16)
|
||||||
|
fg = bg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dat=vram[charaddr+(sc<<2)];
|
dat = svga->vram[charaddr + (svga->sc << 2)];
|
||||||
if (seqregs[1]&1)
|
if (svga->seqregs[1] & 1)
|
||||||
{
|
{
|
||||||
for (xx = 0; xx < 8; xx++)
|
for (xx = 0; xx < 8; xx++)
|
||||||
((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg;
|
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (xx = 0; xx < 8; xx++)
|
for (xx = 0; xx < 8; xx++)
|
||||||
((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg;
|
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
|
||||||
if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4))
|
if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4))
|
||||||
((uint32_t *)buffer32->line[displine])[(x+32+8)&2047]=bg;
|
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 8) & 2047] = bg;
|
||||||
else
|
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;
|
int x, offset;
|
||||||
uint8_t edat[4], dat;
|
uint8_t edat[4], dat;
|
||||||
|
|
||||||
if (firstline_draw == 2000) firstline_draw = displine;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
svga->firstline_draw = svga->displine;
|
||||||
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
offset=((8-scrollcache)<<1)+16;
|
offset = ((8 - svga->scrollcache) << 1) + 16;
|
||||||
for (x = 0; x <= svga_hdisp; x += 16)
|
for (x = 0; x <= svga->hdisp; x += 16)
|
||||||
{
|
{
|
||||||
edat[0]=vram[ma];
|
edat[0] = svga->vram[svga->ma];
|
||||||
edat[1]=vram[ma|0x1];
|
edat[1] = svga->vram[svga->ma | 0x1];
|
||||||
edat[2]=vram[ma|0x2];
|
edat[2] = svga->vram[svga->ma | 0x2];
|
||||||
edat[3]=vram[ma|0x3];
|
edat[3] = svga->vram[svga->ma | 0x3];
|
||||||
ma+=4; ma&=vrammask;
|
svga->ma += 4;
|
||||||
|
svga->ma &= svga->vrammask;
|
||||||
|
|
||||||
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
|
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[svga->displine])[x + 14 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 15 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||||
((uint32_t *)buffer32->line[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[dat>>4]];
|
((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);
|
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[svga->displine])[x + 10 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 11 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||||
((uint32_t *)buffer32->line[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[egapal[dat>>4]];
|
((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);
|
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[svga->displine])[x + 6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||||
((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[dat>>4]];
|
((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);
|
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[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||||
((uint32_t *)buffer32->line[displine])[x+offset]= ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[dat>>4]];
|
((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;
|
int x, offset;
|
||||||
uint8_t edat[4], dat;
|
uint8_t edat[4], dat;
|
||||||
|
|
||||||
if (firstline_draw == 2000) firstline_draw = displine;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
svga->firstline_draw = svga->displine;
|
||||||
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
offset=(8-scrollcache)+24;
|
offset = (8 - svga->scrollcache) + 24;
|
||||||
for (x = 0; x <= svga_hdisp; x += 8)
|
for (x = 0; x <= svga->hdisp; x += 8)
|
||||||
{
|
{
|
||||||
edat[0]=vram[ma];
|
edat[0] = svga->vram[svga->ma];
|
||||||
edat[1]=vram[ma|0x1];
|
edat[1] = svga->vram[svga->ma | 0x1];
|
||||||
edat[2]=vram[ma|0x2];
|
edat[2] = svga->vram[svga->ma | 0x2];
|
||||||
edat[3]=vram[ma|0x3];
|
edat[3] = svga->vram[svga->ma | 0x3];
|
||||||
ma+=4; ma&=vrammask;
|
svga->ma += 4;
|
||||||
|
svga->ma &= svga->vrammask;
|
||||||
|
|
||||||
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
|
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[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||||
((uint32_t *)buffer32->line[displine])[x+6+offset]=pallook[egapal[dat>>4]];
|
((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);
|
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[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||||
((uint32_t *)buffer32->line[displine])[x+4+offset]=pallook[egapal[dat>>4]];
|
((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);
|
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[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||||
((uint32_t *)buffer32->line[displine])[x+2+offset]=pallook[egapal[dat>>4]];
|
((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);
|
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[svga->displine])[x + 1 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||||
((uint32_t *)buffer32->line[displine])[x+offset]= pallook[egapal[dat>>4]];
|
((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;
|
int x, offset;
|
||||||
uint8_t edat[4], dat;
|
uint8_t edat[2], dat;
|
||||||
|
|
||||||
|
if (svga->firstline_draw == 2000)
|
||||||
|
svga->firstline_draw = svga->displine;
|
||||||
|
svga->lastline_draw = svga->displine;
|
||||||
|
offset = ((8 - svga->scrollcache) << 1) + 16;
|
||||||
|
|
||||||
if (firstline_draw == 2000) firstline_draw = displine;
|
|
||||||
lastline_draw = displine;
|
|
||||||
offset=((8-scrollcache)<<1)+16;
|
|
||||||
/*Low res (320) only, though high res (640) should be possible*/
|
/*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[0] = svga->vram[(svga->ma << 1) + 0x8000];
|
||||||
edat[1]=vram[(ma<<1)+0x8004];
|
edat[1] = svga->vram[(svga->ma << 1) + 0x8004];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
edat[0]=vram[(ma<<1)];
|
edat[0] = svga->vram[(svga->ma << 1)];
|
||||||
edat[1]=vram[(ma<<1)+4];
|
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[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[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[(edat[1]>>2)&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]];
|
||||||
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[(edat[1] >> 4) & 3]];
|
||||||
((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[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[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[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]];
|
||||||
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 + 4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[(edat[0] >> 2) & 3]];
|
||||||
((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[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[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[(edat[0]>>2)&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]];
|
||||||
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]];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_8bpp_lowres()
|
void svga_render_8bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
int x, offset;
|
int x, offset;
|
||||||
uint8_t edat[4];
|
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;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
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[0] = svga->vram[svga->ma];
|
||||||
edat[1]=vram[ma|0x1];
|
edat[1] = svga->vram[svga->ma | 0x1];
|
||||||
edat[2]=vram[ma|0x2];
|
edat[2] = svga->vram[svga->ma | 0x2];
|
||||||
edat[3]=vram[ma|0x3];
|
edat[3] = svga->vram[svga->ma | 0x3];
|
||||||
ma+=4; ma&=vrammask;
|
svga->ma += 4;
|
||||||
((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[edat[3]];
|
svga->ma &= svga->vrammask;
|
||||||
((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[edat[2]];
|
((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[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[edat[1]];
|
((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[displine])[x+offset]= ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[edat[0]];
|
((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;
|
int x, offset;
|
||||||
uint8_t edat[4];
|
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;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
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[0] = svga->vram[svga->ma];
|
||||||
edat[1]=vram[ma|0x1];
|
edat[1] = svga->vram[svga->ma | 0x1];
|
||||||
edat[2]=vram[ma|0x2];
|
edat[2] = svga->vram[svga->ma | 0x2];
|
||||||
edat[3]=vram[ma|0x3];
|
edat[3] = svga->vram[svga->ma | 0x3];
|
||||||
ma+=4; ma&=vrammask;
|
svga->ma += 4;
|
||||||
((uint32_t *)buffer32->line[displine])[x+3+offset] = pallook[edat[3]];
|
svga->ma &= svga->vrammask;
|
||||||
((uint32_t *)buffer32->line[displine])[x+2+offset] = pallook[edat[2]];
|
((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[edat[3]];
|
||||||
((uint32_t *)buffer32->line[displine])[x+1+offset] = pallook[edat[1]];
|
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = svga->pallook[edat[2]];
|
||||||
((uint32_t *)buffer32->line[displine])[x+offset] = pallook[edat[0]];
|
((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[edat[1]];
|
||||||
edat[0]=vram[ma];
|
((uint32_t *)buffer32->line[svga->displine])[x + offset] = svga->pallook[edat[0]];
|
||||||
edat[1]=vram[ma|0x1];
|
|
||||||
edat[2]=vram[ma|0x2];
|
edat[0] = svga->vram[svga->ma];
|
||||||
edat[3]=vram[ma|0x3];
|
edat[1] = svga->vram[svga->ma | 0x1];
|
||||||
ma+=4; ma&=vrammask;
|
edat[2] = svga->vram[svga->ma | 0x2];
|
||||||
((uint32_t *)buffer32->line[displine])[x+7+offset] = pallook[edat[3]];
|
edat[3] = svga->vram[svga->ma | 0x3];
|
||||||
((uint32_t *)buffer32->line[displine])[x+6+offset] = pallook[edat[2]];
|
svga->ma += 4;
|
||||||
((uint32_t *)buffer32->line[displine])[x+5+offset] = pallook[edat[1]];
|
svga->ma &= svga->vrammask;
|
||||||
((uint32_t *)buffer32->line[displine])[x+4+offset] = pallook[edat[0]];
|
((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;
|
int x, offset;
|
||||||
uint16_t fg, bg;
|
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;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
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);
|
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
|
||||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
|
||||||
ma+=4; ma&=vrammask;
|
svga->ma += 4;
|
||||||
((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);
|
svga->ma &= svga->vrammask;
|
||||||
((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);
|
((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;
|
int x, offset;
|
||||||
uint16_t fg, bg;
|
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;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
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)
|
for (x = 0; x <= svga->hdisp; x += 2)
|
||||||
{
|
{
|
||||||
fg=vram[ma]|(vram[ma|0x1]<<8);
|
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
|
||||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
|
||||||
ma+=4; ma&=vrammask;
|
svga->ma += 4;
|
||||||
((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19);
|
svga->ma &= svga->vrammask;
|
||||||
((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19);
|
((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()
|
void svga_render_16bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
int x, offset;
|
int x, offset;
|
||||||
uint16_t fg, bg;
|
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;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
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);
|
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
|
||||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
|
||||||
ma+=4; ma&=vrammask;
|
svga->ma += 4;
|
||||||
((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);
|
svga->ma &= svga->vrammask;
|
||||||
((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);
|
((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()
|
void svga_render_16bpp_highres(svga_t *svga)
|
||||||
{
|
{
|
||||||
int x, offset;
|
int x, offset;
|
||||||
uint16_t fg, bg;
|
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;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
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)
|
for (x = 0; x <= svga->hdisp; x += 2)
|
||||||
{
|
{
|
||||||
fg=vram[ma]|(vram[ma|0x1]<<8);
|
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
|
||||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
|
||||||
ma+=4; ma&=vrammask;
|
svga->ma += 4;
|
||||||
((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19);
|
svga->ma &= svga->vrammask;
|
||||||
((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19);
|
((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_24bpp_lowres()
|
void svga_render_24bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
int x, offset;
|
int x, offset;
|
||||||
uint32_t fg;
|
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;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
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);
|
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
|
||||||
ma+=3; ma&=vrammask;
|
svga->ma += 3;
|
||||||
((uint32_t *)buffer32->line[displine])[(x<<1)+offset]=((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=fg;
|
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;
|
int x, offset;
|
||||||
uint32_t fg;
|
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;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
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);
|
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
|
||||||
ma+=3; ma&=vrammask;
|
svga->ma += 3;
|
||||||
((uint32_t *)buffer32->line[displine])[x + offset] = fg;
|
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;
|
int x, offset;
|
||||||
uint32_t fg;
|
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;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
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);
|
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
|
||||||
ma += 4; ma &= vrammask;
|
svga->ma += 4;
|
||||||
((uint32_t *)buffer32->line[displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[displine])[(x << 1) + 1 + offset] = fg;
|
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;
|
int x, offset;
|
||||||
uint32_t fg;
|
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;
|
if (svga->firstline_draw == 2000)
|
||||||
lastline_draw = displine;
|
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);
|
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
|
||||||
ma+=4; ma&=vrammask;
|
svga->ma += 4;
|
||||||
((uint32_t *)buffer32->line[displine])[x + offset] = fg;
|
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];
|
extern uint8_t edatlookup[4][4];
|
||||||
|
|
||||||
void svga_render_blank();
|
void svga_render_blank(svga_t *svga);
|
||||||
void svga_render_text_40();
|
void svga_render_text_40(svga_t *svga);
|
||||||
void svga_render_text_80();
|
void svga_render_text_80(svga_t *svga);
|
||||||
|
|
||||||
void svga_render_2bpp_lowres();
|
void svga_render_2bpp_lowres(svga_t *svga);
|
||||||
void svga_render_4bpp_lowres();
|
void svga_render_4bpp_lowres(svga_t *svga);
|
||||||
void svga_render_4bpp_highres();
|
void svga_render_4bpp_highres(svga_t *svga);
|
||||||
void svga_render_8bpp_lowres();
|
void svga_render_8bpp_lowres(svga_t *svga);
|
||||||
void svga_render_8bpp_highres();
|
void svga_render_8bpp_highres(svga_t *svga);
|
||||||
void svga_render_15bpp_lowres();
|
void svga_render_15bpp_lowres(svga_t *svga);
|
||||||
void svga_render_15bpp_highres();
|
void svga_render_15bpp_highres(svga_t *svga);
|
||||||
void svga_render_16bpp_lowres();
|
void svga_render_16bpp_lowres(svga_t *svga);
|
||||||
void svga_render_16bpp_highres();
|
void svga_render_16bpp_highres(svga_t *svga);
|
||||||
void svga_render_24bpp_lowres();
|
void svga_render_24bpp_lowres(svga_t *svga);
|
||||||
void svga_render_24bpp_highres();
|
void svga_render_24bpp_highres(svga_t *svga);
|
||||||
void svga_render_32bpp_lowres();
|
void svga_render_32bpp_lowres(svga_t *svga);
|
||||||
void svga_render_32bpp_highres();
|
void svga_render_32bpp_highres(svga_t *svga);
|
||||||
|
|
||||||
extern void (*svga_render)();
|
extern void (*svga_render)(svga_t *svga);
|
||||||
|
|
|
||||||
639
src/vid_tandy.c
639
src/vid_tandy.c
|
|
@ -1,138 +1,171 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
#include "video.h"
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
#include "video.h"
|
||||||
|
#include "vid_tandy.h"
|
||||||
|
|
||||||
static int tandy_array_index;
|
static int i_filt[8],q_filt[8];
|
||||||
static uint8_t tandy_array[32];
|
|
||||||
static int tandy_memctrl=-1;
|
|
||||||
static uint32_t tandy_base;
|
|
||||||
static uint8_t tandy_mode,tandy_col;
|
|
||||||
|
|
||||||
static uint8_t *tandy_vram, *tandy_b8000;
|
typedef struct tandy_t
|
||||||
|
|
||||||
void tandy_recalcaddress();
|
|
||||||
void tandy_recalctimings();
|
|
||||||
|
|
||||||
void tandy_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
|
uint8_t crtc[32];
|
||||||
|
int crtcreg;
|
||||||
|
|
||||||
|
int array_index;
|
||||||
|
uint8_t array[32];
|
||||||
|
int memctrl;//=-1;
|
||||||
|
uint32_t base;
|
||||||
|
uint8_t mode, col;
|
||||||
|
uint8_t stat;
|
||||||
|
|
||||||
|
uint8_t *vram, *b8000;
|
||||||
|
|
||||||
|
int linepos, displine;
|
||||||
|
int sc, vc;
|
||||||
|
int dispon;
|
||||||
|
int con, coff, cursoron, blink;
|
||||||
|
int vsynctime, vadj;
|
||||||
|
uint16_t ma, maback;
|
||||||
|
|
||||||
|
int dispontime, dispofftime, vidtime;
|
||||||
|
int firstline, lastline;
|
||||||
|
} tandy_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 tandy_recalcaddress(tandy_t *tandy);
|
||||||
|
void tandy_recalctimings(tandy_t *tandy);
|
||||||
|
|
||||||
|
void tandy_out(uint16_t addr, uint8_t val, void *p)
|
||||||
|
{
|
||||||
|
tandy_t *tandy = (tandy_t *)p;
|
||||||
uint8_t old;
|
uint8_t old;
|
||||||
// pclog("Tandy OUT %04X %02X\n",addr,val);
|
// pclog("Tandy OUT %04X %02X\n",addr,val);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3d4:
|
||||||
crtcreg=val&31;
|
tandy->crtcreg = val & 0x1f;
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3d5:
|
||||||
old=crtc[crtcreg];
|
old = tandy->crtc[tandy->crtcreg];
|
||||||
crtc[crtcreg]=val&crtcmask[crtcreg];
|
tandy->crtc[tandy->crtcreg] = val & crtcmask[tandy->crtcreg];
|
||||||
if (old != val)
|
if (old != val)
|
||||||
{
|
{
|
||||||
if (crtcreg<0xE || crtcreg>0x10)
|
if (tandy->crtcreg < 0xe || tandy->crtcreg > 0x10)
|
||||||
{
|
{
|
||||||
fullchange = changeframecount;
|
fullchange = changeframecount;
|
||||||
tandy_recalctimings();
|
tandy_recalctimings(tandy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x3D8:
|
case 0x3d8:
|
||||||
tandy_mode=val;
|
tandy->mode = val;
|
||||||
return;
|
return;
|
||||||
case 0x3D9:
|
case 0x3d9:
|
||||||
tandy_col=val;
|
tandy->col = val;
|
||||||
return;
|
return;
|
||||||
case 0x3DA:
|
case 0x3da:
|
||||||
tandy_array_index = val & 31;
|
tandy->array_index = val & 0x1f;
|
||||||
break;
|
break;
|
||||||
case 0x3DE:
|
case 0x3de:
|
||||||
if (tandy_array_index & 16) val &= 0xF;
|
if (tandy->array_index & 16)
|
||||||
tandy_array[tandy_array_index & 31] = val;
|
val &= 0xf;
|
||||||
|
tandy->array[tandy->array_index & 0x1f] = val;
|
||||||
break;
|
break;
|
||||||
case 0x3DF:
|
case 0x3df:
|
||||||
tandy_memctrl=val;
|
tandy->memctrl = val;
|
||||||
tandy_recalcaddress();
|
tandy_recalcaddress(tandy);
|
||||||
break;
|
break;
|
||||||
case 0xA0:
|
case 0xa0:
|
||||||
tandy_base=((val>>1)&7)*128*1024;
|
tandy->base = ((val >> 1) & 7) * 128 * 1024;
|
||||||
tandy_recalcaddress();
|
tandy_recalcaddress(tandy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tandy_in(uint16_t addr, void *priv)
|
uint8_t tandy_in(uint16_t addr, void *p)
|
||||||
{
|
{
|
||||||
|
tandy_t *tandy = (tandy_t *)p;
|
||||||
// if (addr!=0x3DA) pclog("Tandy IN %04X\n",addr);
|
// if (addr!=0x3DA) pclog("Tandy IN %04X\n",addr);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3d4:
|
||||||
return crtcreg;
|
return tandy->crtcreg;
|
||||||
case 0x3D5:
|
case 0x3d5:
|
||||||
return crtc[crtcreg];
|
return tandy->crtc[tandy->crtcreg];
|
||||||
case 0x3DA:
|
case 0x3da:
|
||||||
return cgastat;
|
return tandy->stat;
|
||||||
}
|
}
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tandy_recalcaddress()
|
void tandy_recalcaddress(tandy_t *tandy)
|
||||||
{
|
{
|
||||||
if ((tandy_memctrl&0xC0)==0xC0)
|
if ((tandy->memctrl & 0xc0) == 0xc0)
|
||||||
{
|
{
|
||||||
tandy_vram =&ram[((tandy_memctrl&0x6)<<14) +tandy_base];
|
tandy->vram = &ram[((tandy->memctrl & 0x06) << 14) + tandy->base];
|
||||||
tandy_b8000=&ram[((tandy_memctrl&0x30)<<11)+tandy_base];
|
tandy->b8000 = &ram[((tandy->memctrl & 0x30) << 11) + tandy->base];
|
||||||
// printf("VRAM at %05X B8000 at %05X\n",((tandy_memctrl&0x6)<<14)+tandy_base,((tandy_memctrl&0x30)<<11)+tandy_base);
|
// printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x6)<<14)+tandy->base,((tandy->memctrl&0x30)<<11)+tandy->base);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tandy_vram =&ram[((tandy_memctrl&0x7)<<14) +tandy_base];
|
tandy->vram = &ram[((tandy->memctrl & 0x07) << 14) + tandy->base];
|
||||||
tandy_b8000=&ram[((tandy_memctrl&0x38)<<11)+tandy_base];
|
tandy->b8000 = &ram[((tandy->memctrl & 0x38) << 11) + tandy->base];
|
||||||
// printf("VRAM at %05X B8000 at %05X\n",((tandy_memctrl&0x7)<<14)+tandy_base,((tandy_memctrl&0x38)<<11)+tandy_base);
|
// printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x7)<<14)+tandy->base,((tandy->memctrl&0x38)<<11)+tandy->base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tandy_write(uint32_t addr, uint8_t val, void *priv)
|
void tandy_write(uint32_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
if (tandy_memctrl==-1) return;
|
tandy_t *tandy = (tandy_t *)p;
|
||||||
|
if (tandy->memctrl == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
egawrites++;
|
||||||
// pclog("Tandy VRAM write %05X %02X %04X:%04X %04X:%04X\n",addr,val,CS,pc,DS,SI);
|
// pclog("Tandy VRAM write %05X %02X %04X:%04X %04X:%04X\n",addr,val,CS,pc,DS,SI);
|
||||||
tandy_b8000[addr&0x7FFF]=val;
|
tandy->b8000[addr & 0x7fff] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tandy_read(uint32_t addr, void *priv)
|
uint8_t tandy_read(uint32_t addr, void *p)
|
||||||
{
|
{
|
||||||
if (tandy_memctrl==-1) return 0xFF;
|
tandy_t *tandy = (tandy_t *)p;
|
||||||
// pclog("Tandy VRAM read %05X %02X %04X:%04X\n",addr,tandy_b8000[addr&0x7FFF],CS,pc);
|
if (tandy->memctrl == -1)
|
||||||
return tandy_b8000[addr&0x7FFF];
|
return 0xff;
|
||||||
|
|
||||||
|
egareads++;
|
||||||
|
// pclog("Tandy VRAM read %05X %02X %04X:%04X\n",addr,tandy->b8000[addr&0x7FFF],CS,pc);
|
||||||
|
return tandy->b8000[addr & 0x7fff];
|
||||||
}
|
}
|
||||||
|
|
||||||
void tandy_recalctimings()
|
void tandy_recalctimings(tandy_t *tandy)
|
||||||
{
|
{
|
||||||
double _dispontime, _dispofftime;
|
double _dispontime, _dispofftime, disptime;
|
||||||
if (tandy_mode&1)
|
if (tandy->mode & 1)
|
||||||
{
|
{
|
||||||
disptime=crtc[0]+1;
|
disptime = tandy->crtc[0] + 1;
|
||||||
_dispontime=crtc[1];
|
_dispontime = tandy->crtc[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
disptime=(crtc[0]+1)<<1;
|
disptime = (tandy->crtc[0] + 1) << 1;
|
||||||
_dispontime=crtc[1]<<1;
|
_dispontime = tandy->crtc[1] << 1;
|
||||||
}
|
}
|
||||||
_dispofftime = disptime - _dispontime;
|
_dispofftime = disptime - _dispontime;
|
||||||
_dispontime *= CGACONST;
|
_dispontime *= CGACONST;
|
||||||
_dispofftime *= CGACONST;
|
_dispofftime *= CGACONST;
|
||||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
tandy->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
tandy->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 ntsc_col[8][8]=
|
static int ntsc_col[8][8]=
|
||||||
{
|
{
|
||||||
{0,0,0,0,0,0,0,0}, /*Black*/
|
{0,0,0,0,0,0,0,0}, /*Black*/
|
||||||
|
|
@ -145,18 +178,17 @@ static int ntsc_col[8][8]=
|
||||||
{1,1,1,1,1,1,1,1} /*White*/
|
{1,1,1,1,1,1,1,1} /*White*/
|
||||||
};
|
};
|
||||||
|
|
||||||
int i_filt[8],q_filt[8];
|
|
||||||
|
|
||||||
/*static int cga4pal[8][4]=
|
/*static int cga4pal[8][4]=
|
||||||
{
|
{
|
||||||
{0,2,4,6},{0,3,5,7},{0,3,4,7},{0,3,4,7},
|
{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}
|
{0,10,12,14},{0,11,13,15},{0,11,12,15},{0,11,12,15}
|
||||||
};*/
|
};*/
|
||||||
|
|
||||||
void tandy_poll()
|
void tandy_poll(void *p)
|
||||||
{
|
{
|
||||||
// int *cgapal=cga4pal[((tandy_col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)];
|
// int *cgapal=cga4pal[((tandy->col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)];
|
||||||
uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF;
|
tandy_t *tandy = (tandy_t *)p;
|
||||||
|
uint16_t ca = (tandy->crtc[15] | (tandy->crtc[14] << 8)) & 0x3fff;
|
||||||
int drawcursor;
|
int drawcursor;
|
||||||
int x, c;
|
int x, c;
|
||||||
int oldvc;
|
int oldvc;
|
||||||
|
|
@ -169,170 +201,194 @@ void tandy_poll()
|
||||||
int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_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 q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot;
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
if (!linepos)
|
if (!tandy->linepos)
|
||||||
{
|
{
|
||||||
// cgapal[0]=tandy_col&15;
|
// cgapal[0]=tandy->col&15;
|
||||||
// printf("Firstline %i Lastline %i Displine %i\n",firstline,lastline,displine);
|
// printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine);
|
||||||
vidtime+=dispofftime;
|
tandy->vidtime += tandy->dispofftime;
|
||||||
cgastat|=1;
|
tandy->stat |= 1;
|
||||||
linepos=1;
|
tandy->linepos = 1;
|
||||||
oldsc=sc;
|
oldsc = tandy->sc;
|
||||||
if ((crtc[8]&3)==3) sc=(sc<<1)&7;
|
if ((tandy->crtc[8] & 3) == 3)
|
||||||
if (cgadispon)
|
tandy->sc = (tandy->sc << 1) & 7;
|
||||||
|
if (tandy->dispon)
|
||||||
{
|
{
|
||||||
if (displine<firstline)
|
if (tandy->displine < tandy->firstline)
|
||||||
{
|
{
|
||||||
firstline=displine;
|
tandy->firstline = tandy->displine;
|
||||||
// printf("Firstline %i\n",firstline);
|
// printf("Firstline %i\n",firstline);
|
||||||
}
|
}
|
||||||
lastline=displine;
|
tandy->lastline = tandy->displine;
|
||||||
cols[0]=(tandy_array[2]&0xF)+16;
|
cols[0] = (tandy->array[2] & 0xf) + 16;
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
{
|
{
|
||||||
if (tandy_array[3]&4)
|
if (tandy->array[3] & 4)
|
||||||
{
|
{
|
||||||
buffer->line[displine][c]=cols[0];
|
buffer->line[tandy->displine][c] = cols[0];
|
||||||
if (tandy_mode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=cols[0];
|
if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = cols[0];
|
||||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=cols[0];
|
else buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = cols[0];
|
||||||
}
|
}
|
||||||
else if ((tandy_mode&0x12)==0x12)
|
else if ((tandy->mode & 0x12) == 0x12)
|
||||||
{
|
{
|
||||||
buffer->line[displine][c]=0;
|
buffer->line[tandy->displine][c] = 0;
|
||||||
if (tandy_mode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
|
if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = 0;
|
||||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=0;
|
else buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buffer->line[displine][c]=(tandy_col&15)+16;
|
buffer->line[tandy->displine][c] = (tandy->col & 15) + 16;
|
||||||
if (tandy_mode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(tandy_col&15)+16;
|
if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = (tandy->col & 15) + 16;
|
||||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=(tandy_col&15)+16;
|
else buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = (tandy->col & 15) + 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// printf("X %i %i\n",c+(crtc[1]<<4)+8,c+(crtc[1]<<3)+8);
|
// printf("X %i %i\n",c+(crtc[1]<<4)+8,c+(crtc[1]<<3)+8);
|
||||||
// printf("Drawing %i %i %i\n",displine,vc,sc);
|
// printf("Drawing %i %i %i\n",tandy->displine,vc,sc);
|
||||||
if ((tandy_array[3]&0x10) && (tandy_mode&1)) /*320x200x16*/
|
if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/
|
||||||
{
|
{
|
||||||
for (x=0;x<crtc[1];x++)
|
for (x = 0; x < tandy->crtc[1]; x++)
|
||||||
{
|
{
|
||||||
dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)+1];
|
dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) |
|
||||||
ma++;
|
tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1];
|
||||||
buffer->line[displine][(x<<3)+8]=buffer->line[displine][(x<<3)+9] =tandy_array[((dat>>12)&tandy_array[1])+16]+16;
|
tandy->ma++;
|
||||||
buffer->line[displine][(x<<3)+10]=buffer->line[displine][(x<<3)+11]=tandy_array[((dat>>8)&tandy_array[1])+16]+16;
|
buffer->line[tandy->displine][(x << 3) + 8] =
|
||||||
buffer->line[displine][(x<<3)+12]=buffer->line[displine][(x<<3)+13]=tandy_array[((dat>>4)&tandy_array[1])+16]+16;
|
buffer->line[tandy->displine][(x << 3) + 9] = tandy->array[((dat >> 12) & tandy->array[1]) + 16] + 16;
|
||||||
buffer->line[displine][(x<<3)+14]=buffer->line[displine][(x<<3)+15]=tandy_array[(dat&tandy_array[1])+16]+16;
|
buffer->line[tandy->displine][(x << 3) + 10] =
|
||||||
|
buffer->line[tandy->displine][(x << 3) + 11] = tandy->array[((dat >> 8) & tandy->array[1]) + 16] + 16;
|
||||||
|
buffer->line[tandy->displine][(x << 3) + 12] =
|
||||||
|
buffer->line[tandy->displine][(x << 3) + 13] = tandy->array[((dat >> 4) & tandy->array[1]) + 16] + 16;
|
||||||
|
buffer->line[tandy->displine][(x << 3) + 14] =
|
||||||
|
buffer->line[tandy->displine][(x << 3) + 15] = tandy->array[(dat & tandy->array[1]) + 16] + 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tandy_array[3]&0x10) /*160x200x16*/
|
else if (tandy->array[3] & 0x10) /*160x200x16*/
|
||||||
{
|
{
|
||||||
for (x=0;x<crtc[1];x++)
|
for (x = 0; x < tandy->crtc[1]; x++)
|
||||||
{
|
{
|
||||||
dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)+1];
|
dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) |
|
||||||
ma++;
|
tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1];
|
||||||
buffer->line[displine][(x<<4)+8]= buffer->line[displine][(x<<4)+9]= buffer->line[displine][(x<<4)+10]=buffer->line[displine][(x<<4)+11]=tandy_array[((dat>>12)&tandy_array[1])+16]+16;
|
tandy->ma++;
|
||||||
buffer->line[displine][(x<<4)+12]=buffer->line[displine][(x<<4)+13]=buffer->line[displine][(x<<4)+14]=buffer->line[displine][(x<<4)+15]=tandy_array[((dat>>8)&tandy_array[1])+16]+16;
|
buffer->line[tandy->displine][(x << 4) + 8] =
|
||||||
buffer->line[displine][(x<<4)+16]=buffer->line[displine][(x<<4)+17]=buffer->line[displine][(x<<4)+18]=buffer->line[displine][(x<<4)+19]=tandy_array[((dat>>4)&tandy_array[1])+16]+16;
|
buffer->line[tandy->displine][(x << 4) + 9] =
|
||||||
buffer->line[displine][(x<<4)+20]=buffer->line[displine][(x<<4)+21]=buffer->line[displine][(x<<4)+22]=buffer->line[displine][(x<<4)+23]=tandy_array[(dat&tandy_array[1])+16]+16;
|
buffer->line[tandy->displine][(x << 4) + 10] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 11] = tandy->array[((dat >> 12) & tandy->array[1]) + 16] + 16;
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 12] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 13] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 14] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 15] = tandy->array[((dat >> 8) & tandy->array[1]) + 16] + 16;
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 16] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 17] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 18] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 19] = tandy->array[((dat >> 4) & tandy->array[1]) + 16] + 16;
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 20] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 21] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 22] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + 23] = tandy->array[(dat & tandy->array[1]) + 16] + 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tandy_array[3]&0x08) /*640x200x4 - this implementation is a complete guess!*/
|
else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/
|
||||||
{
|
{
|
||||||
for (x=0;x<crtc[1];x++)
|
for (x = 0; x < tandy->crtc[1]; x++)
|
||||||
{
|
{
|
||||||
dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)+1];
|
dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) |
|
||||||
ma++;
|
tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1];
|
||||||
|
tandy->ma++;
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
{
|
{
|
||||||
chr = (dat >> 7) & 1;
|
chr = (dat >> 7) & 1;
|
||||||
chr |= ((dat >> 14) & 2);
|
chr |= ((dat >> 14) & 2);
|
||||||
buffer->line[displine][(x<<3)+8+c]=tandy_array[(chr&tandy_array[1])+16]+16;
|
buffer->line[tandy->displine][(x << 3) + 8 + c] = tandy->array[(chr & tandy->array[1]) + 16] + 16;
|
||||||
dat <<= 1;
|
dat <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tandy_mode&1)
|
else if (tandy->mode & 1)
|
||||||
{
|
{
|
||||||
for (x=0;x<crtc[1];x++)
|
for (x = 0; x < tandy->crtc[1]; x++)
|
||||||
{
|
{
|
||||||
chr=tandy_vram[(ma<<1)&0x3FFF];
|
chr = tandy->vram[ (tandy->ma << 1) & 0x3fff];
|
||||||
attr=tandy_vram[((ma<<1)+1)&0x3FFF];
|
attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff];
|
||||||
drawcursor=((ma==ca) && con && cursoron);
|
drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron);
|
||||||
if (tandy_mode&0x20)
|
if (tandy->mode & 0x20)
|
||||||
{
|
{
|
||||||
cols[1]=tandy_array[((attr&15)&tandy_array[1])+16]+16;
|
cols[1] = tandy->array[ ((attr & 15) & tandy->array[1]) + 16] + 16;
|
||||||
cols[0]=tandy_array[(((attr>>4)&7)&tandy_array[1])+16]+16;
|
cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16] + 16;
|
||||||
if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
|
if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||||
|
cols[1] = cols[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cols[1]=tandy_array[((attr&15)&tandy_array[1])+16]+16;
|
cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16] + 16;
|
||||||
cols[0]=tandy_array[((attr>>4)&tandy_array[1])+16]+16;
|
cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16] + 16;
|
||||||
}
|
}
|
||||||
if (sc&8)
|
if (tandy->sc & 8)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
buffer->line[displine][(x<<3)+c+8]=cols[0];
|
buffer->line[tandy->displine][(x << 3) + c + 8] = cols[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
|
buffer->line[tandy->displine][(x << 3) + c + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||||
}
|
}
|
||||||
// if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) printf("Cursor match! %04X\n",ma);
|
// if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) printf("Cursor match! %04X\n",ma);
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
buffer->line[displine][(x<<3)+c+8]^=15;
|
buffer->line[tandy->displine][(x << 3) + c + 8] ^= 15;
|
||||||
}
|
}
|
||||||
ma++;
|
tandy->ma++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!(tandy_mode&2))
|
else if (!(tandy->mode & 2))
|
||||||
{
|
{
|
||||||
for (x=0;x<crtc[1];x++)
|
for (x = 0; x < tandy->crtc[1]; x++)
|
||||||
{
|
{
|
||||||
chr=tandy_vram[(ma<<1)&0x3FFF];
|
chr = tandy->vram[ (tandy->ma << 1) & 0x3fff];
|
||||||
attr=tandy_vram[((ma<<1)+1)&0x3FFF];
|
attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff];
|
||||||
drawcursor=((ma==ca) && con && cursoron);
|
drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron);
|
||||||
if (tandy_mode&0x20)
|
if (tandy->mode & 0x20)
|
||||||
{
|
{
|
||||||
cols[1]=tandy_array[((attr&15)&tandy_array[1])+16]+16;
|
cols[1] = tandy->array[ ((attr & 15) & tandy->array[1]) + 16] + 16;
|
||||||
cols[0]=tandy_array[(((attr>>4)&7)&tandy_array[1])+16]+16;
|
cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16] + 16;
|
||||||
if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
|
if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||||
|
cols[1] = cols[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cols[1]=tandy_array[((attr&15)&tandy_array[1])+16]+16;
|
cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16] + 16;
|
||||||
cols[0]=tandy_array[((attr>>4)&tandy_array[1])+16]+16;
|
cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16] + 16;
|
||||||
}
|
}
|
||||||
ma++;
|
tandy->ma++;
|
||||||
if (sc&8)
|
if (tandy->sc & 8)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[0];
|
buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (c = 0; c < 8; c++)
|
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];
|
buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] =
|
||||||
|
buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||||
}
|
}
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
for (c = 0; c < 16; c++)
|
for (c = 0; c < 16; c++)
|
||||||
buffer->line[displine][(x<<4)+c+8]^=15;
|
buffer->line[tandy->displine][(x << 4) + c + 8] ^= 15;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!(tandy_mode&16))
|
else if (!(tandy->mode& 16))
|
||||||
{
|
{
|
||||||
cols[0]=(tandy_col&15)|16;
|
cols[0] = (tandy->col & 15) | 16;
|
||||||
col=(tandy_col&16)?24:16;
|
col = (tandy->col & 16) ? 24 : 16;
|
||||||
if (tandy_mode&4)
|
if (tandy->mode & 4)
|
||||||
{
|
{
|
||||||
cols[1] = col | 3;
|
cols[1] = col | 3;
|
||||||
cols[2] = col | 4;
|
cols[2] = col | 4;
|
||||||
cols[3] = col | 7;
|
cols[3] = col | 7;
|
||||||
}
|
}
|
||||||
else if (tandy_col&32)
|
else if (tandy->col & 32)
|
||||||
{
|
{
|
||||||
cols[1] = col | 3;
|
cols[1] = col | 3;
|
||||||
cols[2] = col | 5;
|
cols[2] = col | 5;
|
||||||
|
|
@ -344,28 +400,31 @@ void tandy_poll()
|
||||||
cols[2] = col | 4;
|
cols[2] = col | 4;
|
||||||
cols[3] = col | 6;
|
cols[3] = col | 6;
|
||||||
}
|
}
|
||||||
for (x=0;x<crtc[1];x++)
|
for (x = 0; x < tandy->crtc[1]; x++)
|
||||||
{
|
{
|
||||||
dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1];
|
dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) |
|
||||||
ma++;
|
tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1];
|
||||||
|
tandy->ma++;
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
{
|
{
|
||||||
buffer->line[displine][(x<<4)+(c<<1)+8]=
|
buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] =
|
||||||
buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
|
buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||||
dat <<= 2;
|
dat <<= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cols[0]=0; cols[1]=tandy_array[(tandy_col&tandy_array[1])+16]+16;
|
cols[0] = 0;
|
||||||
for (x=0;x<crtc[1];x++)
|
cols[1] = tandy->array[(tandy->col & tandy->array[1]) + 16] + 16;
|
||||||
|
for (x = 0; x < tandy->crtc[1]; x++)
|
||||||
{
|
{
|
||||||
dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1];
|
dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) |
|
||||||
ma++;
|
tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1];
|
||||||
|
tandy->ma++;
|
||||||
for (c = 0; c < 16; c++)
|
for (c = 0; c < 16; c++)
|
||||||
{
|
{
|
||||||
buffer->line[displine][(x<<4)+c+8]=cols[dat>>15];
|
buffer->line[tandy->displine][(x << 4) + c + 8] = cols[dat >> 15];
|
||||||
dat <<= 1;
|
dat <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -373,26 +432,26 @@ void tandy_poll()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (tandy_array[3]&4)
|
if (tandy->array[3] & 4)
|
||||||
{
|
{
|
||||||
if (tandy_mode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,(tandy_array[2]&0xF)+16);
|
if (tandy->mode & 1) hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, (tandy->array[2] & 0xf) + 16);
|
||||||
else hline(buffer,0,displine,(crtc[1]<<4)+16,(tandy_array[2]&0xF)+16);
|
else hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, (tandy->array[2] & 0xf) + 16);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cols[0]=((tandy_mode&0x12)==0x12)?0:(tandy_col&15)+16;
|
cols[0] = ((tandy->mode & 0x12) == 0x12) ? 0 : (tandy->col & 0xf) + 16;
|
||||||
if (tandy_mode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
|
if (tandy->mode & 1) hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cols[0]);
|
||||||
else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
|
else hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cols[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tandy_mode&1) x=(crtc[1]<<3)+16;
|
if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16;
|
||||||
else x=(crtc[1]<<4)+16;
|
else x = (tandy->crtc[1] << 4) + 16;
|
||||||
if (cga_comp)
|
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] = ntsc_col[buffer->line[tandy->displine][c] & 7][(c << 1) & 6] ? 0x6000 : 0;
|
||||||
y_buf[(c<<1)&6]+=(buffer->line[displine][c]&8)?0x3000:0;
|
y_buf[(c << 1) & 6] += (buffer->line[tandy->displine][c] & 8) ? 0x3000 : 0;
|
||||||
i_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * i_filt[(c << 1) & 6];
|
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];
|
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];
|
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];
|
||||||
|
|
@ -412,12 +471,9 @@ void tandy_poll()
|
||||||
r = (y_val + 249*i_val + 159*q_val) >> 16;
|
r = (y_val + 249*i_val + 159*q_val) >> 16;
|
||||||
g = (y_val - 70*i_val - 166*q_val) >> 16;
|
g = (y_val - 70*i_val - 166*q_val) >> 16;
|
||||||
b = (y_val - 283*i_val + 436*q_val) >> 16;
|
b = (y_val - 283*i_val + 436*q_val) >> 16;
|
||||||
// if (r>255) r=255;
|
|
||||||
// if (g>255) g=255;
|
|
||||||
// if (b>255) b=255;
|
|
||||||
|
|
||||||
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] = ntsc_col[buffer->line[tandy->displine][c] & 7][((c << 1) & 6) + 1] ? 0x6000 : 0;
|
||||||
y_buf[((c<<1)&6)+1]+=(buffer->line[displine][c]&8)?0x3000:0;
|
y_buf[((c << 1) & 6) + 1] += (buffer->line[tandy->displine][c] & 8) ? 0x3000 : 0;
|
||||||
i_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * i_filt[((c << 1) & 6) + 1];
|
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];
|
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];
|
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];
|
||||||
|
|
@ -434,93 +490,102 @@ void tandy_poll()
|
||||||
if (q_val > 34249) q_val = 34249;
|
if (q_val > 34249) q_val = 34249;
|
||||||
if (q_val < -34249) q_val = -34249;
|
if (q_val < -34249) q_val = -34249;
|
||||||
|
|
||||||
r+=(y_val+249*i_val+159*q_val)>>16;
|
r = (y_val + 249*i_val + 159*q_val) >> 16;
|
||||||
g+=(y_val-70*i_val-166*q_val)>>16;
|
g = (y_val - 70*i_val - 166*q_val) >> 16;
|
||||||
b+=(y_val-283*i_val+436*q_val)>>16;
|
b = (y_val - 283*i_val + 436*q_val) >> 16;
|
||||||
if (r > 511) r = 511;
|
if (r > 511) r = 511;
|
||||||
if (g > 511) g = 511;
|
if (g > 511) g = 511;
|
||||||
if (b > 511) b = 511;
|
if (b > 511) b = 511;
|
||||||
|
|
||||||
((uint32_t *)buffer32->line[displine])[c]=makecol32(r/2,g/2,b/2);
|
((uint32_t *)buffer32->line[tandy->displine])[c] = makecol32(r / 2, g / 2, b / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sc=oldsc;
|
tandy->sc = oldsc;
|
||||||
if (vc==crtc[7] && !sc)
|
if (tandy->vc == tandy->crtc[7] && !tandy->sc)
|
||||||
{
|
{
|
||||||
cgastat|=8;
|
tandy->stat |= 8;
|
||||||
// printf("VSYNC on %i %i\n",vc,sc);
|
// printf("VSYNC on %i %i\n",vc,sc);
|
||||||
}
|
}
|
||||||
displine++;
|
tandy->displine++;
|
||||||
if (displine>=360) displine=0;
|
if (tandy->displine >= 360)
|
||||||
|
tandy->displine = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vidtime+=dispontime;
|
tandy->vidtime += tandy->dispontime;
|
||||||
if (cgadispon) cgastat&=~1;
|
if (tandy->dispon)
|
||||||
linepos=0;
|
tandy->stat &= ~1;
|
||||||
if (vsynctime)
|
tandy->linepos = 0;
|
||||||
|
if (tandy->vsynctime)
|
||||||
{
|
{
|
||||||
vsynctime--;
|
tandy->vsynctime--;
|
||||||
if (!vsynctime)
|
if (!tandy->vsynctime)
|
||||||
{
|
{
|
||||||
cgastat&=~8;
|
tandy->stat &= ~8;
|
||||||
// printf("VSYNC off %i %i\n",vc,sc);
|
// printf("VSYNC off %i %i\n",vc,sc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sc==(crtc[11]&31) || ((crtc[8]&3)==3 && sc==((crtc[11]&31)>>1))) { con=0; coff=1; }
|
if (tandy->sc == (tandy->crtc[11] & 31) || ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[11] & 31) >> 1)))
|
||||||
if (vadj)
|
|
||||||
{
|
{
|
||||||
sc++;
|
tandy->con = 0;
|
||||||
sc&=31;
|
tandy->coff = 1;
|
||||||
ma=maback;
|
}
|
||||||
vadj--;
|
if (tandy->vadj)
|
||||||
if (!vadj)
|
|
||||||
{
|
{
|
||||||
cgadispon=1;
|
tandy->sc++;
|
||||||
ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
tandy->sc &= 31;
|
||||||
sc=0;
|
tandy->ma = tandy->maback;
|
||||||
|
tandy->vadj--;
|
||||||
|
if (!tandy->vadj)
|
||||||
|
{
|
||||||
|
tandy->dispon = 1;
|
||||||
|
tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff;
|
||||||
|
tandy->sc = 0;
|
||||||
// printf("Display on!\n");
|
// printf("Display on!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sc==crtc[9] || ((crtc[8]&3)==3 && sc==(crtc[9]>>1)))
|
else if (tandy->sc == tandy->crtc[9] || ((tandy->crtc[8] & 3) == 3 && tandy->sc == (tandy->crtc[9] >> 1)))
|
||||||
{
|
{
|
||||||
maback=ma;
|
tandy->maback = tandy->ma;
|
||||||
// con=0;
|
// con=0;
|
||||||
// coff=0;
|
// coff=0;
|
||||||
sc=0;
|
tandy->sc = 0;
|
||||||
oldvc=vc;
|
oldvc = tandy->vc;
|
||||||
vc++;
|
tandy->vc++;
|
||||||
vc&=127;
|
tandy->vc &= 127;
|
||||||
// printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],cgadispon);
|
// printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],tandy->dispon);
|
||||||
if (vc==crtc[6]) cgadispon=0;
|
if (tandy->vc == tandy->crtc[6])
|
||||||
if (oldvc==crtc[4])
|
tandy->dispon = 0;
|
||||||
|
if (oldvc == tandy->crtc[4])
|
||||||
{
|
{
|
||||||
// printf("Display over at %i\n",displine);
|
// printf("Display over at %i\n",tandy->displine);
|
||||||
vc=0;
|
tandy->vc = 0;
|
||||||
vadj=crtc[5];
|
tandy->vadj = tandy->crtc[5];
|
||||||
if (!vadj) cgadispon=1;
|
if (!tandy->vadj)
|
||||||
if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
tandy->dispon = 1;
|
||||||
if ((crtc[10]&0x60)==0x20) cursoron=0;
|
if (!tandy->vadj)
|
||||||
else cursoron=cgablink&16;
|
tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff;
|
||||||
|
if ((tandy->crtc[10] & 0x60) == 0x20) tandy->cursoron = 0;
|
||||||
|
else tandy->cursoron = tandy->blink & 16;
|
||||||
// printf("CRTC10 %02X %i\n",crtc[10],cursoron);
|
// printf("CRTC10 %02X %i\n",crtc[10],cursoron);
|
||||||
}
|
}
|
||||||
if (vc==crtc[7])
|
if (tandy->vc == tandy->crtc[7])
|
||||||
{
|
{
|
||||||
cgadispon=0;
|
tandy->dispon = 0;
|
||||||
displine=0;
|
tandy->displine = 0;
|
||||||
vsynctime=16;//(crtc[3]>>4)+1;
|
tandy->vsynctime = 16;//(crtc[3]>>4)+1;
|
||||||
// printf("Vsynctime %i %02X\n",vsynctime,crtc[3]);
|
// printf("tandy->vsynctime %i %02X\n",tandy->vsynctime,crtc[3]);
|
||||||
// cgastat|=8;
|
// tandy->stat|=8;
|
||||||
if (crtc[7])
|
if (tandy->crtc[7])
|
||||||
{
|
{
|
||||||
// printf("Lastline %i Firstline %i %i %i %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize);
|
// printf("Lastline %i Firstline %i %i %i %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize);
|
||||||
if (tandy_mode&1) x=(crtc[1]<<3)+16;
|
if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16;
|
||||||
else x=(crtc[1]<<4)+16;
|
else x = (tandy->crtc[1] << 4) + 16;
|
||||||
lastline++;
|
tandy->lastline++;
|
||||||
if (x!=xsize || (lastline-firstline)!=ysize)
|
if (x != xsize || (tandy->lastline - tandy->firstline) != ysize)
|
||||||
{
|
{
|
||||||
xsize = x;
|
xsize = x;
|
||||||
ysize=lastline-firstline;
|
ysize = tandy->lastline - tandy->firstline;
|
||||||
// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtc[1]);
|
// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtc[1]);
|
||||||
if (xsize < 64) xsize = 656;
|
if (xsize < 64) xsize = 656;
|
||||||
if (ysize < 32) ysize = 200;
|
if (ysize < 32) ysize = 200;
|
||||||
|
|
@ -530,38 +595,38 @@ void tandy_poll()
|
||||||
//printf("Xsize is %i\n",xsize);
|
//printf("Xsize is %i\n",xsize);
|
||||||
startblit();
|
startblit();
|
||||||
if (cga_comp)
|
if (cga_comp)
|
||||||
video_blit_memtoscreen(0, firstline-4, 0, (lastline-firstline)+8, xsize, (lastline-firstline)+8);
|
video_blit_memtoscreen(0, tandy->firstline-4, 0, (tandy->lastline - tandy->firstline) + 8, xsize, (tandy->lastline - tandy->firstline) + 8);
|
||||||
else
|
else
|
||||||
video_blit_memtoscreen_8(0, firstline-4, xsize, (lastline-firstline)+8);
|
video_blit_memtoscreen_8(0, tandy->firstline-4, xsize, (tandy->lastline - tandy->firstline) + 8);
|
||||||
endblit();
|
endblit();
|
||||||
frames++;
|
frames++;
|
||||||
video_res_x = xsize - 16;
|
video_res_x = xsize - 16;
|
||||||
video_res_y = ysize;
|
video_res_y = ysize;
|
||||||
if ((tandy_array[3]&0x10) && (tandy_mode&1)) /*320x200x16*/
|
if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/
|
||||||
{
|
{
|
||||||
video_res_x /= 2;
|
video_res_x /= 2;
|
||||||
video_bpp = 4;
|
video_bpp = 4;
|
||||||
}
|
}
|
||||||
else if (tandy_array[3]&0x10) /*160x200x16*/
|
else if (tandy->array[3] & 0x10) /*160x200x16*/
|
||||||
{
|
{
|
||||||
video_res_x /= 4;
|
video_res_x /= 4;
|
||||||
video_bpp = 4;
|
video_bpp = 4;
|
||||||
}
|
}
|
||||||
else if (tandy_array[3]&0x08) /*640x200x4 - this implementation is a complete guess!*/
|
else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/
|
||||||
video_bpp = 2;
|
video_bpp = 2;
|
||||||
else if (tandy_mode&1)
|
else if (tandy->mode & 1)
|
||||||
{
|
{
|
||||||
video_res_x /= 8;
|
video_res_x /= 8;
|
||||||
video_res_y /= crtc[9] + 1;
|
video_res_y /= tandy->crtc[9] + 1;
|
||||||
video_bpp = 0;
|
video_bpp = 0;
|
||||||
}
|
}
|
||||||
else if (!(tandy_mode&2))
|
else if (!(tandy->mode & 2))
|
||||||
{
|
{
|
||||||
video_res_x /= 16;
|
video_res_x /= 16;
|
||||||
video_res_y /= crtc[9] + 1;
|
video_res_y /= tandy->crtc[9] + 1;
|
||||||
video_bpp = 0;
|
video_bpp = 0;
|
||||||
}
|
}
|
||||||
else if (!(tandy_mode&16))
|
else if (!(tandy->mode & 16))
|
||||||
{
|
{
|
||||||
video_res_x /= 2;
|
video_res_x /= 2;
|
||||||
video_bpp = 2;
|
video_bpp = 2;
|
||||||
|
|
@ -569,47 +634,63 @@ void tandy_poll()
|
||||||
else
|
else
|
||||||
video_bpp = 1;
|
video_bpp = 1;
|
||||||
}
|
}
|
||||||
firstline=1000;
|
tandy->firstline = 1000;
|
||||||
lastline=0;
|
tandy->lastline = 0;
|
||||||
cgablink++;
|
tandy->blink++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sc++;
|
tandy->sc++;
|
||||||
sc&=31;
|
tandy->sc &= 31;
|
||||||
ma=maback;
|
tandy->ma = tandy->maback;
|
||||||
}
|
}
|
||||||
if ((sc==(crtc[10]&31) || ((crtc[8]&3)==3 && sc==((crtc[10]&31)>>1)))) con=1;
|
if ((tandy->sc == (tandy->crtc[10] & 31) || ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[10] & 31) >> 1))))
|
||||||
|
tandy->con = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int tandy_init()
|
void *tandy_init()
|
||||||
{
|
{
|
||||||
mem_sethandler(0xb8000, 0x8000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, NULL);
|
int c;
|
||||||
io_sethandler(0x00a0, 0x0002, tandy_in, NULL, NULL, tandy_out, NULL, NULL, NULL);
|
int tandy_tint = -2;
|
||||||
tandy_memctrl = -1;
|
tandy_t *tandy = malloc(sizeof(tandy_t));
|
||||||
return 0;
|
memset(tandy, 0, sizeof(tandy_t));
|
||||||
|
|
||||||
|
tandy->memctrl = -1;
|
||||||
|
|
||||||
|
for (c = 0; c < 8; c++)
|
||||||
|
{
|
||||||
|
i_filt[c] = 512.0 * cos((3.14 * (tandy_tint + c * 4) / 16.0) - 33.0 / 180.0);
|
||||||
|
q_filt[c] = 512.0 * sin((3.14 * (tandy_tint + c * 4) / 16.0) - 33.0 / 180.0);
|
||||||
|
}
|
||||||
|
timer_add(tandy_poll, &tandy->vidtime, TIMER_ALWAYS_ENABLED, tandy);
|
||||||
|
mem_sethandler(0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, tandy);
|
||||||
|
io_sethandler(0x03d0, 0x0010, tandy_in, NULL, NULL, tandy_out, NULL, NULL, tandy);
|
||||||
|
io_sethandler(0x00a0, 0x0001, tandy_in, NULL, NULL, tandy_out, NULL, NULL, tandy);
|
||||||
|
return tandy;
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXCARD vid_tandy =
|
void tandy_close(void *p)
|
||||||
{
|
{
|
||||||
|
tandy_t *tandy = (tandy_t *)p;
|
||||||
|
|
||||||
|
free(tandy->vram);
|
||||||
|
free(tandy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tandy_speed_changed(void *p)
|
||||||
|
{
|
||||||
|
tandy_t *tandy = (tandy_t *)p;
|
||||||
|
|
||||||
|
tandy_recalctimings(tandy);
|
||||||
|
}
|
||||||
|
|
||||||
|
device_t tandy_device =
|
||||||
|
{
|
||||||
|
"Tandy 1000 (video)",
|
||||||
tandy_init,
|
tandy_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
tandy_close,
|
||||||
tandy_out,
|
tandy_speed_changed,
|
||||||
tandy_in,
|
NULL
|
||||||
/*IO at 3Ax/3Bx*/
|
|
||||||
video_out_null,
|
|
||||||
video_in_null,
|
|
||||||
|
|
||||||
tandy_poll,
|
|
||||||
tandy_recalctimings,
|
|
||||||
|
|
||||||
video_write_null,
|
|
||||||
video_write_null,
|
|
||||||
tandy_write,
|
|
||||||
|
|
||||||
video_read_null,
|
|
||||||
video_read_null,
|
|
||||||
tandy_read
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
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 int tkd8001_state=0;
|
||||||
static uint8_t tkd8001_ctrl;
|
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);
|
// pclog("OUT RAMDAC %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3C6:
|
case 0x3C6:
|
||||||
if (tkd8001_state == 4)
|
if (ramdac->state == 4)
|
||||||
{
|
{
|
||||||
tkd8001_state = 0;
|
ramdac->state = 0;
|
||||||
tkd8001_ctrl = val;
|
ramdac->ctrl = val;
|
||||||
switch (val >> 5)
|
switch (val >> 5)
|
||||||
{
|
{
|
||||||
case 0: case 1: case 2: case 3:
|
case 0: case 1: case 2: case 3:
|
||||||
bpp = 8;
|
svga->bpp = 8;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
bpp = 15;
|
svga->bpp = 15;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
bpp = 24;
|
svga->bpp = 24;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
bpp = 16;
|
svga->bpp = 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -37,28 +37,28 @@ void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
||||||
// tkd8001_state = 0;
|
// tkd8001_state = 0;
|
||||||
break;
|
break;
|
||||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
case 0x3C7: case 0x3C8: case 0x3C9:
|
||||||
tkd8001_state = 0;
|
ramdac->state = 0;
|
||||||
break;
|
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);
|
// pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3C6:
|
case 0x3C6:
|
||||||
if (tkd8001_state == 4)
|
if (ramdac->state == 4)
|
||||||
{
|
{
|
||||||
//tkd8001_state = 0;
|
//tkd8001_state = 0;
|
||||||
return tkd8001_ctrl;
|
return ramdac->ctrl;
|
||||||
}
|
}
|
||||||
tkd8001_state++;
|
ramdac->state++;
|
||||||
break;
|
break;
|
||||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
case 0x3C7: case 0x3C8: case 0x3C9:
|
||||||
tkd8001_state = 0;
|
ramdac->state = 0;
|
||||||
break;
|
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);
|
typedef struct tkd8001_ramdac_t
|
||||||
uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv);
|
{
|
||||||
|
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);
|
||||||
|
|
|
||||||
1149
src/vid_tvga.c
1149
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_svga.h"
|
||||||
#include "vid_unk_ramdac.h"
|
#include "vid_unk_ramdac.h"
|
||||||
|
|
||||||
static int unk_state=0;
|
void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga)
|
||||||
static uint8_t unk_ctrl;
|
|
||||||
|
|
||||||
void unk_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
//pclog("OUT RAMDAC %04X %02X\n",addr,val);
|
//pclog("OUT RAMDAC %04X %02X\n",addr,val);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3C6:
|
case 0x3C6:
|
||||||
if (unk_state == 4)
|
if (ramdac->state == 4)
|
||||||
{
|
{
|
||||||
unk_state = 0;
|
ramdac->state = 0;
|
||||||
unk_ctrl = val;
|
ramdac->ctrl = val;
|
||||||
switch ((val&1)|((val&0xE0)>>4))
|
switch ((val&1)|((val&0xE0)>>4))
|
||||||
{
|
{
|
||||||
case 0: case 1: case 2: case 3:
|
case 0: case 1: case 2: case 3:
|
||||||
bpp = 8;
|
svga->bpp = 8;
|
||||||
break;
|
break;
|
||||||
case 6: case 7:
|
case 6: case 7:
|
||||||
bpp = 24;
|
svga->bpp = 24;
|
||||||
break;
|
break;
|
||||||
case 8: case 9: case 0xA: case 0xB:
|
case 8: case 9: case 0xA: case 0xB:
|
||||||
bpp = 15;
|
svga->bpp = 15;
|
||||||
break;
|
break;
|
||||||
case 0xC: case 0xD: case 0xE: case 0xF:
|
case 0xC: case 0xD: case 0xE: case 0xF:
|
||||||
bpp = 16;
|
svga->bpp = 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unk_state = 0;
|
ramdac->state = 0;
|
||||||
break;
|
break;
|
||||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
case 0x3C7: case 0x3C8: case 0x3C9:
|
||||||
unk_state = 0;
|
ramdac->state = 0;
|
||||||
break;
|
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);
|
//pclog("IN RAMDAC %04X\n",addr);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3C6:
|
case 0x3C6:
|
||||||
if (unk_state == 4)
|
if (ramdac->state == 4)
|
||||||
{
|
{
|
||||||
unk_state = 0;
|
ramdac->state = 0;
|
||||||
return unk_ctrl;
|
return ramdac->ctrl;
|
||||||
}
|
}
|
||||||
unk_state++;
|
ramdac->state++;
|
||||||
break;
|
break;
|
||||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
case 0x3C7: case 0x3C8: case 0x3C9:
|
||||||
unk_state = 0;
|
ramdac->state = 0;
|
||||||
break;
|
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);
|
typedef struct unk_ramdac_t
|
||||||
uint8_t unk_ramdac_in(uint16_t addr, void *priv);
|
{
|
||||||
|
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);
|
||||||
|
|
|
||||||
104
src/vid_vga.c
104
src/vid_vga.c
|
|
@ -1,92 +1,116 @@
|
||||||
/*IBM VGA emulation*/
|
/*IBM VGA emulation*/
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vid_svga.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;
|
uint8_t old;
|
||||||
|
|
||||||
pclog("vga_out : %04X %02X %04X:%04X %02X %i\n", addr, val, CS,pc, ram[0x489], ins);
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
crtcreg = val & 0x1f;
|
svga->crtcreg = val & 0x1f;
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
||||||
old=crtc[crtcreg];
|
old = svga->crtc[svga->crtcreg];
|
||||||
crtc[crtcreg]=val;
|
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;
|
fullchange = changeframecount;
|
||||||
svga_recalctimings();
|
svga_recalctimings(svga);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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;
|
uint8_t temp;
|
||||||
|
|
||||||
if (addr != 0x3da) pclog("vga_in : %04X ", addr);
|
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)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
temp = crtcreg;
|
temp = svga->crtcreg;
|
||||||
break;
|
break;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
temp = crtc[crtcreg];
|
temp = svga->crtc[svga->crtcreg];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
temp = svga_in(addr, NULL);
|
temp = svga_in(addr, svga);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vga_init()
|
void *vga_init()
|
||||||
{
|
{
|
||||||
svga_recalctimings_ex = NULL;
|
vga_t *vga = malloc(sizeof(vga_t));
|
||||||
svga_vram_limit = 1 << 18; /*256kb*/
|
memset(vga, 0, sizeof(vga_t));
|
||||||
vrammask = 0x3ffff;
|
|
||||||
svgawbank = svgarbank = 0;
|
svga_init(&vga->svga, vga, 1 << 18, /*256kb*/
|
||||||
bpp = 8;
|
NULL,
|
||||||
svga_miscout = 1;
|
vga_in, vga_out,
|
||||||
return svga_init();
|
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,
|
vga_init,
|
||||||
/*IO at 3Cx/3Dx*/
|
vga_close,
|
||||||
vga_out,
|
vga_speed_changed,
|
||||||
vga_in,
|
svga_add_status_info
|
||||||
/*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
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
src/vid_vga.h
Normal file
1
src/vid_vga.h
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
extern device_t vga_device;
|
||||||
304
src/video.c
304
src/video.c
|
|
@ -1,13 +1,45 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vid_svga.h"
|
#include "vid_svga.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "timer.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 -
|
/*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)(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_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()
|
void video_init()
|
||||||
{
|
{
|
||||||
pclog("Video_init %i %i\n",romset,gfxcard);
|
pclog("Video_init %i %i\n",romset,gfxcard);
|
||||||
|
|
@ -155,107 +123,108 @@ void video_init()
|
||||||
switch (romset)
|
switch (romset)
|
||||||
{
|
{
|
||||||
case ROM_TANDY:
|
case ROM_TANDY:
|
||||||
video_load(vid_tandy);
|
device_add(&tandy_device);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ROM_PC1512:
|
case ROM_PC1512:
|
||||||
video_load(vid_pc1512);
|
device_add(&pc1512_device);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ROM_PC1640:
|
case ROM_PC1640:
|
||||||
video_load(vid_pc1640);
|
device_add(&pc1640_device);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ROM_PC200:
|
case ROM_PC200:
|
||||||
video_load(vid_pc200);
|
device_add(&pc200_device);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ROM_OLIM24:
|
case ROM_OLIM24:
|
||||||
video_load(vid_m24);
|
device_add(&m24_device);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ROM_PC2086:
|
case ROM_PC2086:
|
||||||
case ROM_PC3086:
|
case ROM_PC3086:
|
||||||
|
device_add(¶dise_pvga1a_device);
|
||||||
|
return;
|
||||||
case ROM_MEGAPC:
|
case ROM_MEGAPC:
|
||||||
video_load(vid_paradise);
|
device_add(¶dise_wd90c11_device);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ROM_ACER386:
|
case ROM_ACER386:
|
||||||
video_load(vid_oti067);
|
device_add(&oti067_device);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (gfxcard)
|
switch (gfxcard)
|
||||||
{
|
{
|
||||||
case GFX_MDA:
|
case GFX_MDA:
|
||||||
video_load(vid_mda);
|
device_add(&mda_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_HERCULES:
|
case GFX_HERCULES:
|
||||||
video_load(vid_hercules);
|
device_add(&hercules_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_CGA:
|
case GFX_CGA:
|
||||||
video_load(vid_cga);
|
device_add(&cga_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_EGA:
|
case GFX_EGA:
|
||||||
video_load(vid_ega);
|
device_add(&ega_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_TVGA:
|
case GFX_TVGA:
|
||||||
video_load(vid_tvga);
|
device_add(&tvga8900d_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_ET4000:
|
case GFX_ET4000:
|
||||||
video_load(vid_et4000);
|
device_add(&et4000_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_ET4000W32:
|
case GFX_ET4000W32:
|
||||||
video_load(vid_et4000w32p);
|
device_add(&et4000w32p_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_BAHAMAS64:
|
case GFX_BAHAMAS64:
|
||||||
video_load(vid_s3);
|
device_add(&s3_bahamas64_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_N9_9FX:
|
case GFX_N9_9FX:
|
||||||
video_load(vid_s3);
|
device_add(&s3_9fx_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_STEALTH64:
|
case GFX_STEALTH64:
|
||||||
video_load(vid_s3);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_VIRGE:
|
case GFX_VIRGE:
|
||||||
video_load(vid_s3_virge);
|
device_add(&s3_virge_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_TGUI9440:
|
case GFX_TGUI9440:
|
||||||
video_load(vid_tgui9440);
|
device_add(&tgui9440_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_VGA:
|
case GFX_VGA:
|
||||||
video_load(vid_vga);
|
device_add(&vga_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_VGAEDGE16:
|
case GFX_VGAEDGE16:
|
||||||
video_load(vid_ati18800);
|
device_add(&ati18800_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_VGACHARGER:
|
case GFX_VGACHARGER:
|
||||||
video_load(vid_ati28800);
|
device_add(&ati18800_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFX_OTI067:
|
case GFX_OTI067:
|
||||||
video_load(vid_oti067);
|
device_add(&oti067_device);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GFX_MACH64GX:
|
case GFX_MACH64GX:
|
||||||
video_load(vid_mach64);
|
device_add(&mach64gx_device);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GFX_CL_GD5429:
|
case GFX_CL_GD5429:
|
||||||
video_load(vid_gd5429);
|
device_add(&gd5429_device);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -263,68 +232,16 @@ void video_init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t cga32[256];
|
|
||||||
|
|
||||||
BITMAP *buffer,*vbuf;//,*vbuf2;
|
BITMAP *buffer, *buffer32;
|
||||||
BITMAP *buffer32;
|
|
||||||
int speshul=0;
|
|
||||||
|
|
||||||
uint8_t fontdat[256][8];
|
uint8_t fontdat[256][8];
|
||||||
uint8_t fontdatm[256][16];
|
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 xsize=1,ysize=1;
|
||||||
int firstline=1000,lastline=0;
|
|
||||||
|
|
||||||
int ntsc_col[8][8]=
|
|
||||||
{
|
|
||||||
{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*/
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
extern int fullchange;
|
PALETTE cgapal;/* =
|
||||||
|
|
||||||
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,0},{42,0,0},{42,21,0},
|
||||||
{ 0, 0, 0},{0,42,42},{42,0,42},{42,42,42},
|
{ 0, 0, 0},{0,42,42},{42,0,42},{42,42,42},
|
||||||
|
|
@ -345,7 +262,7 @@ PALETTE cgapal=
|
||||||
{0,0,0},{0,42,42},{42,0,0},{42,42,42},
|
{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},
|
||||||
{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)
|
void loadfont(char *s, int format)
|
||||||
{
|
{
|
||||||
|
|
@ -419,45 +336,21 @@ 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()
|
void initvideo()
|
||||||
{
|
{
|
||||||
int c;
|
int c, d, e;
|
||||||
// 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);
|
buffer32 = create_bitmap(2048, 2048);
|
||||||
// set_color_depth(8);
|
|
||||||
buffer = create_bitmap(2048, 2048);
|
buffer = create_bitmap(2048, 2048);
|
||||||
// set_color_depth(32);
|
|
||||||
for (c = 0; c < 64; c++)
|
for (c = 0; c < 64; c++)
|
||||||
{
|
{
|
||||||
cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
|
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].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
|
||||||
cgapal[c + 64].b = (((c & 1) ? 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;
|
if ((c & 0x17) == 6)
|
||||||
|
cgapal[c + 64].g >>= 1;
|
||||||
}
|
}
|
||||||
for (c = 0; c < 64; c++)
|
for (c = 0; c < 64; c++)
|
||||||
{
|
{
|
||||||
|
|
@ -465,56 +358,31 @@ void initvideo()
|
||||||
cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 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;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetvideo()
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
if (MDA && !TANDY && !AMSTRAD && romset!=ROM_PC200) updatewindowsize(720,350);
|
|
||||||
else updatewindowsize(656,416);
|
|
||||||
cgastat=0;
|
|
||||||
set_palette(cgapal);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
cgacol=7;
|
|
||||||
for (c = 0; c < 256; c++)
|
for (c = 0; c < 256; c++)
|
||||||
{
|
{
|
||||||
mdacols[c][0][0]=mdacols[c][1][0]=mdacols[c][1][1]=16;
|
e = c;
|
||||||
if (c&8) mdacols[c][0][1]=15+16;
|
for (d = 0; d < 8; d++)
|
||||||
else mdacols[c][0][1]=7+16;
|
{
|
||||||
|
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()
|
void closevideo()
|
||||||
{
|
{
|
||||||
destroy_bitmap(buffer);
|
destroy_bitmap(buffer);
|
||||||
destroy_bitmap(vbuf);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
115
src/video.h
115
src/video.h
|
|
@ -1,70 +1,8 @@
|
||||||
extern int egareads,egawrites;
|
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 fullchange;
|
||||||
extern int changeframecount;
|
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
|
typedef struct
|
||||||
{
|
{
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
@ -72,73 +10,23 @@ typedef struct
|
||||||
uint8_t *line[0];
|
uint8_t *line[0];
|
||||||
} BITMAP;
|
} BITMAP;
|
||||||
|
|
||||||
extern BITMAP *buffer,*buffer32,*vbuf;
|
extern BITMAP *buffer, *buffer32;
|
||||||
|
|
||||||
extern BITMAP *screen;
|
extern BITMAP *screen;
|
||||||
|
|
||||||
BITMAP *create_bitmap(int w, int h);
|
BITMAP *create_bitmap(int w, int h);
|
||||||
|
|
||||||
extern int wx,wy;
|
|
||||||
|
|
||||||
extern uint8_t fontdat[256][8];
|
extern uint8_t fontdat[256][8];
|
||||||
extern uint8_t fontdatm[256][16];
|
extern uint8_t fontdatm[256][16];
|
||||||
|
|
||||||
|
|
||||||
extern int xsize,ysize;
|
extern int xsize,ysize;
|
||||||
|
|
||||||
extern int dacread,dacwrite,dacpos;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t r, g, b;
|
uint8_t r, g, b;
|
||||||
} RGB;
|
} RGB;
|
||||||
|
|
||||||
typedef RGB PALETTE[256];
|
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;
|
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)(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 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_timing_b, video_timing_w, video_timing_l;
|
||||||
extern int video_speed;
|
extern int video_speed;
|
||||||
|
|
||||||
|
|
|
||||||
20
src/win.c
20
src/win.c
|
|
@ -377,6 +377,9 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadbios();
|
||||||
|
|
||||||
timeBeginPeriod(1);
|
timeBeginPeriod(1);
|
||||||
// soundobject=CreateEvent(NULL, FALSE, FALSE, NULL);
|
// soundobject=CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
// soundthreadh=CreateThread(NULL,0,soundthread,NULL,NULL,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;
|
sound_card_current = temp_sound_card_current;
|
||||||
|
|
||||||
mem_resize();
|
mem_resize();
|
||||||
loadbios();
|
|
||||||
mem_load_video_bios();
|
mem_load_video_bios();
|
||||||
|
loadbios();
|
||||||
resetpchard();
|
resetpchard();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1327,6 +1330,7 @@ BOOL CALLBACK statusdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
||||||
{
|
{
|
||||||
int egasp;
|
int egasp;
|
||||||
char s[256];
|
char s[256];
|
||||||
|
char device_s[4096];
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
case WM_INITDIALOG:
|
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);
|
SendDlgItemMessage(hdlg,IDC_STEXT7,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||||
sprintf(s,"Timer 0 frequency : %fHz",pit_timer0_freq());
|
sprintf(s,"Timer 0 frequency : %fHz",pit_timer0_freq());
|
||||||
SendDlgItemMessage(hdlg,IDC_STEXT8,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
SendDlgItemMessage(hdlg,IDC_STEXT8,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||||
if (chain4) sprintf(s,"VGA chained (possibly mode 13h)");
|
device_add_status_info(device_s, 4096);
|
||||||
else sprintf(s,"VGA unchained (possibly mode-X)");
|
SendDlgItemMessage(hdlg,IDC_STEXT_DEVICE,WM_SETTEXT,(WPARAM)NULL,(LPARAM)device_s);
|
||||||
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);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
switch (LOWORD(wParam))
|
switch (LOWORD(wParam))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue