From 58085bcc877bf46ab0a8d1d56636fd8e1176ea2b Mon Sep 17 00:00:00 2001 From: TomW Date: Mon, 24 Jun 2013 20:42:35 +0100 Subject: [PATCH] Re-organisation of video emulation. --- src/808x.c | 2 + src/device.c | 20 + src/device.h | 6 +- src/dma.c | 11 +- src/ega.c | 269 +------ src/ibm.h | 3 + src/keyboard_amstrad.c | 4 + src/keyboard_olim24.c | 4 + src/pc.c | 9 +- src/pc.rc | 11 +- src/pit.c | 5 +- src/resources.h | 6 +- src/sound_adlib.c | 1 + src/sound_adlibgold.c | 1 + src/sound_cms.c | 1 + src/sound_gus.c | 3 +- src/sound_pas16.c | 1 + src/sound_sb.c | 18 +- src/sound_sb_dsp.c | 6 + src/sound_sn76489.c | 1 + src/sound_wss.c | 1 + src/vid_ati18800.c | 145 ++-- src/vid_ati18800.h | 1 + src/vid_ati28800.c | 158 ++-- src/vid_ati28800.h | 1 + src/vid_ati68860_ramdac.c | 25 +- src/vid_ati68860_ramdac.h | 9 +- src/vid_ati_eeprom.c | 181 +++-- src/vid_ati_eeprom.h | 19 +- src/vid_ati_mach64.c | 1217 ++++++++++++++++-------------- src/vid_ati_mach64.h | 1 + src/vid_cga.c | 577 +++++++------- src/vid_cga.h | 45 +- src/vid_cl5429.c | 772 ++++++++++--------- src/vid_cl5429.h | 1 + src/vid_ega.c | 1040 ++++++++++++++------------ src/vid_ega.h | 78 +- src/vid_et4000.c | 167 +++-- src/vid_et4000.h | 1 + src/vid_et4000w32.c | 1147 ++++++++++++++-------------- src/vid_et4000w32.h | 1 + src/vid_hercules.c | 410 +++++----- src/vid_hercules.h | 1 + src/vid_icd2061.c | 66 +- src/vid_icd2061.h | 16 +- src/vid_ics2595.c | 46 +- src/vid_ics2595.h | 14 +- src/vid_mda.c | 371 +++++---- src/vid_mda.h | 1 + src/vid_olivetti_m24.c | 529 +++++++------ src/vid_olivetti_m24.h | 1 + src/vid_oti067.c | 141 ++-- src/vid_oti067.h | 1 + src/vid_paradise.c | 326 ++++---- src/vid_paradise.h | 2 + src/vid_pc1512.c | 578 +++++++------- src/vid_pc1512.h | 1 + src/vid_pc1640.c | 164 ++-- src/vid_pc1640.h | 1 + src/vid_pc200.c | 145 ++-- src/vid_pc200.h | 1 + src/vid_s3.c | 1493 +++++++++++++++++++------------------ src/vid_s3.h | 2 + src/vid_s3_virge.c | 445 ++++++----- src/vid_s3_virge.h | 1 + src/vid_sdac_ramdac.c | 126 ++-- src/vid_sdac_ramdac.h | 16 +- src/vid_stg_ramdac.c | 123 +-- src/vid_stg_ramdac.h | 12 +- src/vid_svga.c | 1416 +++++++++++++++++++---------------- src/vid_svga.h | 163 ++-- src/vid_svga_render.c | 579 +++++++------- src/vid_svga_render.h | 34 +- src/vid_tandy.c | 787 ++++++++++--------- src/vid_tandy.h | 1 + src/vid_tkd8001_ramdac.c | 34 +- src/vid_tkd8001_ramdac.h | 10 +- src/vid_tvga.c | 823 ++++++++++---------- src/vid_tvga.h | 2 + src/vid_unk_ramdac.c | 39 +- src/vid_unk_ramdac.h | 10 +- src/vid_vga.c | 108 +-- src/vid_vga.h | 1 + src/video.c | 348 +++------ src/video.h | 115 +-- src/win.c | 20 +- 86 files changed, 8175 insertions(+), 7317 deletions(-) create mode 100644 src/vid_ati18800.h create mode 100644 src/vid_ati28800.h create mode 100644 src/vid_ati_mach64.h create mode 100644 src/vid_cl5429.h create mode 100644 src/vid_et4000.h create mode 100644 src/vid_hercules.h create mode 100644 src/vid_mda.h create mode 100644 src/vid_oti067.h create mode 100644 src/vid_paradise.h create mode 100644 src/vid_pc1512.h create mode 100644 src/vid_pc1640.h create mode 100644 src/vid_pc200.h create mode 100644 src/vid_s3.h create mode 100644 src/vid_s3_virge.h create mode 100644 src/vid_tandy.h create mode 100644 src/vid_tvga.h create mode 100644 src/vid_vga.h diff --git a/src/808x.c b/src/808x.c index 0fe7193..87c65c0 100644 --- a/src/808x.c +++ b/src/808x.c @@ -19,6 +19,8 @@ #include "timer.h" #include "x86.h" +int nmi = 0; + int nextcyc=0; int cycdiff; int is8086=0; diff --git a/src/device.c b/src/device.c index 5a97eb0..92a7b7e 100644 --- a/src/device.c +++ b/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; + } + } + } +} diff --git a/src/device.h b/src/device.h index e1605a3..237960d 100644 --- a/src/device.h +++ b/src/device.h @@ -2,11 +2,13 @@ typedef struct device_t { char name[50]; void *(*init)(); - void (*close)(void *priv); - void (*speed_changed)(void *priv); + void (*close)(void *p); + void (*speed_changed)(void *p); + int (*add_status_info)(char *s, int max_len, void *p); } device_t; void device_init(); void device_add(device_t *d); void device_close_all(); void device_speed_changed(); +char *device_add_status_info(char *s, int max_len); diff --git a/src/dma.c b/src/dma.c index 8e4dcb1..766354d 100644 --- a/src/dma.c +++ b/src/dma.c @@ -213,7 +213,7 @@ void dma_page_write(uint16_t addr, uint8_t val, void *priv) { /* if (!(addr&0xF)) {*/ - pclog("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc); +// pclog("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc); // if (val==0x29 && pc==0xD25) output=1; // } dmapages[addr&0xF]=val; @@ -258,12 +258,12 @@ uint8_t _dma_read(uint32_t addr) { switch (addr&0xFFFF8000) { - case 0xA0000: case 0xA8000: +/* case 0xA0000: case 0xA8000: return video_read_a000(addr, NULL); case 0xB0000: return video_read_b000(addr, NULL); case 0xB8000: - return video_read_b800(addr, NULL); + return video_read_b800(addr, NULL);*/ } if (isram[addr>>16]) return ram[addr]; return 0xff; @@ -271,9 +271,10 @@ uint8_t _dma_read(uint32_t addr) void _dma_write(uint32_t addr, uint8_t val) { + pclog("_dma_write %08X %02X\n", addr, val); switch (addr&0xFFFF8000) { - case 0xA0000: case 0xA8000: +/* case 0xA0000: case 0xA8000: video_write_a000(addr,val, NULL); return; case 0xB0000: @@ -284,7 +285,7 @@ void _dma_write(uint32_t addr, uint8_t val) return; case 0xC0000: case 0xC8000: case 0xD0000: case 0xD8000: case 0xE0000: case 0xE8000: case 0xF0000: case 0xF8000: - return; + return;*/ } if (isram[addr >> 16]) ram[addr] = val; diff --git a/src/ega.c b/src/ega.c index a87bc21..2dcca31 100644 --- a/src/ega.c +++ b/src/ega.c @@ -1,217 +1,10 @@ #include "ibm.h" #include "video.h" -void doblit(); - -int egareads=0,egawrites=0; -int framecount=0; -int changeframecount=2; - -void redotextlookup(); -int output; -int svgaon=0; -uint32_t svgarbank,svgawbank; -uint8_t svgaseg,svgaseg2; -uint8_t svga3d8; - -uint8_t oldvram=0; -int frames; -int hsync; -uint8_t cgastat; - -uint8_t gdcreg[16]; -int gdcaddr; -uint8_t attrregs[32]; -int attraddr,attrff=0; -uint8_t ega3c2; - -uint8_t rotatevga[8][256]; -uint8_t writemask,charset; -int writemode,readmode,readplane,chain4; -uint8_t colourcompare,colournocare; -uint8_t la,lb,lc,ld; - -uint8_t *vram; - -int egares; - -uint8_t seqregs[64]; -int seqaddr; - -uint8_t oak_regs[32]; -int oak_index; - - -extern int egaswitchread,egaswitches; -/*For VGA non-interlace colour, ID bits should be 1 1 0 or 6*/ -int vres=0; - -PALETTE vgapal; -uint32_t *pallook,pallook16[256],pallook64[256],pallook256[256]; -int dacread,dacwrite,dacpos=0; -int palchange=1; - -int fullchange; - -int dispontime,dispofftime; -double disptime; - -int ega_vtotal,ega_dispend,ega_vsyncstart,ega_split,ega_hdisp,ega_rowoffset; -int vidclock; -float cpuclock; - -int bpp; - -uint32_t vrammask; - -uint8_t changedvram[(8192*1024)/1024]; - - -int charseta,charsetb; - -int egapal[16]; - -int displine; - -int rowdbl=0; -int scrblank=0; - - - - -uint8_t edatlookup[4][4]; - -uint32_t textlookup[256][2][16][16]; - -/*void redotextlookup() -{ - int c,d,e; - uint32_t temp; - int coffset=(VGA)?0:64; - for (c=0;c<256;c++) - { - for (d=0;d<16;d++) - { -// printf("ATTR %i=%02X+%02X\n",d,attrregs[d],coffset); - for (e=0;e<16;e++) - { - temp=0; - if (c&0x80) temp|=(attrregs[d]+coffset); - else temp|=(attrregs[e]+coffset); - if (c&0x40) temp|=(attrregs[d]+coffset)<<8; - else temp|=(attrregs[e]+coffset)<<8; - if (c&0x20) temp|=(attrregs[d]+coffset)<<16; - else temp|=(attrregs[e]+coffset)<<16; - if (c&0x10) temp|=(attrregs[d]+coffset)<<24; - else temp|=(attrregs[e]+coffset)<<24; -// if (c==0x5) printf("%08X %i %i %02X %02X\n",temp,d,e,attrregs[d],attrregs[e]); - textlookup[c][0][d][e]=temp; - temp=0; - if (c&0x08) temp|=(attrregs[d]+coffset); - else temp|=(attrregs[e]+coffset); - if (c&0x04) temp|=(attrregs[d]+coffset)<<8; - else temp|=(attrregs[e]+coffset)<<8; - if (c&0x02) temp|=(attrregs[d]+coffset)<<16; - else temp|=(attrregs[e]+coffset)<<16; - if (c&0x01) temp|=(attrregs[d]+coffset)<<24; - else temp|=(attrregs[e]+coffset)<<24; - textlookup[c][1][d][e]=temp; - } - } - } -}*/ - -void initega() -{ - int c,d,e; - bpp=8; - for (c=0;c<256;c++) - { - e=c; - for (d=0;d<8;d++) - { - rotatevga[d][c]=e; - e=(e>>1)|((e&1)?0x80:0); - } - } - crtc[0xC]=crtc[0xD]=0; - for (c=0;c<4;c++) - { - for (d=0;d<4;d++) - { - edatlookup[c][d]=0; - if (c&1) edatlookup[c][d]|=1; - if (d&1) edatlookup[c][d]|=2; - if (c&2) edatlookup[c][d]|=0x10; - if (d&2) edatlookup[c][d]|=0x20; -// printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]); - } - } - /*redotextlookup();*/ - for (c=0;c<256;c++) - { - pallook64[c]=makecol32(((c>>2)&1)*0xAA,((c>>1)&1)*0xAA,(c&1)*0xAA); - pallook64[c]+=makecol32(((c>>5)&1)*0x55,((c>>4)&1)*0x55,((c>>3)&1)*0x55); - pallook16[c]=makecol32(((c>>2)&1)*0xAA,((c>>1)&1)*0xAA,(c&1)*0xAA); - pallook16[c]+=makecol32(((c>>4)&1)*0x55,((c>>4)&1)*0x55,((c>>4)&1)*0x55); - if ((c&0x17)==6) pallook16[c]=makecol32(0xAA,0x55,0); -// printf("%03i %08X\n",c,pallook[c]); - } - pallook=pallook16; - seqregs[0xC]=0x20; - vrammask=(ET4000)?0xFFFFF:0x1FFFFF; -// writeega_func=writeega; - gdcreg[6]=8; - gdcreg[8]=0xFF; - writemode=0; - chain4=0; - writemask=3; - - et4k_b8000=0; - - svgarbank=svgawbank=0; -} -uint32_t egabase,egaoffset; - -void cacheega() -{ - egabase=(crtc[0xC]<<8)|crtc[0xD]; - if (ET4000 || ET4000W32 || TRIDENT) - egabase|=((crtc[0x33]&3)<<18); -// printf("EGABASE %05X\n",egabase); -// egaoffset=8-((attrregs[0x13])&7); -// printf("Cache base!\n"); -} -void cacheega2() -{ -// egabase=(crtc[0xC]<<8)|crtc[0xD]; - if (gdcreg[5]&0x40) egaoffset=8-(((attrregs[0x13])&7)>>1); - else egaoffset=8-((attrregs[0x13])&7); -// printf("Cache offset!\n"); -} - -int olddisplines,oldxsize; - -int oldreadflash; -int oldegaaddr,oldegasplit; - -int vc,sc; -int egadispon=0; -int linepos; -int displine; -uint32_t ma,maback,ca; -int firstline,lastline; -int xsize,ysize; -int scrollcache; -int con,cursoron,cgablink; - -BITMAP *buffer,*vbuf,*buffer32; - -int linecountff=0; void dumpegaregs() { - int c; +/* int c; printf("CRTC :"); for (c=0;c<0x20;c++) printf(" %02X",crtc[c]); printf("\n"); @@ -234,64 +27,6 @@ void dumpegaregs() for (c=0;c<0x10;c++) printf(" %02X",gdcreg[c]); printf("\n"); // printf("OLD CTRL2 = %02X NEW CTRL2 = %02X DAC = %02X 3C2 = %02X\n",tridentoldctrl2,tridentnewctrl2,tridentdac,ega3c2); - printf("BPP = %02X\n",bpp); + printf("BPP = %02X\n",bpp);*/ } -int oddeven; - -int wx,wy; -int vslines; - -int frames = 0; - -void doblit() -{ - startblit(); - if ((wx!=xsize || wy!=ysize) && !vid_resize) - { - xsize=wx; - ysize=wy+1; - if (xsize<64) xsize=656; - if (ysize<32) ysize=200; - if (vres) updatewindowsize(xsize,ysize<<1); - else updatewindowsize(xsize,ysize); - } - video_blit_memtoscreen(32, 0, 0, ysize, xsize, ysize); - if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF); - endblit(); - frames++; -} - -int ega_getdepth() -{ - if (!(gdcreg[6]&1)) return 0; - switch (gdcreg[5]&0x60) - { - case 0x00: - return 4; - case 0x20: - return 2; - case 0x40: case 0x60: - if (TRIDENT || ET4000W32) return bpp; - return 8; - } - return 0; -} - -int ega_getx() -{ - int x; - if (!(gdcreg[6]&1)) return (crtc[1]+1); - if ((attrregs[0x10]&0x40) && !(tridentoldctrl2&0x10)) x=(crtc[1]+1)*4; - else x=(crtc[1]+1)*8; - if (TRIDENT && (bpp==15 || bpp==16)) x>>=1; - if (TRIDENT && bpp==24) x=(x<<1)/3; - return x; -} - -int ega_gety() -{ - if (crtc[0x1E]&4) return (ega_dispend/((crtc[9]&31)+1))<<1; - if (crtc[9]&0x80) return (ega_dispend/((crtc[9]&31)+1))>>1; - return ega_dispend/((crtc[9]&31)+1); -} diff --git a/src/ibm.h b/src/ibm.h index 889ddd7..164e7a4 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -458,3 +458,6 @@ extern int times; extern float isa_timing, bus_timing; extern int frame; + + +uint8_t *vramp; diff --git a/src/keyboard_amstrad.c b/src/keyboard_amstrad.c index 903de83..62f6193 100644 --- a/src/keyboard_amstrad.c +++ b/src/keyboard_amstrad.c @@ -3,6 +3,7 @@ #include "mem.h" #include "pic.h" #include "sound.h" +#include "timer.h" #include "keyboard.h" #include "keyboard_amstrad.h" @@ -31,6 +32,7 @@ static uint8_t amstrad_systemstat_1, amstrad_systemstat_2; void keyboard_amstrad_poll() { + keybsenddelay += (1000 * TIMER_USEC); if (keyboard_amstrad.wantirq) { keyboard_amstrad.wantirq = 0; @@ -166,4 +168,6 @@ void keyboard_amstrad_init() keyboard_amstrad_reset(); keyboard_send = keyboard_amstrad_adddata; keyboard_poll = keyboard_amstrad_poll; + + timer_add(keyboard_amstrad_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); } diff --git a/src/keyboard_olim24.c b/src/keyboard_olim24.c index da42395..141be39 100644 --- a/src/keyboard_olim24.c +++ b/src/keyboard_olim24.c @@ -3,6 +3,7 @@ #include "mem.h" #include "mouse.h" #include "pic.h" +#include "timer.h" #include "keyboard.h" #include "keyboard_olim24.h" @@ -38,6 +39,7 @@ static uint8_t mouse_scancodes[7]; void keyboard_olim24_poll() { + keybsenddelay += (1000 * TIMER_USEC); //pclog("poll %i\n", keyboard_olim24.wantirq); if (keyboard_olim24.wantirq) { @@ -283,4 +285,6 @@ void keyboard_olim24_init() keyboard_send = keyboard_olim24_adddata; keyboard_poll = keyboard_olim24_poll; mouse_poll = mouse_olim24_poll; + + timer_add(keyboard_olim24_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); } diff --git a/src/pc.c b/src/pc.c index b8d090b..398efeb 100644 --- a/src/pc.c +++ b/src/pc.c @@ -179,8 +179,6 @@ void pc_reset() // sb_reset(); ali1429_reset(); - et4000w32_reset(); - // video_init(); } @@ -209,8 +207,8 @@ void initpc() initvideo(); mem_init(); - loadbios(); mem_load_video_bios(); + loadbios(); loaddisc(0,discfns[0]); loaddisc(1,discfns[1]); @@ -221,10 +219,8 @@ void initpc() //loadfont(); loadnvr(); - resetvideo(); sound_init(); inithdc(); - initega(); resetide(); ioctl_open(cdrom_drive); model_init(); @@ -244,7 +240,6 @@ void initpc() /* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed(); mem_updatecache(); ali1429_reset(); - et4000w32_reset(); // CPUID=(is486 && (cpuspeed==7 || cpuspeed>=9)); // pclog("Init - CPUID %i %i\n",CPUID,cpuspeed); shadowbios=0; @@ -330,6 +325,7 @@ void runpc() framecount++; if (framecountx>=100) { + pclog("onesec\n"); framecountx=0; mips=(float)insc/1000000.0f; insc=0; @@ -404,7 +400,6 @@ void closepc() { atapi->exit(); // ioctl_close(); - dumpegaregs(); dumppic(); // output=7; // setpitclock(clocks[0][0][0]); diff --git a/src/pc.rc b/src/pc.rc index a0ef5ad..a750147 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -50,8 +50,9 @@ BEGIN COMBOBOX IDC_COMBOSPD,62,116,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBOSND,62,136,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBOMEM,62,152,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - CONTROL "Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,172,118,10 - CONTROL "Composite CGA",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,188,118,10 + CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,172,118,10 + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,188,118,10 + CONTROL "Composite CGA",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,204,118,10 LTEXT "Machine :",IDC_STATIC,15,16,40,10 LTEXT "Video :",IDC_STATIC,15,36,34,10 LTEXT "CPU type :",IDC_STATIC,15,56,34,10 @@ -150,9 +151,5 @@ BEGIN LTEXT "6",IDC_STEXT6,16,76,180,10 LTEXT "7",IDC_STEXT7,16,88,180,10 LTEXT "8",IDC_STEXT8,16,100,180,10 - LTEXT "9",IDC_STEXT9,16,112,180,10 - LTEXT "10",IDC_STEXT10,16,124,180,10 - LTEXT "11",IDC_STEXT11,16,136,180,10 - LTEXT "12",IDC_STEXT12,16,148,180,10 - LTEXT "13",IDC_STEXT13,16,160,180,10 + LTEXT "9",IDC_STEXT_DEVICE,16,112,180,1000 END diff --git a/src/pit.c b/src/pit.c index fffe488..595d187 100644 --- a/src/pit.c +++ b/src/pit.c @@ -31,14 +31,15 @@ void setpitclock(float clock) cpuclock=clock; PITCONST=clock/1193182.0; CGACONST=(clock/(19687500.0/11.0)); - MDACONST=(clock/1813000.0); + MDACONST=(clock/2032125.0); VGACONST1=(clock/25175000.0); VGACONST2=(clock/28322000.0); isa_timing = clock/8000000.0; bus_timing = clock/(double)cpu_busspeed; video_updatetiming(); // pclog("egacycles %i egacycles2 %i temp %f clock %f\n",egacycles,egacycles2,temp,clock); - video_recalctimings(); +/* if (video_recalctimings) + video_recalctimings();*/ RTCCONST=clock/32768.0; TIMER_USEC = (int)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT)); device_speed_changed(); diff --git a/src/resources.h b/src/resources.h index 740c950..4e0ca43 100644 --- a/src/resources.h +++ b/src/resources.h @@ -56,8 +56,4 @@ #define IDC_STEXT6 1105 #define IDC_STEXT7 1106 #define IDC_STEXT8 1107 -#define IDC_STEXT9 1108 -#define IDC_STEXT10 1109 -#define IDC_STEXT11 1110 -#define IDC_STEXT12 1111 -#define IDC_STEXT13 1112 +#define IDC_STEXT_DEVICE 1108 diff --git a/src/sound_adlib.c b/src/sound_adlib.c index cf383f1..f55f7b0 100644 --- a/src/sound_adlib.c +++ b/src/sound_adlib.c @@ -58,5 +58,6 @@ device_t adlib_device = "AdLib", adlib_init, adlib_close, + NULL, NULL }; diff --git a/src/sound_adlibgold.c b/src/sound_adlibgold.c index 17e646b..880def8 100644 --- a/src/sound_adlibgold.c +++ b/src/sound_adlibgold.c @@ -593,5 +593,6 @@ device_t adgold_device = "AdLib Gold", adgold_init, adgold_close, + NULL, NULL }; diff --git a/src/sound_cms.c b/src/sound_cms.c index 59a0a30..1019eb6 100644 --- a/src/sound_cms.c +++ b/src/sound_cms.c @@ -175,5 +175,6 @@ device_t cms_device = "Creative Music System / Game Blaster", cms_init, cms_close, + NULL, NULL }; diff --git a/src/sound_gus.c b/src/sound_gus.c index b27f6c6..cd784af 100644 --- a/src/sound_gus.c +++ b/src/sound_gus.c @@ -1103,5 +1103,6 @@ device_t gus_device = "Gravis UltraSound", gus_init, gus_close, - gus_speed_changed + gus_speed_changed, + NULL }; diff --git a/src/sound_pas16.c b/src/sound_pas16.c index 5b5b412..ccf350d 100644 --- a/src/sound_pas16.c +++ b/src/sound_pas16.c @@ -749,5 +749,6 @@ device_t pas16_device = "Pro Audio Spectrum 16", pas16_init, pas16_close, + NULL, NULL }; diff --git a/src/sound_sb.c b/src/sound_sb.c index ec5625f..f2e9449 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -376,40 +376,46 @@ device_t sb_1_device = "Sound Blaster v1.0", sb_1_init, sb_close, - sb_speed_changed + sb_speed_changed, + NULL }; device_t sb_15_device = { "Sound Blaster v1.5", sb_15_init, sb_close, - sb_speed_changed + sb_speed_changed, + NULL }; device_t sb_2_device = { "Sound Blaster v2.0", sb_2_init, sb_close, - sb_speed_changed + sb_speed_changed, + NULL }; device_t sb_pro_v1_device = { "Sound Blaster Pro v1", sb_pro_v1_init, sb_close, - sb_speed_changed + sb_speed_changed, + NULL }; device_t sb_pro_v2_device = { "Sound Blaster Pro v2", sb_pro_v2_init, sb_close, - sb_speed_changed + sb_speed_changed, + NULL }; device_t sb_16_device = { "Sound Blaster 16", sb_16_init, sb_close, - sb_speed_changed + sb_speed_changed, + NULL }; diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 05b657a..7f63e6e 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -272,6 +272,12 @@ void sb_exec_command(sb_dsp_t *dsp) pclog("sb_exec_command : SB command %02X\n", dsp->sb_command); switch (dsp->sb_command) { + case 0x01: /*???*/ + sb_add_data(dsp, 0); + break; + case 0x03: /*ASP status*/ + sb_add_data(dsp, 0); + break; case 0x10: /*8-bit direct mode*/ dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8; break; diff --git a/src/sound_sn76489.c b/src/sound_sn76489.c index 88094bb..75f40ff 100644 --- a/src/sound_sn76489.c +++ b/src/sound_sn76489.c @@ -194,5 +194,6 @@ device_t sn76489_device = "TI SN74689 PSG", sn76489_init, sn76489_close, + NULL, NULL }; diff --git a/src/sound_wss.c b/src/sound_wss.c index 0fbf5bb..7aec4ac 100644 --- a/src/sound_wss.c +++ b/src/sound_wss.c @@ -303,5 +303,6 @@ device_t wss_device = "Windows Sound System", wss_init, wss_close, + NULL, NULL }; diff --git a/src/vid_ati18800.c b/src/vid_ati18800.c index 762a084..a4e8051 100644 --- a/src/vid_ati18800.c +++ b/src/vid_ati18800.c @@ -1,142 +1,163 @@ /*ATI 18800 emulation (VGA Edge-16)*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "video.h" +#include "vid_ati18800.h" #include "vid_ati_eeprom.h" #include "vid_svga.h" -static uint8_t ati_regs[256]; -static int ati_index; - -void ati18800_out(uint16_t addr, uint8_t val, void *priv) +typedef struct ati18800_t { + svga_t svga; + ati_eeprom_t eeprom; + + uint8_t regs[256]; + int index; +} ati18800_t; + +void ati18800_out(uint16_t addr, uint8_t val, void *p) +{ + ati18800_t *ati18800 = (ati18800_t *)p; + svga_t *svga = &ati18800->svga; uint8_t old; pclog("ati18800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; switch (addr) { case 0x1ce: - ati_index = val; + ati18800->index = val; break; case 0x1cf: - ati_regs[ati_index] = val; - switch (ati_index) + ati18800->regs[ati18800->index] = val; + switch (ati18800->index) { case 0xb2: case 0xbe: - if (ati_regs[0xbe] & 8) /*Read/write bank mode*/ + if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/ { - svgarbank = ((ati_regs[0xb2] >> 5) & 7) * 0x10000; - svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000; + svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000; + svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; } else /*Single bank mode*/ - svgarbank = svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000; + svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; break; case 0xb3: - ati_eeprom_write(val & 8, val & 2, val & 1); + ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1); break; } break; case 0x3D4: - crtcreg = val & 0x3f; + svga->crtcreg = val & 0x3f; return; case 0x3D5: - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; - if (old!=val) + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(svga); } } break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t ati18800_in(uint16_t addr, void *priv) +uint8_t ati18800_in(uint16_t addr, void *p) { + ati18800_t *ati18800 = (ati18800_t *)p; + svga_t *svga = &ati18800->svga; uint8_t temp; if (addr != 0x3da) pclog("ati18800_in : %04X ", addr); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; switch (addr) { case 0x1ce: - temp = ati_index; + temp = ati18800->index; break; case 0x1cf: - switch (ati_index) + switch (ati18800->index) { case 0xb7: - temp = ati_regs[ati_index] & ~8; - if (ati_eeprom_read()) + temp = ati18800->regs[ati18800->index] & ~8; + if (ati_eeprom_read(&ati18800->eeprom)) temp |= 8; break; default: - temp = ati_regs[ati_index]; + temp = ati18800->regs[ati18800->index]; break; } break; case 0x3D4: - temp = crtcreg; + temp = svga->crtcreg; break; case 0x3D5: - temp = crtc[crtcreg]; + temp = svga->crtc[svga->crtcreg]; break; default: - temp = svga_in(addr, NULL); + temp = svga_in(addr, svga); break; } if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); return temp; } -int ati18800_init() +void *ati18800_init() { - svga_recalctimings_ex = NULL; - svga_vram_limit = 1 << 19; /*512kb*/ - vrammask = 0x7ffff; - svgawbank = svgarbank = 0; - bpp = 8; - svga_miscout = 1; + ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); + memset(ati18800, 0, sizeof(ati18800_t)); - io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, NULL); - - ati_eeprom_load("ati18800.nvr", 0); - - return svga_init(); + svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/ + NULL, + ati18800_in, ati18800_out, + NULL); + + io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + + ati18800->svga.miscout = 1; + + ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); + + return ati18800; } -GFXCARD vid_ati18800 = +void ati18800_close(void *p) { + ati18800_t *ati18800 = (ati18800_t *)p; + + svga_close(&ati18800->svga); + + free(ati18800); +} + +void ati18800_speed_changed(void *p) +{ + ati18800_t *ati18800 = (ati18800_t *)p; + + svga_recalctimings(&ati18800->svga); +} + +device_t ati18800_device = +{ + "ATI-18800", ati18800_init, - /*IO at 3Cx/3Dx*/ - ati18800_out, - ati18800_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - svga_poll, - svga_recalctimings, - - svga_write, - video_write_null, - video_write_null, - - svga_read, - video_read_null, - video_read_null + ati18800_close, + ati18800_speed_changed, + svga_add_status_info }; + diff --git a/src/vid_ati18800.h b/src/vid_ati18800.h new file mode 100644 index 0000000..83fe2c0 --- /dev/null +++ b/src/vid_ati18800.h @@ -0,0 +1 @@ +extern device_t ati18800_device; diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 5c89795..9a663db 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -1,161 +1,183 @@ /*ATI 28800 emulation (VGA Charger)*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "video.h" +#include "vid_ati28800.h" #include "vid_ati_eeprom.h" #include "vid_svga.h" #include "vid_svga_render.h" -static uint8_t ati_regs[256]; -static int ati_index; - -void ati28800_out(uint16_t addr, uint8_t val, void *priv) +typedef struct ati28800_t { + svga_t svga; + ati_eeprom_t eeprom; + + uint8_t regs[256]; + int index; +} ati28800_t; + +void ati28800_out(uint16_t addr, uint8_t val, void *p) +{ + ati28800_t *ati28800 = (ati28800_t *)p; + svga_t *svga = &ati28800->svga; uint8_t old; pclog("ati28800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) + addr ^= 0x60; switch (addr) { case 0x1ce: - ati_index = val; + ati28800->index = val; break; case 0x1cf: - ati_regs[ati_index] = val; - switch (ati_index) + ati28800->regs[ati28800->index] = val; + switch (ati28800->index) { case 0xb2: case 0xbe: - if (ati_regs[0xbe] & 8) /*Read/write bank mode*/ + if (ati28800->regs[0xbe] & 8) /*Read/write bank mode*/ { - svgarbank = ((ati_regs[0xb2] >> 5) & 7) * 0x10000; - svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000; + svga->read_bank = ((ati28800->regs[0xb2] >> 5) & 7) * 0x10000; + svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; } else /*Single bank mode*/ - svgarbank = svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000; + svga->read_bank = svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; break; case 0xb3: - ati_eeprom_write(val & 8, val & 2, val & 1); + ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1); break; } break; case 0x3D4: - crtcreg = val & 0x3f; + svga->crtcreg = val & 0x3f; return; case 0x3D5: - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; - if (old!=val) + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(svga); } } break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t ati28800_in(uint16_t addr, void *priv) +uint8_t ati28800_in(uint16_t addr, void *p) { + ati28800_t *ati28800 = (ati28800_t *)p; + svga_t *svga = &ati28800->svga; uint8_t temp; if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; switch (addr) { case 0x1ce: - temp = ati_index; + temp = ati28800->index; break; case 0x1cf: - switch (ati_index) + switch (ati28800->index) { case 0xb7: - temp = ati_regs[ati_index] & ~8; - if (ati_eeprom_read()) + temp = ati28800->regs[ati28800->index] & ~8; + if (ati_eeprom_read(&ati28800->eeprom)) temp |= 8; break; default: - temp = ati_regs[ati_index]; + temp = ati28800->regs[ati28800->index]; break; } break; case 0x3c2: - if ((vgapal[0].r + vgapal[0].g + vgapal[0].b) >= 0x50) + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) temp = 0; else temp = 0x10; break; case 0x3D4: - temp = crtcreg; + temp = svga->crtcreg; break; case 0x3D5: - temp = crtc[crtcreg]; + temp = svga->crtc[svga->crtcreg]; break; default: - temp = svga_in(addr, NULL); + temp = svga_in(addr, svga); break; } if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); return temp; } -void ati28800_recalctimings() +void ati28800_recalctimings(svga_t *svga) { + ati28800_t *ati28800 = (ati28800_t *)svga->p; pclog("ati28800_recalctimings\n"); - if (!scrblank && (ati_regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ + if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ { pclog("8bpp_highres\n"); - svga_render = svga_render_8bpp_highres; - svga_rowoffset <<= 1; - svga_ma <<= 1; + svga->render = svga_render_8bpp_highres; + svga->rowoffset <<= 1; + svga->ma <<= 1; } } -int ati28800_init() +void *ati28800_init() { - svga_recalctimings_ex = ati28800_recalctimings; - svga_vram_limit = 1 << 19; /*512kb*/ - vrammask = 0x7ffff; - svgawbank = svgarbank = 0; - bpp = 8; - svga_miscout = 1; + ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); + memset(ati28800, 0, sizeof(ati28800_t)); - io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, NULL); - - ati_eeprom_load("ati28800.nvr", 0); - - return svga_init(); + svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ + ati28800_recalctimings, + ati28800_in, ati28800_out, + NULL); + + io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, ati28800); + io_sethandler(0x03c0, 0x0020, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, ati28800); + + ati28800->svga.miscout = 1; + + ati_eeprom_load(&ati28800->eeprom, "ati28800.nvr", 0); + + return ati28800; } -GFXCARD vid_ati28800 = +void ati28800_close(void *p) { + ati28800_t *ati28800 = (ati28800_t *)p; + + svga_close(&ati28800->svga); + + free(ati28800); +} + +void ati28800_speed_changed(void *p) +{ + ati28800_t *ati28800 = (ati28800_t *)p; + + svga_recalctimings(&ati28800->svga); +} + +device_t ati28800_device = +{ + "ATI-28800", ati28800_init, - /*IO at 3Cx/3Dx*/ - ati28800_out, - ati28800_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - svga_poll, - svga_recalctimings, - - svga_write, - video_write_null, - video_write_null, - - svga_read, - video_read_null, - video_read_null + ati28800_close, + ati28800_speed_changed, + svga_add_status_info }; diff --git a/src/vid_ati28800.h b/src/vid_ati28800.h new file mode 100644 index 0000000..6cb3617 --- /dev/null +++ b/src/vid_ati28800.h @@ -0,0 +1 @@ +extern device_t ati28800_device; diff --git a/src/vid_ati68860_ramdac.c b/src/vid_ati68860_ramdac.c index 7dae246..448756f 100644 --- a/src/vid_ati68860_ramdac.c +++ b/src/vid_ati68860_ramdac.c @@ -23,46 +23,45 @@ bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT #include "vid_svga.h" #include "vid_ati68860_ramdac.h" -static uint8_t ramdac_regs[16]; -void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv) +void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga) { // pclog("ati68860_out : addr %04X val %02X %04X:%04X\n", addr, val, CS,pc); switch (addr) { case 0: - svga_out(0x3c8, val, NULL); + svga_out(0x3c8, val, svga); break; case 1: - svga_out(0x3c9, val, NULL); + svga_out(0x3c9, val, svga); break; case 2: - svga_out(0x3c6, val, NULL); + svga_out(0x3c6, val, svga); break; case 3: - svga_out(0x3c7, val, NULL); + svga_out(0x3c7, val, svga); break; default: - ramdac_regs[addr & 0xf] = val; + ramdac->regs[addr & 0xf] = val; break; } } -uint8_t ati68860_ramdac_in(uint16_t addr, void *priv) +uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga) { uint8_t ret = 0; switch (addr) { case 0: - ret = svga_in(0x3c8, NULL); + ret = svga_in(0x3c8, svga); break; case 1: - ret = svga_in(0x3c9, NULL); + ret = svga_in(0x3c9, svga); break; case 2: - ret = svga_in(0x3c6, NULL); + ret = svga_in(0x3c6, svga); break; case 3: - ret = svga_in(0x3c7, NULL); + ret = svga_in(0x3c7, svga); break; case 4: case 8: ret = 2; @@ -75,7 +74,7 @@ uint8_t ati68860_ramdac_in(uint16_t addr, void *priv) break; default: - ret = ramdac_regs[addr & 0xf]; + ret = ramdac->regs[addr & 0xf]; break; } // pclog("ati68860_in : addr %04X ret %02X %04X:%04X\n", addr, ret, CS,pc); diff --git a/src/vid_ati68860_ramdac.h b/src/vid_ati68860_ramdac.h index 1dc2bc4..7f00e36 100644 --- a/src/vid_ati68860_ramdac.h +++ b/src/vid_ati68860_ramdac.h @@ -1,2 +1,7 @@ -void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv); -uint8_t ati68860_ramdac_in(uint16_t addr, void *priv); +typedef struct ati68860_ramdac_t +{ + uint8_t regs[16]; +} ati68860_ramdac_t; + +void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga); +uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga); diff --git a/src/vid_ati_eeprom.c b/src/vid_ati_eeprom.c index 5e1dba7..77fff76 100644 --- a/src/vid_ati_eeprom.c +++ b/src/vid_ati_eeprom.c @@ -1,7 +1,6 @@ #include "ibm.h" #include "vid_ati_eeprom.h" -static uint16_t eeprom[256]; enum { EEPROM_IDLE, @@ -29,201 +28,193 @@ enum EEPROM_OP_EWEN = 3 }; -static int oldclk, oldena; -static int eeprom_opcode, eeprom_state, eeprom_count, eeprom_out; -static int eeprom_wp; -static uint32_t eeprom_dat; -static int eeprom_type; - -static char eeprom_fn[256] = {0}; - -void ati_eeprom_load(char *fn, int type) +void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) { FILE *f; - eeprom_type = type; - strcpy(eeprom_fn, fn); - f = romfopen(eeprom_fn, "rb"); + eeprom->type = type; + strcpy(eeprom->fn, fn); + f = romfopen(eeprom->fn, "rb"); if (!f) { - memset(eeprom, 0, type ? 512 : 128); + memset(eeprom->data, 0, eeprom->type ? 512 : 128); return; } - fread(eeprom, 1, type ? 512 : 128, f); + fread(eeprom->data, 1, eeprom->type ? 512 : 128, f); fclose(f); } -void ati_eeprom_save() +void ati_eeprom_save(ati_eeprom_t *eeprom) { - FILE *f = romfopen(eeprom_fn, "wb"); + FILE *f = romfopen(eeprom->fn, "wb"); if (!f) return; - fwrite(eeprom, 1, eeprom_type ? 512 : 128, f); + fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f); fclose(f); } -void ati_eeprom_write(int ena, int clk, int dat) +void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) { int c; pclog("EEPROM write %i %i %i\n", ena, clk, dat); if (!ena) { - eeprom_out = 1; + eeprom->out = 1; } - if (clk && !oldclk) + if (clk && !eeprom->oldclk) { - if (ena && !oldena) + if (ena && !eeprom->oldena) { - eeprom_state = EEPROM_WAIT; - eeprom_opcode = 0; - eeprom_count = 3; - eeprom_out = 1; + eeprom->state = EEPROM_WAIT; + eeprom->opcode = 0; + eeprom->count = 3; + eeprom->out = 1; } else if (ena) { pclog("EEPROM receive %i %i %i\n", ena, clk, dat); - switch (eeprom_state) + switch (eeprom->state) { case EEPROM_WAIT: if (!dat) break; - eeprom_state = EEPROM_OPCODE; + eeprom->state = EEPROM_OPCODE; /* fall through */ case EEPROM_OPCODE: - eeprom_opcode = (eeprom_opcode << 1) | (dat ? 1 : 0); - eeprom_count--; - if (!eeprom_count) + eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0); + eeprom->count--; + if (!eeprom->count) { - pclog("EEPROM opcode - %i\n", eeprom_opcode); - switch (eeprom_opcode) + pclog("EEPROM opcode - %i\n", eeprom->opcode); + switch (eeprom->opcode) { case EEPROM_OP_WRITE: - eeprom_count = eeprom_type ? 24 : 22; - eeprom_state = EEPROM_INPUT; - eeprom_dat = 0; + eeprom->count = eeprom->type ? 24 : 22; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; break; case EEPROM_OP_READ: - eeprom_count = eeprom_type ? 8 : 6; - eeprom_state = EEPROM_INPUT; - eeprom_dat = 0; + eeprom->count = eeprom->type ? 8 : 6; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; break; case EEPROM_OP_EW: - eeprom_count = 2; - eeprom_state = EEPROM_INPUT; - eeprom_dat = 0; + eeprom->count = 2; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; break; case EEPROM_OP_ERASE: - eeprom_count = eeprom_type ? 8 : 6; - eeprom_state = EEPROM_INPUT; - eeprom_dat = 0; + eeprom->count = eeprom->type ? 8 : 6; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; break; } } break; case EEPROM_INPUT: - eeprom_dat = (eeprom_dat << 1) | (dat ? 1 : 0); - eeprom_count--; - if (!eeprom_count) + eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0); + eeprom->count--; + if (!eeprom->count) { - pclog("EEPROM dat - %02X\n", eeprom_dat); - switch (eeprom_opcode) + pclog("EEPROM dat - %02X\n", eeprom->dat); + switch (eeprom->opcode) { case EEPROM_OP_WRITE: - pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom_dat >> 16) & (eeprom_type ? 255 : 63), eeprom_dat & 0xffff); - if (!eeprom_wp) + pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom->dat >> 16) & (eeprom->type ? 255 : 63), eeprom->dat & 0xffff); + if (!eeprom->wp) { - eeprom[(eeprom_dat >> 16) & (eeprom_type ? 255 : 63)] = eeprom_dat & 0xffff; - ati_eeprom_save(); + eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff; + ati_eeprom_save(eeprom); } - eeprom_state = EEPROM_IDLE; - eeprom_out = 1; + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; break; case EEPROM_OP_READ: - eeprom_count = 17; - eeprom_state = EEPROM_OUTPUT; - eeprom_dat = eeprom[eeprom_dat]; - pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom_dat); + eeprom->count = 17; + eeprom->state = EEPROM_OUTPUT; + eeprom->dat = eeprom->data[eeprom->dat]; + pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom->dat); break; case EEPROM_OP_EW: - pclog("EEPROM_OP_EW %i\n", eeprom_dat); - switch (eeprom_dat) + pclog("EEPROM_OP_EW %i\n", eeprom->dat); + switch (eeprom->dat) { case EEPROM_OP_EWDS: - eeprom_wp = 1; + eeprom->wp = 1; break; case EEPROM_OP_WRAL: - opcode = EEPROM_OP_WRALMAIN; - eeprom_count = 20; + eeprom->opcode = EEPROM_OP_WRALMAIN; + eeprom->count = 20; break; case EEPROM_OP_ERAL: - if (!eeprom_wp) + if (!eeprom->wp) { - memset(eeprom, 0xff, 128); - ati_eeprom_save(); + memset(eeprom->data, 0xff, 128); + ati_eeprom_save(eeprom); } break; case EEPROM_OP_EWEN: - eeprom_wp = 0; + eeprom->wp = 0; break; } - eeprom_state = EEPROM_IDLE; - eeprom_out = 1; + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; break; case EEPROM_OP_ERASE: - pclog("EEPROM_OP_ERASE %i\n", eeprom_dat); - if (!eeprom_wp) + pclog("EEPROM_OP_ERASE %i\n", eeprom->dat); + if (!eeprom->wp) { - eeprom[eeprom_dat] = 0xffff; - ati_eeprom_save(); + eeprom->data[eeprom->dat] = 0xffff; + ati_eeprom_save(eeprom); } - eeprom_state = EEPROM_IDLE; - eeprom_out = 1; + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; break; case EEPROM_OP_WRALMAIN: - pclog("EEPROM_OP_WRAL %04X\n", eeprom_dat); - if (!eeprom_wp) + pclog("EEPROM_OP_WRAL %04X\n", eeprom->dat); + if (!eeprom->wp) { for (c = 0; c < 256; c++) - eeprom[c] = eeprom_dat; - ati_eeprom_save(); + eeprom->data[c] = eeprom->dat; + ati_eeprom_save(eeprom); } - eeprom_state = EEPROM_IDLE; - eeprom_out = 1; + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; break; } } break; } } - oldena = ena; + eeprom->oldena = ena; } - else if (!clk && oldclk) + else if (!clk && eeprom->oldclk) { if (ena) { - switch (eeprom_state) + switch (eeprom->state) { case EEPROM_OUTPUT: - eeprom_out = (eeprom_dat & 0x10000) ? 1 : 0; - eeprom_dat <<= 1; - pclog("EEPROM_OUTPUT - data %i\n", eeprom_out); - eeprom_count--; - if (!eeprom_count) + eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0; + eeprom->dat <<= 1; + pclog("EEPROM_OUTPUT - data %i\n", eeprom->out); + eeprom->count--; + if (!eeprom->count) { pclog("EEPROM_OUTPUT complete\n"); - eeprom_state = EEPROM_IDLE; + eeprom->state = EEPROM_IDLE; } break; } } } - oldclk = clk; + eeprom->oldclk = clk; } -int ati_eeprom_read() +int ati_eeprom_read(ati_eeprom_t *eeprom) { - return eeprom_out; + return eeprom->out; } diff --git a/src/vid_ati_eeprom.h b/src/vid_ati_eeprom.h index f886ad0..e69c2d7 100644 --- a/src/vid_ati_eeprom.h +++ b/src/vid_ati_eeprom.h @@ -1,3 +1,16 @@ -void ati_eeprom_load(char *fn, int type); -void ati_eeprom_write(int ena, int clk, int dat); -int ati_eeprom_read(); +typedef struct ati_eeprom_t +{ + uint16_t data[256]; + + int oldclk, oldena; + int opcode, state, count, out; + int wp; + uint32_t dat; + int type; + + char fn[256]; +} ati_eeprom_t; + +void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type); +void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat); +int ati_eeprom_read(ati_eeprom_t *eeprom); diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index b163ded..9af9600 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -1,5 +1,7 @@ /*ATI Mach64 emulation*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "video.h" @@ -10,16 +12,22 @@ #include "vid_svga_render.h" //#define MACH64_DEBUG -static int mach64_bank_r[2] = {0, 0}; -static int mach64_bank_w[2] = {0, 0}; void mach64_write(uint32_t addr, uint8_t val, void *priv); uint8_t mach64_read(uint32_t addr, void *priv); -static uint8_t ati_regs[256]; -static int ati_index; - -struct +typedef struct mach64_t { + svga_t svga; + ati68860_ramdac_t ramdac; + ati_eeprom_t eeprom; + ics2595_t ics2595; + + uint8_t regs[256]; + int index; + + int bank_r[2]; + int bank_w[2]; + uint32_t config_cntl; uint32_t context_load_cntl; @@ -62,6 +70,10 @@ struct uint32_t mem_cntl; + uint32_t ovr_clr; + uint32_t ovr_wid_left_right; + uint32_t ovr_wid_top_bottom; + uint32_t pat_cntl; uint32_t pat_reg0, pat_reg1; @@ -73,6 +85,8 @@ struct uint32_t src_off_pitch; uint32_t src_y_x; + uint8_t stat; + struct { int op; @@ -100,7 +114,7 @@ struct int err; } accel; -} mach64; +} mach64_t; enum { @@ -149,152 +163,161 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv); void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv); void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv); -void mach64_out(uint16_t addr, uint8_t val, void *priv) +void mach64_out(uint16_t addr, uint8_t val, void *p) { + mach64_t *mach64 = p; + svga_t *svga = &mach64->svga; uint8_t old; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; // pclog("mach64 out %04X %02X\n", addr, val); switch (addr) { case 0x1ce: - ati_index = val; + mach64->index = val; break; case 0x1cf: - ati_regs[ati_index] = val; + mach64->regs[mach64->index] = val; break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - ati68860_ramdac_out((addr & 3) | ((mach64.dac_cntl & 3) << 2), val, NULL); + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, svga); return; case 0x3cf: - if (gdcaddr == 6) + if (svga->gdcaddr == 6) { - if ((gdcreg[6] & 0xc) != (val & 0xc)) + if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - mem_removehandler(0xa0000, 0x20000, mach64_read, NULL, NULL, mach64_write, NULL, NULL, NULL); - mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); - mem_removehandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL); - pclog("Write mapping %02X\n", val); - switch (val&0xC) + mem_removehandler(0xa0000, 0x20000, mach64_read, NULL, NULL, mach64_write, NULL, NULL, mach64); + mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); + mem_removehandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, mach64); +// pclog("Write mapping %02X\n", val); + switch (val & 0xc) { case 0x0: /*128k at A0000*/ - mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL, NULL); - mem_sethandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL); + mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL, mach64); + mem_sethandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, mach64); break; case 0x4: /*64k at A0000*/ - mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL, NULL); + mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL, mach64); break; case 0x8: /*32k at B0000*/ - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0xC: /*32k at B8000*/ - mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; } } - gdcreg[6] = val; + svga->gdcreg[6] = val; return; } break; case 0x3D4: - crtcreg = val & 0x3f; + svga->crtcreg = val & 0x3f; return; case 0x3D5: - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; if (old!=val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(svga); } } break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t mach64_in(uint16_t addr, void *priv) +uint8_t mach64_in(uint16_t addr, void *p) { - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + mach64_t *mach64 = p; + svga_t *svga = &mach64->svga; + + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) + addr ^= 0x60; // pclog("IN mach64 %04X\n", addr); switch (addr) { case 0x1ce: - return ati_index; + return mach64->index; case 0x1cf: - return ati_regs[ati_index]; + return mach64->regs[mach64->index]; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return ati68860_ramdac_in((addr & 3) | ((mach64.dac_cntl & 3) << 2), NULL); + return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, svga); case 0x3D4: - return crtcreg; + return svga->crtcreg; case 0x3D5: - return crtc[crtcreg]; + return svga->crtc[svga->crtcreg]; } - return svga_in(addr, NULL); + return svga_in(addr, svga); } -void mach64_recalctimings() +void mach64_recalctimings(svga_t *svga) { - if (((mach64.crtc_gen_cntl >> 24) & 3) == 3) + mach64_t *mach64 = (mach64_t *)svga->p; + + if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { - svga_vtotal = (mach64.crtc_v_total_disp & 2047) + 1; - svga_dispend = ((mach64.crtc_v_total_disp >> 16) & 2047) + 1; - svga_htotal = (mach64.crtc_h_total_disp & 255) + 1; - svga_hdisp_time = svga_hdisp = ((mach64.crtc_h_total_disp >> 16) & 255) + 1; - svga_vsyncstart = (mach64.crtc_v_sync_strt_wid & 2047) + 1; - svga_rowoffset = (mach64.crtc_off_pitch >> 22); - svga_clock = cpuclock / ics2595_output_clock; - svga_ma = (mach64.crtc_off_pitch & 0x1fffff) * 2; - svga_linedbl = svga_rowcount = 0; + svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; + svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; + svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; + svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; + svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; + svga->rowoffset = (mach64->crtc_off_pitch >> 22); + svga->clock = cpuclock / mach64->ics2595.output_clock; + svga->ma = (mach64->crtc_off_pitch & 0x1fffff) * 2; + svga->linedbl = svga->rowcount = 0; // svga_htotal <<= 1; // svga_hdisp <<= 1; - svga_rowoffset <<= 1; - switch ((mach64.crtc_gen_cntl >> 8) & 7) + svga->rowoffset <<= 1; + switch ((mach64->crtc_gen_cntl >> 8) & 7) { case 1: - svga_render = svga_render_4bpp_highres; - svga_hdisp *= 8; + svga->render = svga_render_4bpp_highres; + svga->hdisp *= 8; break; case 2: - svga_render = svga_render_8bpp_highres; - svga_hdisp *= 8; - svga_rowoffset /= 2; + svga->render = svga_render_8bpp_highres; + svga->hdisp *= 8; + svga->rowoffset /= 2; break; case 3: - svga_render = svga_render_15bpp_highres; - svga_hdisp *= 8; + svga->render = svga_render_15bpp_highres; + svga->hdisp *= 8; //svga_rowoffset *= 2; break; case 4: - svga_render = svga_render_16bpp_highres; - svga_hdisp *= 8; + svga->render = svga_render_16bpp_highres; + svga->hdisp *= 8; //svga_rowoffset *= 2; break; case 5: - svga_render = svga_render_24bpp_highres; - svga_hdisp *= 8; - svga_rowoffset = (svga_rowoffset * 3) / 2; + svga->render = svga_render_24bpp_highres; + svga->hdisp *= 8; + svga->rowoffset = (svga->rowoffset * 3) / 2; break; case 6: - svga_render = svga_render_32bpp_highres; - svga_hdisp *= 8; + svga->render = svga_render_32bpp_highres; + svga->hdisp *= 8; break; } - pclog("mach64_recalctimings : frame %i,%i disp %i,%i vsync at %i rowoffset %i pixel clock %f MA %08X\n", svga_htotal, svga_vtotal, svga_hdisp, svga_dispend, svga_vsyncstart, svga_rowoffset, svga_clock, svga_ma); + // pclog("mach64_recalctimings : frame %i,%i disp %i,%i vsync at %i rowoffset %i pixel clock %f MA %08X\n", svga->htotal, svga->vtotal, svga->hdisp, svga->dispend, svga->vsyncstart, svga->rowoffset, svga->clock, svga->ma); } } @@ -314,171 +337,172 @@ void mach64_recalctimings() case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ } -void mach64_cursor_dump() +void mach64_cursor_dump(mach64_t *mach64) { + svga_t *svga = &mach64->svga; pclog("Mach64 cursor :\n"); - pclog("Ena = %i X = %i Y = %i Addr = %05X Xoff = %i Yoff = %i\n", svga_hwcursor.ena, svga_hwcursor.x, svga_hwcursor.y, svga_hwcursor.addr, svga_hwcursor.xoff, svga_hwcursor.yoff); + pclog("Ena = %i X = %i Y = %i Addr = %05X Xoff = %i Yoff = %i\n", svga->hwcursor.ena, svga->hwcursor.x, svga->hwcursor.y, svga->hwcursor.addr, svga->hwcursor.xoff, svga->hwcursor.yoff); } -void mach64_start_fill() +void mach64_start_fill(mach64_t *mach64) { int x, y; - mach64.accel.dst_x = (mach64.dst_y_x >> 16) & 0xfff; - mach64.accel.dst_y = mach64.dst_y_x & 0xfff; + mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff; + mach64->accel.dst_y = mach64->dst_y_x & 0xfff; - mach64.accel.dst_width = (mach64.dst_height_width >> 16) & 0x1fff; - mach64.accel.dst_height = mach64.dst_height_width & 0x1fff; - mach64.accel.x_count = mach64.accel.dst_width; + mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff; + mach64->accel.dst_height = mach64->dst_height_width & 0x1fff; + mach64->accel.x_count = mach64->accel.dst_width; - mach64.accel.src_x = (mach64.src_y_x >> 16) & 0xfff; - mach64.accel.src_y = mach64.src_y_x & 0xfff; + mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff; + mach64->accel.src_y = mach64->src_y_x & 0xfff; - mach64.accel.src_pitch = (mach64.src_off_pitch >> 22) * 8; - mach64.accel.src_offset = (mach64.src_off_pitch & 0xfffff) * 8; + mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; + mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; - mach64.accel.dst_pitch = (mach64.dst_off_pitch >> 22) * 8; - mach64.accel.dst_offset = (mach64.dst_off_pitch & 0xfffff) * 8; + mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; + mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; - mach64.accel.mix_fg = (mach64.dp_mix >> 16) & 0x1f; - mach64.accel.mix_bg = mach64.dp_mix & 0x1f; + mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; + mach64->accel.mix_bg = mach64->dp_mix & 0x1f; - mach64.accel.source_bg = mach64.dp_src & 7; - mach64.accel.source_fg = (mach64.dp_src >> 8) & 7; - mach64.accel.source_mix = (mach64.dp_src >> 16) & 7; + mach64->accel.source_bg = mach64->dp_src & 7; + mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; + mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; - mach64.accel.dst_pix_width = mach64.dp_pix_width & 7; - mach64.accel.src_pix_width = (mach64.dp_pix_width >> 8) & 7; - mach64.accel.host_pix_width = (mach64.dp_pix_width >> 16) & 7; + mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; + mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; + mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; - mach64.accel.dst_size = mach64_width[mach64.accel.dst_pix_width]; - mach64.accel.src_size = mach64_width[mach64.accel.src_pix_width]; + mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; + mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; -/* mach64.accel.src_x *= mach64_inc[mach64.accel.src_pix_width]; - mach64.accel.src_pitch *= mach64_inc[mach64.accel.src_pix_width]; - mach64.accel.dst_x *= mach64_inc[mach64.accel.dst_pix_width]; - mach64.accel.dst_pitch *= mach64_inc[mach64.accel.dst_pix_width];*/ +/* mach64->accel.src_x *= mach64_inc[mach64->accel.src_pix_width]; + mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; + mach64->accel.dst_x *= mach64_inc[mach64->accel.dst_pix_width]; + mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ - mach64.accel.src_offset >>= mach64.accel.src_size; - mach64.accel.dst_offset >>= mach64.accel.dst_size; + mach64->accel.src_offset >>= mach64->accel.src_size; + mach64->accel.dst_offset >>= mach64->accel.dst_size; - mach64.accel.src_x_start = mach64.accel.src_x; - mach64.accel.dst_x_start = mach64.accel.dst_x; + mach64->accel.src_x_start = mach64->accel.src_x; + mach64->accel.dst_x_start = mach64->accel.dst_x; -/* if (mach64.accel.source_fg == SRC_BLITSRC || mach64.accel.source_bg == SRC_BLITSRC) +/* if (mach64->accel.source_fg == SRC_BLITSRC || mach64->accel.source_bg == SRC_BLITSRC) {*/ - mach64.accel.xinc = (mach64.dst_cntl & 1) ? 1 : -1; - mach64.accel.yinc = (mach64.dst_cntl & 2) ? 1 : -1; + mach64->accel.xinc = (mach64->dst_cntl & 1) ? 1 : -1; + mach64->accel.yinc = (mach64->dst_cntl & 2) ? 1 : -1; /* } else { - mach64.accel.xinc = mach64_inc[mach64.accel.src_pix_width]; - mach64.accel.yinc = 1; + mach64->accel.xinc = mach64_inc[mach64->accel.src_pix_width]; + mach64->accel.yinc = 1; }*/ - mach64.accel.source_host = ((mach64.dp_src & 7) == SRC_HOST) || (((mach64.dp_src >> 8) & 7) == SRC_HOST); + mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); -// pclog("mach64_start_fill : pattern %08X %08X\n", mach64.pat_reg0, mach64.pat_reg1); +// pclog("mach64_start_fill : pattern %08X %08X\n", mach64->pat_reg0, mach64->pat_reg1); for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { - uint32_t temp = (y & 4) ? mach64.pat_reg1 : mach64.pat_reg0; - mach64.accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; -// pclog("%i ", mach64.accel.pattern[y][x]); + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; +// pclog("%i ", mach64->accel.pattern[y][x]); } // pclog("\n"); } - mach64.accel.sc_left = mach64.sc_left_right & 0x1fff; - mach64.accel.sc_right = (mach64.sc_left_right >> 16) & 0x1fff; - mach64.accel.sc_top = mach64.sc_top_bottom & 0x7fff; - mach64.accel.sc_bottom = (mach64.sc_top_bottom >> 16) & 0x7fff; + mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; + mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; + mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; + mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; -/* mach64.accel.sc_left *= mach64_inc[mach64.accel.dst_pix_width]; - mach64.accel.sc_right *= mach64_inc[mach64.accel.dst_pix_width];*/ +/* mach64->accel.sc_left *= mach64_inc[mach64->accel.dst_pix_width]; + mach64->accel.sc_right *= mach64_inc[mach64->accel.dst_pix_width];*/ - mach64.accel.dp_frgd_clr = mach64.dp_frgd_clr; - mach64.accel.dp_bkgd_clr = mach64.dp_bkgd_clr; + mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; + mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; - mach64.accel.busy = 1; + mach64->accel.busy = 1; #ifdef MACH64_DEBUG - pclog("mach64_start_fill : dst %i, %i src %i, %i size %i, %i src pitch %i offset %X dst pitch %i offset %X scissor %i %i %i %i src_fg %i\n", mach64.accel.dst_x, mach64.accel.dst_y, mach64.accel.src_x, mach64.accel.src_y, mach64.accel.dst_width, mach64.accel.dst_height, mach64.accel.src_pitch, mach64.accel.src_offset, mach64.accel.dst_pitch, mach64.accel.dst_offset, mach64.accel.sc_left, mach64.accel.sc_right, mach64.accel.sc_top, mach64.accel.sc_bottom, mach64.accel.source_fg); + pclog("mach64_start_fill : dst %i, %i src %i, %i size %i, %i src pitch %i offset %X dst pitch %i offset %X scissor %i %i %i %i src_fg %i\n", mach64->accel.dst_x, mach64->accel.dst_y, mach64->accel.src_x, mach64->accel.src_y, mach64->accel.dst_width, mach64->accel.dst_height, mach64->accel.src_pitch, mach64->accel.src_offset, mach64->accel.dst_pitch, mach64->accel.dst_offset, mach64->accel.sc_left, mach64->accel.sc_right, mach64->accel.sc_top, mach64->accel.sc_bottom, mach64->accel.source_fg); #endif - mach64.accel.op = OP_RECT; + mach64->accel.op = OP_RECT; } -void mach64_start_line() +void mach64_start_line(mach64_t *mach64) { int x, y; - mach64.accel.dst_x = (mach64.dst_y_x >> 16) & 0xfff; - mach64.accel.dst_y = mach64.dst_y_x & 0xfff; + mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff; + mach64->accel.dst_y = mach64->dst_y_x & 0xfff; - mach64.accel.src_x = (mach64.src_y_x >> 16) & 0xfff; - mach64.accel.src_y = mach64.src_y_x & 0xfff; + mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff; + mach64->accel.src_y = mach64->src_y_x & 0xfff; - mach64.accel.src_pitch = (mach64.src_off_pitch >> 22) * 8; - mach64.accel.src_offset = (mach64.src_off_pitch & 0xfffff) * 8; + mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; + mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; - mach64.accel.dst_pitch = (mach64.dst_off_pitch >> 22) * 8; - mach64.accel.dst_offset = (mach64.dst_off_pitch & 0xfffff) * 8; + mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; + mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; - mach64.accel.mix_fg = (mach64.dp_mix >> 16) & 0x1f; - mach64.accel.mix_bg = mach64.dp_mix & 0x1f; + mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; + mach64->accel.mix_bg = mach64->dp_mix & 0x1f; - mach64.accel.source_bg = mach64.dp_src & 7; - mach64.accel.source_fg = (mach64.dp_src >> 8) & 7; - mach64.accel.source_mix = (mach64.dp_src >> 16) & 7; + mach64->accel.source_bg = mach64->dp_src & 7; + mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; + mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; - mach64.accel.dst_pix_width = mach64.dp_pix_width & 7; - mach64.accel.src_pix_width = (mach64.dp_pix_width >> 8) & 7; - mach64.accel.host_pix_width = (mach64.dp_pix_width >> 16) & 7; + mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; + mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; + mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; - mach64.accel.dst_size = mach64_width[mach64.accel.dst_pix_width]; - mach64.accel.src_size = mach64_width[mach64.accel.src_pix_width]; + mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; + mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; - mach64.accel.src_offset >>= mach64.accel.src_size; - mach64.accel.dst_offset >>= mach64.accel.dst_size; + mach64->accel.src_offset >>= mach64->accel.src_size; + mach64->accel.dst_offset >>= mach64->accel.dst_size; -/* mach64.accel.src_pitch *= mach64_inc[mach64.accel.src_pix_width]; - mach64.accel.dst_pitch *= mach64_inc[mach64.accel.dst_pix_width];*/ +/* mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; + mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ - mach64.accel.source_host = ((mach64.dp_src & 7) == SRC_HOST) || (((mach64.dp_src >> 8) & 7) == SRC_HOST); + mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { - uint32_t temp = (y & 4) ? mach64.pat_reg1 : mach64.pat_reg0; - mach64.accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; } } - mach64.accel.sc_left = mach64.sc_left_right & 0x1fff; - mach64.accel.sc_right = (mach64.sc_left_right >> 16) & 0x1fff; - mach64.accel.sc_top = mach64.sc_top_bottom & 0x7fff; - mach64.accel.sc_bottom = (mach64.sc_top_bottom >> 16) & 0x7fff; + mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; + mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; + mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; + mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; - mach64.accel.dp_frgd_clr = mach64.dp_frgd_clr; - mach64.accel.dp_bkgd_clr = mach64.dp_bkgd_clr; + mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; + mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; - mach64.accel.x_count = mach64.dst_bres_lnth & 0x7fff; - mach64.accel.err = (mach64.dst_bres_err & 0x3ffff) | ((mach64.dst_bres_err & 0x40000) ? 0xfffc0000 : 0); + mach64->accel.x_count = mach64->dst_bres_lnth & 0x7fff; + mach64->accel.err = (mach64->dst_bres_err & 0x3ffff) | ((mach64->dst_bres_err & 0x40000) ? 0xfffc0000 : 0); - mach64.accel.busy = 1; + mach64->accel.busy = 1; #ifdef MACH64_DEBUG pclog("mach64_start_line\n"); #endif - mach64.accel.op = OP_LINE; + mach64->accel.op = OP_LINE; } -#define READ(addr, dat, width) if (width == 0) dat = vram[((addr)) & 0x7fffff]; \ - else if (width == 1) dat = *(uint16_t *)&vram[((addr) << 1) & 0x7fffff]; \ - else dat = *(uint32_t *)&vram[((addr) << 2) & 0x7fffff]; +#define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) & 0x7fffff]; \ + else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & 0x7fffff]; \ + else dat = *(uint32_t *)&svga->vram[((addr) << 2) & 0x7fffff]; -#define MIX switch (mix ? mach64.accel.mix_fg : mach64.accel.mix_bg) \ +#define MIX switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg) \ { \ case 0x0: dest_dat = ~dest_dat; break; \ case 0x1: dest_dat = 0; break; \ @@ -500,30 +524,32 @@ void mach64_start_line() #define WRITE(addr, width) if (width == 0) \ { \ - vram[(addr) & 0x7fffff] = dest_dat; \ - changedvram[((addr) & 0x7fffff) >> 10] = changeframecount; \ + svga->vram[(addr) & 0x7fffff] = dest_dat; \ + svga->changedvram[((addr) & 0x7fffff) >> 10] = changeframecount; \ } \ else if (width == 1) \ { \ - *(uint16_t *)&vram[((addr) << 1) & 0x7fffff] = dest_dat; \ - changedvram[(((addr) << 1) & 0x7fffff) >> 10] = changeframecount; \ + *(uint16_t *)&svga->vram[((addr) << 1) & 0x7fffff] = dest_dat; \ + svga->changedvram[(((addr) << 1) & 0x7fffff) >> 10] = changeframecount; \ } \ else \ { \ - *(uint32_t *)&vram[((addr) << 2) & 0x7fffff] = dest_dat; \ - changedvram[(((addr) << 2) & 0x7fffff) >> 10] = changeframecount; \ + *(uint32_t *)&svga->vram[((addr) << 2) & 0x7fffff] = dest_dat; \ + svga->changedvram[(((addr) << 2) & 0x7fffff) >> 10] = changeframecount; \ } -void mach64_blit(uint32_t cpu_dat, int count) +void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) { - if (!mach64.accel.busy) + svga_t *svga = &mach64->svga; + + if (!mach64->accel.busy) { #ifdef MACH64_DEBUG pclog("mach64_blit : return as not busy\n"); #endif return; } - switch (mach64.accel.op) + switch (mach64->accel.op) { case OP_RECT: while (count) @@ -532,10 +558,10 @@ void mach64_blit(uint32_t cpu_dat, int count) uint32_t host_dat; int mix; - if (mach64.accel.source_host) + if (mach64->accel.source_host) { host_dat = cpu_dat; - switch (mach64.accel.src_size) + switch (mach64->accel.src_size) { case 0: cpu_dat >>= 8; @@ -553,14 +579,14 @@ void mach64_blit(uint32_t cpu_dat, int count) else count--; - switch (mach64.accel.source_mix) + switch (mach64->accel.source_mix) { case MONO_SRC_HOST: mix = cpu_dat >> 31; cpu_dat <<= 1; break; case MONO_SRC_PAT: - mix = mach64.accel.pattern[mach64.accel.dst_y & 7][mach64.accel.dst_x & 7]; + mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7]; break; case MONO_SRC_1: default: @@ -568,69 +594,69 @@ void mach64_blit(uint32_t cpu_dat, int count) break; } - if (mach64.accel.dst_x >= mach64.accel.sc_left && mach64.accel.dst_x <= mach64.accel.sc_right && - mach64.accel.dst_y >= mach64.accel.sc_top && mach64.accel.dst_y <= mach64.accel.sc_bottom) + if (mach64->accel.dst_x >= mach64->accel.sc_left && mach64->accel.dst_x <= mach64->accel.sc_right && + mach64->accel.dst_y >= mach64->accel.sc_top && mach64->accel.dst_y <= mach64->accel.sc_bottom) { - switch (mix ? mach64.accel.source_fg : mach64.accel.source_bg) + switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) { case SRC_HOST: src_dat = host_dat; break; case SRC_BLITSRC: - READ(mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x, src_dat, mach64.accel.src_size); + READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size); break; case SRC_FG: - src_dat = mach64.accel.dp_frgd_clr; + src_dat = mach64->accel.dp_frgd_clr; break; case SRC_BG: - src_dat = mach64.accel.dp_bkgd_clr; + src_dat = mach64->accel.dp_bkgd_clr; break; default: src_dat = 0; break; } - READ(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, dest_dat, mach64.accel.dst_size); + READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size); -// pclog("Blit %i,%i %i,%i %X %X %i %02X %02X %i ", mach64.accel.src_x, mach64.accel.src_y, mach64.accel.dst_x, mach64.accel.dst_y, (mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x) & 0x7fffff, (mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix); +// pclog("Blit %i,%i %i,%i %X %X %i %02X %02X %i ", mach64->accel.src_x, mach64->accel.src_y, mach64->accel.dst_x, mach64->accel.dst_y, (mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x) & 0x7fffff, (mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix); MIX -// pclog("%02X %i\n", dest_dat, mach64.accel.dst_height); +// pclog("%02X %i\n", dest_dat, mach64->accel.dst_height); - WRITE(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, mach64.accel.dst_size); + WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); } - if (mach64.dst_cntl & DST_24_ROT_EN) + if (mach64->dst_cntl & DST_24_ROT_EN) { - mach64.accel.dp_frgd_clr = ((mach64.accel.dp_frgd_clr >> 8) & 0xffff) | (mach64.accel.dp_frgd_clr << 16); - mach64.accel.dp_bkgd_clr = ((mach64.accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64.accel.dp_bkgd_clr << 16); + mach64->accel.dp_frgd_clr = ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16); + mach64->accel.dp_bkgd_clr = ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16); } - mach64.accel.src_x += mach64.accel.xinc; - mach64.accel.dst_x += mach64.accel.xinc; - mach64.accel.x_count--; + mach64->accel.src_x += mach64->accel.xinc; + mach64->accel.dst_x += mach64->accel.xinc; + mach64->accel.x_count--; - if (mach64.accel.x_count <= 0) + if (mach64->accel.x_count <= 0) { - mach64.accel.x_count = mach64.accel.dst_width; - mach64.accel.src_x = mach64.accel.src_x_start; - mach64.accel.dst_x = mach64.accel.dst_x_start; + mach64->accel.x_count = mach64->accel.dst_width; + mach64->accel.src_x = mach64->accel.src_x_start; + mach64->accel.dst_x = mach64->accel.dst_x_start; - mach64.accel.src_y += mach64.accel.yinc; - mach64.accel.dst_y += mach64.accel.yinc; - mach64.accel.dst_height--; + mach64->accel.src_y += mach64->accel.yinc; + mach64->accel.dst_y += mach64->accel.yinc; + mach64->accel.dst_height--; - if (mach64.accel.dst_height <= 0) + if (mach64->accel.dst_height <= 0) { /*Blit finished*/ #ifdef MACH64_DEBUG pclog("mach64 blit finished\n"); #endif - mach64.accel.busy = 0; + mach64->accel.busy = 0; return; } - if (mach64.accel.source_host) + if (mach64->accel.source_host) return; } } @@ -643,10 +669,10 @@ void mach64_blit(uint32_t cpu_dat, int count) uint32_t host_dat; int mix; - if (mach64.accel.source_host) + if (mach64->accel.source_host) { host_dat = cpu_dat; - switch (mach64.accel.src_size) + switch (mach64->accel.src_size) { case 0: cpu_dat >>= 8; @@ -664,14 +690,14 @@ void mach64_blit(uint32_t cpu_dat, int count) else count--; - switch (mach64.accel.source_mix) + switch (mach64->accel.source_mix) { case MONO_SRC_HOST: mix = cpu_dat >> 31; cpu_dat <<= 1; break; case MONO_SRC_PAT: - mix = mach64.accel.pattern[mach64.accel.dst_y & 7][mach64.accel.dst_x & 7]; + mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7]; break; case MONO_SRC_1: default: @@ -679,232 +705,244 @@ void mach64_blit(uint32_t cpu_dat, int count) break; } - if (mach64.accel.dst_x >= mach64.accel.sc_left && mach64.accel.dst_x <= mach64.accel.sc_right && - mach64.accel.dst_y >= mach64.accel.sc_top && mach64.accel.dst_y <= mach64.accel.sc_bottom) + if (mach64->accel.dst_x >= mach64->accel.sc_left && mach64->accel.dst_x <= mach64->accel.sc_right && + mach64->accel.dst_y >= mach64->accel.sc_top && mach64->accel.dst_y <= mach64->accel.sc_bottom) { - switch (mix ? mach64.accel.source_fg : mach64.accel.source_bg) + switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) { case SRC_HOST: src_dat = host_dat; break; case SRC_BLITSRC: - READ(mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x, src_dat, mach64.accel.src_size); + READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size); break; case SRC_FG: - src_dat = mach64.accel.dp_frgd_clr; + src_dat = mach64->accel.dp_frgd_clr; break; case SRC_BG: - src_dat = mach64.accel.dp_bkgd_clr; + src_dat = mach64->accel.dp_bkgd_clr; break; default: src_dat = 0; break; } - READ(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, dest_dat, mach64.accel.dst_size); + READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size); -// pclog("Blit %i,%i %i,%i %X %X %i %02X %02X %i ", mach64.accel.src_x, mach64.accel.src_y, mach64.accel.dst_x, mach64.accel.dst_y, (mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x) & 0x7fffff, (mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix); +// pclog("Blit %i,%i %i,%i %X %X %i %02X %02X %i ", mach64->accel.src_x, mach64->accel.src_y, mach64->accel.dst_x, mach64->accel.dst_y, (mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x) & 0x7fffff, (mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix); MIX -// pclog("%02X %i\n", dest_dat, mach64.accel.dst_height); +// pclog("%02X %i\n", dest_dat, mach64->accel.dst_height); - WRITE(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, mach64.accel.dst_size); + WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); } - mach64.accel.x_count--; - if (mach64.accel.x_count <= 0) + mach64->accel.x_count--; + if (mach64->accel.x_count <= 0) { /*Blit finished*/ #ifdef MACH64_DEBUG pclog("mach64 blit finished\n"); #endif - mach64.accel.busy = 0; + mach64->accel.busy = 0; return; } - switch (mach64.dst_cntl & 7) + switch (mach64->dst_cntl & 7) { case 0: case 2: - mach64.accel.src_x--; - mach64.accel.dst_x--; + mach64->accel.src_x--; + mach64->accel.dst_x--; break; case 1: case 3: - mach64.accel.src_x++; - mach64.accel.dst_x++; + mach64->accel.src_x++; + mach64->accel.dst_x++; break; case 4: case 5: - mach64.accel.src_y--; - mach64.accel.dst_y--; + mach64->accel.src_y--; + mach64->accel.dst_y--; break; case 6: case 7: - mach64.accel.src_y++; - mach64.accel.dst_y++; + mach64->accel.src_y++; + mach64->accel.dst_y++; break; } #ifdef MACH64_DEBUG - pclog("x %i y %i err %i inc %i dec %i\n", mach64.accel.dst_x, mach64.accel.dst_y, mach64.accel.err, mach64.dst_bres_inc, mach64.dst_bres_dec); + pclog("x %i y %i err %i inc %i dec %i\n", mach64->accel.dst_x, mach64->accel.dst_y, mach64->accel.err, mach64->dst_bres_inc, mach64->dst_bres_dec); #endif - if (mach64.accel.err >= 0) + if (mach64->accel.err >= 0) { - mach64.accel.err += mach64.dst_bres_dec; + mach64->accel.err += mach64->dst_bres_dec; - switch (mach64.dst_cntl & 7) + switch (mach64->dst_cntl & 7) { case 0: case 1: - mach64.accel.src_y--; - mach64.accel.dst_y--; + mach64->accel.src_y--; + mach64->accel.dst_y--; break; case 2: case 3: - mach64.accel.src_y++; - mach64.accel.dst_y++; + mach64->accel.src_y++; + mach64->accel.dst_y++; break; case 4: case 6: - mach64.accel.src_x--; - mach64.accel.dst_x--; + mach64->accel.src_x--; + mach64->accel.dst_x--; break; case 5: case 7: - mach64.accel.src_x++; - mach64.accel.dst_x++; + mach64->accel.src_x++; + mach64->accel.dst_x++; break; } } else - mach64.accel.err += mach64.dst_bres_inc; + mach64->accel.err += mach64->dst_bres_inc; } break; } } -void mach64_load_context() +void mach64_load_context(mach64_t *mach64) { + svga_t *svga = &mach64->svga; uint32_t addr; - while (mach64.context_load_cntl & 0x30000) + while (mach64->context_load_cntl & 0x30000) { - addr = (0x3fff - (mach64.context_load_cntl & 0x3fff)) * 256; - mach64.context_mask = *(uint32_t *)&vram[addr]; + addr = (0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256; + mach64->context_mask = *(uint32_t *)&svga->vram[addr]; #ifdef MACH64_DEBUG - pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64.context_load_cntl, addr, mach64.context_mask); + pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask); #endif - if (mach64.context_mask & (1 << 2)) - mach64_ext_writel(0x100, *(uint32_t *)&vram[addr + 0x08], NULL); - if (mach64.context_mask & (1 << 3)) - mach64_ext_writel(0x10c, *(uint32_t *)&vram[addr + 0x0c], NULL); - if (mach64.context_mask & (1 << 4)) - mach64_ext_writel(0x118, *(uint32_t *)&vram[addr + 0x10], NULL); - if (mach64.context_mask & (1 << 5)) - mach64_ext_writel(0x124, *(uint32_t *)&vram[addr + 0x14], NULL); - if (mach64.context_mask & (1 << 6)) - mach64_ext_writel(0x128, *(uint32_t *)&vram[addr + 0x18], NULL); - if (mach64.context_mask & (1 << 7)) - mach64_ext_writel(0x12c, *(uint32_t *)&vram[addr + 0x1c], NULL); - if (mach64.context_mask & (1 << 8)) - mach64_ext_writel(0x180, *(uint32_t *)&vram[addr + 0x20], NULL); - if (mach64.context_mask & (1 << 9)) - mach64_ext_writel(0x18c, *(uint32_t *)&vram[addr + 0x24], NULL); - if (mach64.context_mask & (1 << 10)) - mach64_ext_writel(0x198, *(uint32_t *)&vram[addr + 0x28], NULL); - if (mach64.context_mask & (1 << 11)) - mach64_ext_writel(0x1a4, *(uint32_t *)&vram[addr + 0x2c], NULL); - if (mach64.context_mask & (1 << 12)) - mach64_ext_writel(0x1b0, *(uint32_t *)&vram[addr + 0x30], NULL); - if (mach64.context_mask & (1 << 13)) - mach64_ext_writel(0x280, *(uint32_t *)&vram[addr + 0x34], NULL); - if (mach64.context_mask & (1 << 14)) - mach64_ext_writel(0x284, *(uint32_t *)&vram[addr + 0x38], NULL); - if (mach64.context_mask & (1 << 15)) - mach64_ext_writel(0x2a8, *(uint32_t *)&vram[addr + 0x3c], NULL); - if (mach64.context_mask & (1 << 16)) - mach64_ext_writel(0x2b4, *(uint32_t *)&vram[addr + 0x40], NULL); - if (mach64.context_mask & (1 << 17)) - mach64_ext_writel(0x2c0, *(uint32_t *)&vram[addr + 0x44], NULL); - if (mach64.context_mask & (1 << 18)) - mach64_ext_writel(0x2c4, *(uint32_t *)&vram[addr + 0x48], NULL); - if (mach64.context_mask & (1 << 19)) - mach64_ext_writel(0x2c8, *(uint32_t *)&vram[addr + 0x4c], NULL); - if (mach64.context_mask & (1 << 20)) - mach64_ext_writel(0x2cc, *(uint32_t *)&vram[addr + 0x50], NULL); - if (mach64.context_mask & (1 << 21)) - mach64_ext_writel(0x2d0, *(uint32_t *)&vram[addr + 0x54], NULL); - if (mach64.context_mask & (1 << 22)) - mach64_ext_writel(0x2d4, *(uint32_t *)&vram[addr + 0x58], NULL); - if (mach64.context_mask & (1 << 23)) - mach64_ext_writel(0x2d8, *(uint32_t *)&vram[addr + 0x5c], NULL); - if (mach64.context_mask & (1 << 24)) - mach64_ext_writel(0x300, *(uint32_t *)&vram[addr + 0x60], NULL); - if (mach64.context_mask & (1 << 25)) - mach64_ext_writel(0x304, *(uint32_t *)&vram[addr + 0x64], NULL); - if (mach64.context_mask & (1 << 26)) - mach64_ext_writel(0x308, *(uint32_t *)&vram[addr + 0x68], NULL); - if (mach64.context_mask & (1 << 27)) - mach64_ext_writel(0x330, *(uint32_t *)&vram[addr + 0x6c], NULL); + if (mach64->context_mask & (1 << 2)) + mach64_ext_writel(0x100, *(uint32_t *)&svga->vram[addr + 0x08], mach64); + if (mach64->context_mask & (1 << 3)) + mach64_ext_writel(0x10c, *(uint32_t *)&svga->vram[addr + 0x0c], mach64); + if (mach64->context_mask & (1 << 4)) + mach64_ext_writel(0x118, *(uint32_t *)&svga->vram[addr + 0x10], mach64); + if (mach64->context_mask & (1 << 5)) + mach64_ext_writel(0x124, *(uint32_t *)&svga->vram[addr + 0x14], mach64); + if (mach64->context_mask & (1 << 6)) + mach64_ext_writel(0x128, *(uint32_t *)&svga->vram[addr + 0x18], mach64); + if (mach64->context_mask & (1 << 7)) + mach64_ext_writel(0x12c, *(uint32_t *)&svga->vram[addr + 0x1c], mach64); + if (mach64->context_mask & (1 << 8)) + mach64_ext_writel(0x180, *(uint32_t *)&svga->vram[addr + 0x20], mach64); + if (mach64->context_mask & (1 << 9)) + mach64_ext_writel(0x18c, *(uint32_t *)&svga->vram[addr + 0x24], mach64); + if (mach64->context_mask & (1 << 10)) + mach64_ext_writel(0x198, *(uint32_t *)&svga->vram[addr + 0x28], mach64); + if (mach64->context_mask & (1 << 11)) + mach64_ext_writel(0x1a4, *(uint32_t *)&svga->vram[addr + 0x2c], mach64); + if (mach64->context_mask & (1 << 12)) + mach64_ext_writel(0x1b0, *(uint32_t *)&svga->vram[addr + 0x30], mach64); + if (mach64->context_mask & (1 << 13)) + mach64_ext_writel(0x280, *(uint32_t *)&svga->vram[addr + 0x34], mach64); + if (mach64->context_mask & (1 << 14)) + mach64_ext_writel(0x284, *(uint32_t *)&svga->vram[addr + 0x38], mach64); + if (mach64->context_mask & (1 << 15)) + mach64_ext_writel(0x2a8, *(uint32_t *)&svga->vram[addr + 0x3c], mach64); + if (mach64->context_mask & (1 << 16)) + mach64_ext_writel(0x2b4, *(uint32_t *)&svga->vram[addr + 0x40], mach64); + if (mach64->context_mask & (1 << 17)) + mach64_ext_writel(0x2c0, *(uint32_t *)&svga->vram[addr + 0x44], mach64); + if (mach64->context_mask & (1 << 18)) + mach64_ext_writel(0x2c4, *(uint32_t *)&svga->vram[addr + 0x48], mach64); + if (mach64->context_mask & (1 << 19)) + mach64_ext_writel(0x2c8, *(uint32_t *)&svga->vram[addr + 0x4c], mach64); + if (mach64->context_mask & (1 << 20)) + mach64_ext_writel(0x2cc, *(uint32_t *)&svga->vram[addr + 0x50], mach64); + if (mach64->context_mask & (1 << 21)) + mach64_ext_writel(0x2d0, *(uint32_t *)&svga->vram[addr + 0x54], mach64); + if (mach64->context_mask & (1 << 22)) + mach64_ext_writel(0x2d4, *(uint32_t *)&svga->vram[addr + 0x58], mach64); + if (mach64->context_mask & (1 << 23)) + mach64_ext_writel(0x2d8, *(uint32_t *)&svga->vram[addr + 0x5c], mach64); + if (mach64->context_mask & (1 << 24)) + mach64_ext_writel(0x300, *(uint32_t *)&svga->vram[addr + 0x60], mach64); + if (mach64->context_mask & (1 << 25)) + mach64_ext_writel(0x304, *(uint32_t *)&svga->vram[addr + 0x64], mach64); + if (mach64->context_mask & (1 << 26)) + mach64_ext_writel(0x308, *(uint32_t *)&svga->vram[addr + 0x68], mach64); + if (mach64->context_mask & (1 << 27)) + mach64_ext_writel(0x330, *(uint32_t *)&svga->vram[addr + 0x6c], mach64); - mach64.context_load_cntl = *(uint32_t *)&vram[addr + 0x70]; + mach64->context_load_cntl = *(uint32_t *)&svga->vram[addr + 0x70]; } } -uint8_t mach64_ext_readb(uint32_t addr, void *priv) +uint8_t mach64_ext_readb(uint32_t addr, void *p) { + mach64_t *mach64 = (mach64_t *)p; uint8_t ret; switch (addr & 0x3ff) { case 0x00: case 0x01: case 0x02: case 0x03: - READ8(addr, mach64.crtc_h_total_disp); + READ8(addr, mach64->crtc_h_total_disp); break; case 0x08: case 0x09: case 0x0a: case 0x0b: - READ8(addr, mach64.crtc_v_total_disp); + READ8(addr, mach64->crtc_v_total_disp); break; case 0x0c: case 0x0d: case 0x0e: case 0x0f: - READ8(addr, mach64.crtc_v_sync_strt_wid); + READ8(addr, mach64->crtc_v_sync_strt_wid); break; case 0x14: case 0x15: case 0x16: case 0x17: - READ8(addr, mach64.crtc_off_pitch); + READ8(addr, mach64->crtc_off_pitch); break; case 0x18: - ret = mach64.crtc_int_cntl & ~1; - if (cgastat & 8) + ret = mach64->crtc_int_cntl & ~1; + if (mach64->stat & 8) ret |= 1; break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: - READ8(addr, mach64.crtc_gen_cntl); + READ8(addr, mach64->crtc_gen_cntl); + break; + + case 0x40: case 0x41: case 0x42: case 0x43: + READ8(addr, mach64->ovr_clr); + break; + case 0x44: case 0x45: case 0x46: case 0x47: + READ8(addr, mach64->ovr_wid_left_right); + break; + case 0x48: case 0x49: case 0x4a: case 0x4b: + READ8(addr, mach64->ovr_wid_top_bottom); break; case 0x68: case 0x69: case 0x6a: case 0x6b: - READ8(addr, mach64.cur_offset); + READ8(addr, mach64->cur_offset); break; case 0x6c: case 0x6d: case 0x6e: case 0x6f: - READ8(addr, mach64.cur_horz_vert_posn); + READ8(addr, mach64->cur_horz_vert_posn); break; case 0x70: case 0x71: case 0x72: case 0x73: - READ8(addr, mach64.cur_horz_vert_off); + READ8(addr, mach64->cur_horz_vert_off); break; case 0x80: case 0x81: case 0x82: case 0x83: - READ8(addr, mach64.scratch_reg0); + READ8(addr, mach64->scratch_reg0); break; case 0x84: case 0x85: case 0x86: case 0x87: - READ8(addr, mach64.scratch_reg1); + READ8(addr, mach64->scratch_reg1); break; case 0x90: case 0x91: case 0x92: case 0x93: - READ8(addr, mach64.clock_cntl); + READ8(addr, mach64->clock_cntl); break; case 0xb0: case 0xb1: case 0xb2: case 0xb3: - READ8(addr, mach64.mem_cntl); + READ8(addr, mach64->mem_cntl); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: - READ8(addr, mach64.dac_cntl); + READ8(addr, mach64->dac_cntl); break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: - READ8(addr, mach64.gen_test_cntl); + READ8(addr, mach64->gen_test_cntl); break; case 0xe0: case 0xe1: case 0xe2: case 0xe3: @@ -912,113 +950,113 @@ uint8_t mach64_ext_readb(uint32_t addr, void *priv) break; case 0x100: case 0x101: case 0x102: case 0x103: - READ8(addr, mach64.dst_off_pitch); + READ8(addr, mach64->dst_off_pitch); break; case 0x104: case 0x105: - READ8(addr, mach64.dst_y_x); + READ8(addr, mach64->dst_y_x); break; case 0x108: case 0x109: case 0x11c: case 0x11d: - READ8(addr + 2, mach64.dst_y_x); + READ8(addr + 2, mach64->dst_y_x); break; case 0x10c: case 0x10d: case 0x10e: case 0x10f: - READ8(addr, mach64.dst_y_x); + READ8(addr, mach64->dst_y_x); break; case 0x110: case 0x111: addr += 2; case 0x114: case 0x115: case 0x118: case 0x119: case 0x11a: case 0x11b: case 0x11e: case 0x11f: - READ8(addr, mach64.dst_height_width); + READ8(addr, mach64->dst_height_width); break; case 0x120: case 0x121: case 0x122: case 0x123: - READ8(addr, mach64.dst_bres_lnth); + READ8(addr, mach64->dst_bres_lnth); break; case 0x124: case 0x125: case 0x126: case 0x127: - READ8(addr, mach64.dst_bres_err); + READ8(addr, mach64->dst_bres_err); break; case 0x128: case 0x129: case 0x12a: case 0x12b: - READ8(addr, mach64.dst_bres_inc); + READ8(addr, mach64->dst_bres_inc); break; case 0x12c: case 0x12d: case 0x12e: case 0x12f: - READ8(addr, mach64.dst_bres_dec); + READ8(addr, mach64->dst_bres_dec); break; case 0x130: case 0x131: case 0x132: case 0x133: - READ8(addr, mach64.dst_cntl); + READ8(addr, mach64->dst_cntl); break; case 0x180: case 0x181: case 0x182: case 0x183: - READ8(addr, mach64.src_off_pitch); + READ8(addr, mach64->src_off_pitch); break; case 0x184: case 0x185: - READ8(addr, mach64.src_y_x); + READ8(addr, mach64->src_y_x); break; case 0x188: case 0x189: - READ8(addr + 2, mach64.src_y_x); + READ8(addr + 2, mach64->src_y_x); break; case 0x18c: case 0x18d: case 0x18e: case 0x18f: - READ8(addr, mach64.src_y_x); + READ8(addr, mach64->src_y_x); break; case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: - READ8(addr, mach64.src_cntl); + READ8(addr, mach64->src_cntl); break; case 0x280: case 0x281: case 0x282: case 0x283: - READ8(addr, mach64.pat_reg0); + READ8(addr, mach64->pat_reg0); break; case 0x284: case 0x285: case 0x286: case 0x287: - READ8(addr, mach64.pat_reg1); + READ8(addr, mach64->pat_reg1); break; case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9: - READ8(addr, mach64.sc_left_right); + READ8(addr, mach64->sc_left_right); break; case 0x2a4: case 0x2a5: addr += 2; case 0x2aa: case 0x2ab: - READ8(addr, mach64.sc_left_right); + READ8(addr, mach64->sc_left_right); break; case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5: - READ8(addr, mach64.sc_top_bottom); + READ8(addr, mach64->sc_top_bottom); break; case 0x2b0: case 0x2b1: addr += 2; case 0x2b6: case 0x2b7: - READ8(addr, mach64.sc_top_bottom); + READ8(addr, mach64->sc_top_bottom); break; case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: - READ8(addr, mach64.dp_bkgd_clr); + READ8(addr, mach64->dp_bkgd_clr); break; case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: - READ8(addr, mach64.dp_frgd_clr); + READ8(addr, mach64->dp_frgd_clr); break; case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3: - READ8(addr, mach64.dp_pix_width); + READ8(addr, mach64->dp_pix_width); break; case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: - READ8(addr, mach64.dp_mix); + READ8(addr, mach64->dp_mix); break; case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: - READ8(addr, mach64.dp_src); + READ8(addr, mach64->dp_src); break; case 0x320: case 0x321: case 0x322: case 0x323: - READ8(addr, mach64.context_mask); + READ8(addr, mach64->context_mask); break; case 0x330: case 0x331: - READ8(addr, mach64.dst_cntl); + READ8(addr, mach64->dst_cntl); break; case 0x332: - READ8(addr - 2, mach64.src_cntl); + READ8(addr - 2, mach64->src_cntl); break; case 0x333: - READ8(addr - 3, mach64.pat_cntl); + READ8(addr - 3, mach64->pat_cntl); break; default: @@ -1030,8 +1068,9 @@ uint8_t mach64_ext_readb(uint32_t addr, void *priv) #endif return ret; } -uint16_t mach64_ext_readw(uint32_t addr, void *priv) +uint16_t mach64_ext_readw(uint32_t addr, void *p) { + mach64_t *mach64 = (mach64_t *)p; uint16_t ret; switch (addr & 0x3ff) { @@ -1039,11 +1078,11 @@ uint16_t mach64_ext_readw(uint32_t addr, void *priv) #ifdef MACH64_DEBUG pclog(" "); #endif - ret = mach64_ext_readb(addr, priv); + ret = mach64_ext_readb(addr, p); #ifdef MACH64_DEBUG pclog(" "); #endif - ret |= mach64_ext_readb(addr + 1, priv) << 8; + ret |= mach64_ext_readb(addr + 1, p) << 8; break; } #ifdef MACH64_DEBUG @@ -1051,33 +1090,34 @@ uint16_t mach64_ext_readw(uint32_t addr, void *priv) #endif return ret; } -uint32_t mach64_ext_readl(uint32_t addr, void *priv) +uint32_t mach64_ext_readl(uint32_t addr, void *p) { + mach64_t *mach64 = (mach64_t *)p; uint32_t ret; switch (addr & 0x3ff) { case 0x18: - ret = mach64.crtc_int_cntl & ~1; - if (cgastat & 8) + ret = mach64->crtc_int_cntl & ~1; + if (mach64->stat & 8) ret |= 1; break; case 0xb4: - ret = (mach64_bank_w[0] >> 15) | ((mach64_bank_w[1] >> 15) << 16); + ret = (mach64->bank_w[0] >> 15) | ((mach64->bank_w[1] >> 15) << 16); break; case 0xb8: - ret = (mach64_bank_r[0] >> 15) | ((mach64_bank_r[1] >> 15) << 16); + ret = (mach64->bank_r[0] >> 15) | ((mach64->bank_r[1] >> 15) << 16); break; default: #ifdef MACH64_DEBUG pclog(" "); #endif - ret = mach64_ext_readw(addr, priv); + ret = mach64_ext_readw(addr, p); #ifdef MACH64_DEBUG pclog(" "); #endif - ret |= mach64_ext_readw(addr + 2, priv) << 16; + ret |= mach64_ext_readw(addr + 2, p) << 16; break; } #ifdef MACH64_DEBUG @@ -1086,187 +1126,200 @@ uint32_t mach64_ext_readl(uint32_t addr, void *priv) return ret; } -void mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) +void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) { + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; #ifdef MACH64_DEBUG pclog("mach64_ext_writeb : addr %08X val %02X\n", addr, val); #endif switch (addr & 0x3ff) { case 0x00: case 0x01: case 0x02: case 0x03: - WRITE8(addr, mach64.crtc_h_total_disp, val); - svga_recalctimings(); + WRITE8(addr, mach64->crtc_h_total_disp, val); + svga_recalctimings(&mach64->svga); break; case 0x08: case 0x09: case 0x0a: case 0x0b: - WRITE8(addr, mach64.crtc_v_total_disp, val); - svga_recalctimings(); + WRITE8(addr, mach64->crtc_v_total_disp, val); + svga_recalctimings(&mach64->svga); break; case 0x0c: case 0x0d: case 0x0e: case 0x0f: - WRITE8(addr, mach64.crtc_v_sync_strt_wid, val); - svga_recalctimings(); + WRITE8(addr, mach64->crtc_v_sync_strt_wid, val); + svga_recalctimings(&mach64->svga); break; case 0x14: case 0x15: case 0x16: case 0x17: - WRITE8(addr, mach64.crtc_off_pitch, val); - svga_recalctimings(); + WRITE8(addr, mach64->crtc_off_pitch, val); + svga_recalctimings(&mach64->svga); fullchange = changeframecount; break; case 0x18: - mach64.crtc_int_cntl = val; + mach64->crtc_int_cntl = val; break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: - WRITE8(addr, mach64.crtc_gen_cntl, val); - svga_recalctimings(); + WRITE8(addr, mach64->crtc_gen_cntl, val); + svga_recalctimings(&mach64->svga); + break; + + case 0x40: case 0x41: case 0x42: case 0x43: + WRITE8(addr, mach64->ovr_clr, val); + break; + case 0x44: case 0x45: case 0x46: case 0x47: + WRITE8(addr, mach64->ovr_wid_left_right, val); + break; + case 0x48: case 0x49: case 0x4a: case 0x4b: + WRITE8(addr, mach64->ovr_wid_top_bottom, val); break; case 0x68: case 0x69: case 0x6a: case 0x6b: - WRITE8(addr, mach64.cur_offset, val); - svga_hwcursor.addr = (mach64.cur_offset & 0xfffff) * 8; - mach64_cursor_dump(); + WRITE8(addr, mach64->cur_offset, val); + svga->hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8; + mach64_cursor_dump(mach64); break; case 0x6c: case 0x6d: case 0x6e: case 0x6f: - WRITE8(addr, mach64.cur_horz_vert_posn, val); - svga_hwcursor.x = mach64.cur_horz_vert_posn & 0x7ff; - svga_hwcursor.y = (mach64.cur_horz_vert_posn >> 16) & 0x7ff; - mach64_cursor_dump(); + WRITE8(addr, mach64->cur_horz_vert_posn, val); + svga->hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff; + svga->hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff; + mach64_cursor_dump(mach64); break; case 0x70: case 0x71: case 0x72: case 0x73: - WRITE8(addr, mach64.cur_horz_vert_off, val); - svga_hwcursor.xoff = mach64.cur_horz_vert_off & 0x3f; - svga_hwcursor.yoff = (mach64.cur_horz_vert_off >> 16) & 0x3f; - mach64_cursor_dump(); + WRITE8(addr, mach64->cur_horz_vert_off, val); + svga->hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f; + svga->hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f; + mach64_cursor_dump(mach64); break; case 0x80: case 0x81: case 0x82: case 0x83: - WRITE8(addr, mach64.scratch_reg0, val); + WRITE8(addr, mach64->scratch_reg0, val); break; case 0x84: case 0x85: case 0x86: case 0x87: - WRITE8(addr, mach64.scratch_reg1, val); + WRITE8(addr, mach64->scratch_reg1, val); break; case 0x90: case 0x91: case 0x92: case 0x93: - WRITE8(addr, mach64.clock_cntl, val); - ics2595_write(val & 0x40, val & 0xf); + WRITE8(addr, mach64->clock_cntl, val); + ics2595_write(&mach64->ics2595, val & 0x40, val & 0xf); + svga_recalctimings(&mach64->svga); break; case 0xb0: case 0xb1: case 0xb2: case 0xb3: - WRITE8(addr, mach64.mem_cntl, val); + WRITE8(addr, mach64->mem_cntl, val); break; case 0xb4: - mach64_bank_w[0] = val * 32768; + mach64->bank_w[0] = val * 32768; #ifdef MACH64_DEBUG - pclog("mach64 : write bank A0000-A7FFF set to %08X\n", mach64_bank_w[0]); + pclog("mach64 : write bank A0000-A7FFF set to %08X\n", mach64->bank_w[0]); #endif break; case 0xb5: case 0xb6: - mach64_bank_w[1] = val * 32768; + mach64->bank_w[1] = val * 32768; #ifdef MACH64_DEBUG - pclog("mach64 : write bank A8000-AFFFF set to %08X\n", mach64_bank_w[1]); + pclog("mach64 : write bank A8000-AFFFF set to %08X\n", mach64->bank_w[1]); #endif break; case 0xb8: - mach64_bank_r[0] = val * 32768; + mach64->bank_r[0] = val * 32768; #ifdef MACH64_DEBUG - pclog("mach64 : read bank A0000-A7FFF set to %08X\n", mach64_bank_r[0]); + pclog("mach64 : read bank A0000-A7FFF set to %08X\n", mach64->bank_r[0]); #endif break; case 0xb9: case 0xba: - mach64_bank_r[1] = val * 32768; + mach64->bank_r[1] = val * 32768; #ifdef MACH64_DEBUG - pclog("mach64 : read bank A8000-AFFFF set to %08X\n", mach64_bank_r[1]); + pclog("mach64 : read bank A8000-AFFFF set to %08X\n", mach64->bank_r[1]); #endif break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: - WRITE8(addr, mach64.dac_cntl, val); + WRITE8(addr, mach64->dac_cntl, val); break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: - WRITE8(addr, mach64.gen_test_cntl, val); + WRITE8(addr, mach64->gen_test_cntl, val); // if (val == 2) output = 3; - ati_eeprom_write(mach64.gen_test_cntl & 0x10, mach64.gen_test_cntl & 2, mach64.gen_test_cntl & 1); - mach64.gen_test_cntl = (mach64.gen_test_cntl & ~8) | (ati_eeprom_read() ? 8 : 0); - svga_hwcursor.ena = mach64.gen_test_cntl & 0x80; - mach64_cursor_dump(); + ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1); + mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0); + svga->hwcursor.ena = mach64->gen_test_cntl & 0x80; + mach64_cursor_dump(mach64); break; case 0x100: case 0x101: case 0x102: case 0x103: - WRITE8(addr, mach64.dst_off_pitch, val); + WRITE8(addr, mach64->dst_off_pitch, val); break; case 0x104: case 0x105: case 0x11c: case 0x11d: - WRITE8(addr + 2, mach64.dst_y_x, val); + WRITE8(addr + 2, mach64->dst_y_x, val); break; case 0x108: case 0x109: - WRITE8(addr, mach64.dst_y_x, val); + WRITE8(addr, mach64->dst_y_x, val); break; case 0x10c: case 0x10d: case 0x10e: case 0x10f: - WRITE8(addr, mach64.dst_y_x, val); + WRITE8(addr, mach64->dst_y_x, val); break; case 0x110: case 0x111: addr += 2; case 0x114: case 0x115: case 0x118: case 0x119: case 0x11a: case 0x11b: case 0x11e: case 0x11f: - WRITE8(addr, mach64.dst_height_width, val); + WRITE8(addr, mach64->dst_height_width, val); if ((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f) { - mach64_start_fill(); + mach64_start_fill(mach64); #ifdef MACH64_DEBUG - pclog("%i %i %i %i %i\n", (mach64.dst_height_width & 0x7ff), (mach64.dst_height_width & 0x7ff0000), - ((mach64.dp_src & 7) != SRC_HOST), (((mach64.dp_src >> 8) & 7) != SRC_HOST), - (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST)); + pclog("%i %i %i %i %i\n", (mach64->dst_height_width & 0x7ff), (mach64->dst_height_width & 0x7ff0000), + ((mach64->dp_src & 7) != SRC_HOST), (((mach64->dp_src >> 8) & 7) != SRC_HOST), + (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)); #endif - if ((mach64.dst_height_width & 0x7ff) && (mach64.dst_height_width & 0x7ff0000) && - ((mach64.dp_src & 7) != SRC_HOST) && (((mach64.dp_src >> 8) & 7) != SRC_HOST) && - (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST)) - mach64_blit(0, -1); + if ((mach64->dst_height_width & 0x7ff) && (mach64->dst_height_width & 0x7ff0000) && + ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && + (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) + mach64_blit(0, -1, mach64); } break; case 0x120: case 0x121: case 0x122: case 0x123: - WRITE8(addr, mach64.dst_bres_lnth, val); + WRITE8(addr, mach64->dst_bres_lnth, val); if ((addr & 0x3ff) == 0x123 && !(val & 0x80)) { - mach64_start_line(); + mach64_start_line(mach64); - if ((mach64.dst_bres_lnth & 0x7fff) && - ((mach64.dp_src & 7) != SRC_HOST) && (((mach64.dp_src >> 8) & 7) != SRC_HOST) && - (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST)) - mach64_blit(0, -1); + if ((mach64->dst_bres_lnth & 0x7fff) && + ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && + (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) + mach64_blit(0, -1, mach64); } break; case 0x124: case 0x125: case 0x126: case 0x127: - WRITE8(addr, mach64.dst_bres_err, val); + WRITE8(addr, mach64->dst_bres_err, val); break; case 0x128: case 0x129: case 0x12a: case 0x12b: - WRITE8(addr, mach64.dst_bres_inc, val); + WRITE8(addr, mach64->dst_bres_inc, val); break; case 0x12c: case 0x12d: case 0x12e: case 0x12f: - WRITE8(addr, mach64.dst_bres_dec, val); + WRITE8(addr, mach64->dst_bres_dec, val); break; case 0x130: case 0x131: case 0x132: case 0x133: - WRITE8(addr, mach64.dst_cntl, val); + WRITE8(addr, mach64->dst_cntl, val); break; case 0x180: case 0x181: case 0x182: case 0x183: - WRITE8(addr, mach64.src_off_pitch, val); + WRITE8(addr, mach64->src_off_pitch, val); break; case 0x184: case 0x185: - WRITE8(addr, mach64.src_y_x, val); + WRITE8(addr, mach64->src_y_x, val); break; case 0x188: case 0x189: - WRITE8(addr + 2, mach64.src_y_x, val); + WRITE8(addr + 2, mach64->src_y_x, val); break; case 0x18c: case 0x18d: case 0x18e: case 0x18f: - WRITE8(addr, mach64.src_y_x, val); + WRITE8(addr, mach64->src_y_x, val); break; case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: - WRITE8(addr, mach64.src_cntl, val); + WRITE8(addr, mach64->src_cntl, val); break; case 0x200: case 0x201: case 0x202: case 0x203: @@ -1285,68 +1338,69 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) case 0x234: case 0x235: case 0x236: case 0x237: case 0x238: case 0x239: case 0x23a: case 0x23b: case 0x23c: case 0x23d: case 0x23e: case 0x23f: - mach64_blit(val, 8); + mach64_blit(val, 8, mach64); break; case 0x280: case 0x281: case 0x282: case 0x283: - WRITE8(addr, mach64.pat_reg0, val); + WRITE8(addr, mach64->pat_reg0, val); break; case 0x284: case 0x285: case 0x286: case 0x287: - WRITE8(addr, mach64.pat_reg1, val); + WRITE8(addr, mach64->pat_reg1, val); break; case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9: - WRITE8(addr, mach64.sc_left_right, val); + WRITE8(addr, mach64->sc_left_right, val); break; case 0x2a4: case 0x2a5: addr += 2; case 0x2aa: case 0x2ab: - WRITE8(addr, mach64.sc_left_right, val); + WRITE8(addr, mach64->sc_left_right, val); break; case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5: - WRITE8(addr, mach64.sc_top_bottom, val); + WRITE8(addr, mach64->sc_top_bottom, val); break; case 0x2b0: case 0x2b1: addr += 2; case 0x2b6: case 0x2b7: - WRITE8(addr, mach64.sc_top_bottom, val); + WRITE8(addr, mach64->sc_top_bottom, val); break; case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: - WRITE8(addr, mach64.dp_bkgd_clr, val); + WRITE8(addr, mach64->dp_bkgd_clr, val); break; case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: - WRITE8(addr, mach64.dp_frgd_clr, val); + WRITE8(addr, mach64->dp_frgd_clr, val); break; case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3: - WRITE8(addr, mach64.dp_pix_width, val); + WRITE8(addr, mach64->dp_pix_width, val); break; case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: - WRITE8(addr, mach64.dp_mix, val); + WRITE8(addr, mach64->dp_mix, val); break; case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: - WRITE8(addr, mach64.dp_src, val); + WRITE8(addr, mach64->dp_src, val); break; case 0x320: case 0x321: case 0x322: case 0x323: - WRITE8(addr, mach64.context_mask, val); + WRITE8(addr, mach64->context_mask, val); break; case 0x330: case 0x331: - WRITE8(addr, mach64.dst_cntl, val); + WRITE8(addr, mach64->dst_cntl, val); break; case 0x332: - WRITE8(addr - 2, mach64.src_cntl, val); + WRITE8(addr - 2, mach64->src_cntl, val); break; case 0x333: - WRITE8(addr - 3, mach64.pat_cntl, val & 7); + WRITE8(addr - 3, mach64->pat_cntl, val & 7); break; } } -void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv) +void mach64_ext_writew(uint32_t addr, uint16_t val, void *p) { + mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG pclog("mach64_ext_writew : addr %08X val %04X\n", addr, val); #endif @@ -1360,23 +1414,24 @@ void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv) case 0x228: case 0x22a: case 0x22c: case 0x22e: case 0x230: case 0x232: case 0x234: case 0x236: case 0x238: case 0x23a: case 0x23c: case 0x23e: - mach64_blit(val, 16); + mach64_blit(val, 16, mach64); break; default: #ifdef MACH64_DEBUG pclog(" "); #endif - mach64_ext_writeb(addr, val, priv); + mach64_ext_writeb(addr, val, p); #ifdef MACH64_DEBUG pclog(" "); #endif - mach64_ext_writeb(addr + 1, val >> 8, priv); + mach64_ext_writeb(addr + 1, val >> 8, p); break; } } -void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv) +void mach64_ext_writel(uint32_t addr, uint32_t val, void *p) { + mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG if ((addr & 0x3c0) != 0x200) pclog("mach64_ext_writel : addr %08X val %08X\n", addr, val); @@ -1384,123 +1439,135 @@ void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv) switch (addr & 0x3fc) { case 0x32c: - mach64.context_load_cntl = val; + mach64->context_load_cntl = val; if (val & 0x30000) - mach64_load_context(); + mach64_load_context(mach64); break; case 0x200: case 0x204: case 0x208: case 0x20c: case 0x210: case 0x214: case 0x218: case 0x21c: case 0x220: case 0x224: case 0x228: case 0x22c: case 0x230: case 0x234: case 0x238: case 0x23c: - if (mach64.accel.source_host) - mach64_blit(val, 32); + if (mach64->accel.source_host) + mach64_blit(val, 32, mach64); else - mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32); + mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32, mach64); break; default: #ifdef MACH64_DEBUG pclog(" "); #endif - mach64_ext_writew(addr, val, priv); + mach64_ext_writew(addr, val, p); #ifdef MACH64_DEBUG pclog(" "); #endif - mach64_ext_writew(addr + 2, val >> 16, priv); + mach64_ext_writew(addr + 2, val >> 16, p); break; } } -uint8_t mach64_ext_inb(uint16_t port, void *priv) +uint8_t mach64_ext_inb(uint16_t port, void *p) { + mach64_t *mach64 = (mach64_t *)p; uint8_t ret; // if (CS == 0x2be7) output = 3; switch (port) { case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef: - ret = mach64_ext_readb(0x00 | (port & 3), NULL); + case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef: + ret = mach64_ext_readb(0x00 | (port & 3), p); break; case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: - ret = mach64_ext_readb(0x08 | (port & 3), NULL); + ret = mach64_ext_readb(0x08 | (port & 3), p); break; case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: - ret = mach64_ext_readb(0x0c | (port & 3), NULL); + ret = mach64_ext_readb(0x0c | (port & 3), p); break; case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: - ret = mach64_ext_readb(0x14 | (port & 3), NULL); + ret = mach64_ext_readb(0x14 | (port & 3), p); break; case 0x1aec: - ret = mach64_ext_readb(0x18, NULL); + ret = mach64_ext_readb(0x18, p); break; case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: - ret = mach64_ext_readb(0x1c | (port & 3), NULL); + ret = mach64_ext_readb(0x1c | (port & 3), p); + break; + + case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef: + ret = mach64_ext_readb(0x40 | (port & 3), p); + break; + case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef: + ret = mach64_ext_readb(0x44 | (port & 3), p); + break; + case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef: + ret = mach64_ext_readb(0x48 | (port & 3), p); break; case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: - ret = mach64_ext_readb(0x68 | (port & 3), NULL); + ret = mach64_ext_readb(0x68 | (port & 3), p); break; case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: - ret = mach64_ext_readb(0x6c | (port & 3), NULL); + ret = mach64_ext_readb(0x6c | (port & 3), p); break; case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: - ret = mach64_ext_readb(0x70 | (port & 3), NULL); + ret = mach64_ext_readb(0x70 | (port & 3), p); break; case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: - ret = mach64_ext_readb(0x80 | (port & 3), NULL); + ret = mach64_ext_readb(0x80 | (port & 3), p); break; case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: - ret = mach64_ext_readb(0x84 | (port & 3), NULL); + ret = mach64_ext_readb(0x84 | (port & 3), p); break; case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: - ret = mach64_ext_readb(0x90 | (port & 3), NULL); + ret = mach64_ext_readb(0x90 | (port & 3), p); break; case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: - ret = mach64_ext_readb(0xb0 | (port & 3), NULL); + ret = mach64_ext_readb(0xb0 | (port & 3), p); break; case 0x56ec: - ret = mach64_ext_readb(0xb4, NULL); + ret = mach64_ext_readb(0xb4, p); break; case 0x56ed: case 0x56ee: - ret = mach64_ext_readb(0xb5, NULL); + ret = mach64_ext_readb(0xb5, p); break; case 0x5aec: - ret = mach64_ext_readb(0xb8, NULL); + ret = mach64_ext_readb(0xb8, p); break; case 0x5aed: case 0x5aee: - ret = mach64_ext_readb(0xb9, NULL); + ret = mach64_ext_readb(0xb9, p); break; case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: - ret = ati68860_ramdac_in((port & 3) | ((mach64.dac_cntl & 3) << 2), NULL); + ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); break; case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: - ret = mach64_ext_readb(0xc4 | (port & 3), NULL); + ret = mach64_ext_readb(0xc4 | (port & 3), p); break; case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: - ret = mach64_ext_readb(0xd0 | (port & 3), NULL); + ret = mach64_ext_readb(0xd0 | (port & 3), p); break; case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: - READ8(port, mach64.config_cntl); + READ8(port, mach64->config_cntl); break; case 0x6eec: case 0x6eed: case 0x6eee: case 0x6eef: - ret = mach64_ext_readb(0xe0 | (port & 3), NULL); + ret = mach64_ext_readb(0xe0 | (port & 3), p); break; case 0x72ec: ret = 6 | (3 << 3); /*VLB, 256Kx16 DRAM*/ break; - + default: ret = 0; break; @@ -1510,16 +1577,17 @@ uint8_t mach64_ext_inb(uint16_t port, void *priv) #endif return ret; } -uint16_t mach64_ext_inw(uint16_t port, void *priv) +uint16_t mach64_ext_inw(uint16_t port, void *p) { + mach64_t *mach64 = (mach64_t *)p; uint16_t ret; switch (port) { default: pclog(" "); - ret = mach64_ext_inb(port, priv); + ret = mach64_ext_inb(port, p); pclog(" "); - ret |= (mach64_ext_inb(port + 1, priv) << 8); + ret |= (mach64_ext_inb(port + 1, p) << 8); break; } #ifdef MACH64_DEBUG @@ -1527,23 +1595,24 @@ uint16_t mach64_ext_inw(uint16_t port, void *priv) #endif return ret; } -uint32_t mach64_ext_inl(uint16_t port, void *priv) +uint32_t mach64_ext_inl(uint16_t port, void *p) { + mach64_t *mach64 = (mach64_t *)p; uint32_t ret; switch (port) { case 0x56ec: - ret = mach64_ext_readl(0xb4, NULL); + ret = mach64_ext_readl(0xb4, p); break; case 0x5aec: - ret = mach64_ext_readl(0xb8, NULL); + ret = mach64_ext_readl(0xb8, p); break; default: pclog(" "); - ret = mach64_ext_inw(port, priv); + ret = mach64_ext_inw(port, p); pclog(" "); - ret |= (mach64_ext_inw(port + 2, priv) << 16); + ret |= (mach64_ext_inw(port + 2, p) << 16); break; } #ifdef MACH64_DEBUG @@ -1552,8 +1621,9 @@ uint32_t mach64_ext_inl(uint16_t port, void *priv) return ret; } -void mach64_ext_outb(uint16_t port, uint8_t val, void *priv) +void mach64_ext_outb(uint16_t port, uint8_t val, void *p) { + mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG pclog("mach64_ext_outb : port %04X val %02X %04X:%04X\n", port, val, CS,pc); #endif @@ -1561,83 +1631,94 @@ void mach64_ext_outb(uint16_t port, uint8_t val, void *priv) { case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef: case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef: - mach64_ext_writeb(0x00 | (port & 3), val, NULL); + mach64_ext_writeb(0x00 | (port & 3), val, p); break; case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: - mach64_ext_writeb(0x08 | (port & 3), val, NULL); + mach64_ext_writeb(0x08 | (port & 3), val, p); break; case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: - mach64_ext_writeb(0x0c | (port & 3), val, NULL); + mach64_ext_writeb(0x0c | (port & 3), val, p); break; case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: - mach64_ext_writeb(0x14 | (port & 3), val, NULL); + mach64_ext_writeb(0x14 | (port & 3), val, p); break; case 0x1aec: - mach64_ext_writeb(0x18, val, NULL); + mach64_ext_writeb(0x18, val, p); break; case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: - mach64_ext_writeb(0x1c | (port & 3), val, NULL); + mach64_ext_writeb(0x1c | (port & 3), val, p); + break; + + case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef: + mach64_ext_writeb(0x40 | (port & 3), val, p); + break; + case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef: + mach64_ext_writeb(0x44 | (port & 3), val, p); + break; + case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef: + mach64_ext_writeb(0x48 | (port & 3), val, p); break; case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: - mach64_ext_writeb(0x68 | (port & 3), val, NULL); + mach64_ext_writeb(0x68 | (port & 3), val, p); break; case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: - mach64_ext_writeb(0x6c | (port & 3), val, NULL); + mach64_ext_writeb(0x6c | (port & 3), val, p); break; case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: - mach64_ext_writeb(0x70 | (port & 3), val, NULL); + mach64_ext_writeb(0x70 | (port & 3), val, p); break; case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: - mach64_ext_writeb(0x80 | (port & 3), val, NULL); + mach64_ext_writeb(0x80 | (port & 3), val, p); break; case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: - mach64_ext_writeb(0x84 | (port & 3), val, NULL); + mach64_ext_writeb(0x84 | (port & 3), val, p); break; case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: - mach64_ext_writeb(0x90 | (port & 3), val, NULL); + mach64_ext_writeb(0x90 | (port & 3), val, p); break; case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: - mach64_ext_writeb(0xb0 | (port & 3), val, NULL); + mach64_ext_writeb(0xb0 | (port & 3), val, p); break; case 0x56ec: - mach64_ext_writeb(0xb4, val, NULL); + mach64_ext_writeb(0xb4, val, p); break; case 0x56ed: case 0x56ee: - mach64_ext_writeb(0xb5, val, NULL); + mach64_ext_writeb(0xb5, val, p); break; case 0x5aec: - mach64_ext_writeb(0xb8, val, NULL); + mach64_ext_writeb(0xb8, val, p); break; case 0x5aed: case 0x5aee: - mach64_ext_writeb(0xb9, val, NULL); + mach64_ext_writeb(0xb9, val, p); break; case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: - ati68860_ramdac_out((port & 3) | ((mach64.dac_cntl & 3) << 2), val, NULL); + ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); break; case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: - mach64_ext_writeb(0xc4 | (port & 3), val, NULL); + mach64_ext_writeb(0xc4 | (port & 3), val, p); break; case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: - mach64_ext_writeb(0xd0 | (port & 3), val, NULL); + mach64_ext_writeb(0xd0 | (port & 3), val, p); break; case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: - WRITE8(port, mach64.config_cntl, val); + WRITE8(port, mach64->config_cntl, val); break; } } -void mach64_ext_outw(uint16_t port, uint16_t val, void *priv) +void mach64_ext_outw(uint16_t port, uint16_t val, void *p) { + mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG pclog("mach64_ext_outw : port %04X val %04X\n", port, val); #endif @@ -1647,16 +1728,17 @@ void mach64_ext_outw(uint16_t port, uint16_t val, void *priv) #ifdef MACH64_DEBUG pclog(" "); #endif - mach64_ext_outb(port, val, priv); + mach64_ext_outb(port, val, p); #ifdef MACH64_DEBUG pclog(" "); #endif - mach64_ext_outb(port + 1, val >> 8, priv); + mach64_ext_outb(port + 1, val >> 8, p); break; } } -void mach64_ext_outl(uint16_t port, uint32_t val, void *priv) +void mach64_ext_outl(uint16_t port, uint32_t val, void *p) { + mach64_t *mach64 = (mach64_t *)p; pclog("mach64_ext_outl : port %04X val %08X\n", port, val); switch (port) { @@ -1664,104 +1746,113 @@ void mach64_ext_outl(uint16_t port, uint32_t val, void *priv) #ifdef MACH64_DEBUG pclog(" "); #endif - mach64_ext_outw(port, val, priv); + mach64_ext_outw(port, val, p); #ifdef MACH64_DEBUG pclog(" "); #endif - mach64_ext_outw(port + 2, val >> 16, priv); + mach64_ext_outw(port + 2, val >> 16, p); break; } } -void mach64_write(uint32_t addr, uint8_t val, void *priv) +void mach64_write(uint32_t addr, uint8_t val, void *p) { + mach64_t *mach64 = (mach64_t *)p; // pclog("mach64_write : %05X %02X ", addr, val); - addr = (addr & 0x7fff) + mach64_bank_w[(addr >> 15) & 1]; + addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; // pclog("%08X\n", addr); - svga_write_linear(addr, val, priv); + svga_write_linear(addr, val, p); } -uint8_t mach64_read(uint32_t addr, void *priv) +uint8_t mach64_read(uint32_t addr, void *p) { + mach64_t *mach64 = (mach64_t *)p; uint8_t ret; // pclog("mach64_read : %05X ", addr); - addr = (addr & 0x7fff) + mach64_bank_r[(addr >> 15) & 1]; - ret = svga_read_linear(addr, priv); + addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; + ret = svga_read_linear(addr, p); // pclog("%08X %02X\n", addr, ret); return ret; } -void mach64_hwcursor_draw(int displine) +void mach64_hwcursor_draw(svga_t *svga, int displine) { int x, offset; uint8_t dat; - offset = svga_hwcursor_latch.xoff; - for (x = 0; x < 64 - svga_hwcursor_latch.xoff; x += 4) + offset = svga->hwcursor_latch.xoff; + for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { - dat = vram[svga_hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32] ^= 0xFFFFFF; + dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF; dat >>= 2; offset += 4; } - svga_hwcursor_latch.addr += 16; + svga->hwcursor_latch.addr += 16; } -int mach64_init() +void *mach64gx_init() { int c; + mach64_t *mach64 = malloc(sizeof(mach64_t)); + memset(mach64, 0, sizeof(mach64_t)); - svga_recalctimings_ex = mach64_recalctimings; - svga_hwcursor_draw = mach64_hwcursor_draw; - - svga_vram_limit = 1 << 22; /*4mb*/ - vrammask = 0x3fffff; + svga_init(&mach64->svga, mach64, 1 << 22, /*4mb*/ + mach64_recalctimings, + mach64_in, mach64_out, + mach64_hwcursor_draw); + + io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); for (c = 0; c < 8; c++) { - io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL); - io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL); - io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL); - io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL); + io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); } - io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, NULL); + io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - ati_eeprom_load("mach64.nvr", 1); + ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); - mach64.dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ + mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ - mach64.dst_cntl = 3; - return svga_init(); + mach64->dst_cntl = 3; + + return mach64; } -GFXCARD vid_mach64 = +void mach64_close(void *p) { - mach64_init, - /*IO at 3Cx/3Dx*/ - mach64_out, - mach64_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, + mach64_t *mach64 = (mach64_t *)p; - svga_poll, - svga_recalctimings, + svga_close(&mach64->svga); + + free(mach64); +} - svga_write, - video_write_null, - video_write_null, +void mach64_speed_changed(void *p) +{ + mach64_t *mach64 = (mach64_t *)p; + + svga_recalctimings(&mach64->svga); +} - svga_read, - video_read_null, - video_read_null +device_t mach64gx_device = +{ + "ATI Mach64GX", + mach64gx_init, + mach64_close, + mach64_speed_changed, + svga_add_status_info }; diff --git a/src/vid_ati_mach64.h b/src/vid_ati_mach64.h new file mode 100644 index 0000000..efc694d --- /dev/null +++ b/src/vid_ati_mach64.h @@ -0,0 +1 @@ +extern device_t mach64gx_device; diff --git a/src/vid_cga.c b/src/vid_cga.c index 662a38f..ceab7fc 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -1,110 +1,115 @@ /*CGA emulation*/ +#include #include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "timer.h" #include "video.h" #include "vid_cga.h" -void cga_recalctimings(); +static int i_filt[8],q_filt[8]; -void cga_out(uint16_t addr, uint8_t val, void *priv) +static uint8_t crtcmask[32] = { + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +void cga_recalctimings(cga_t *cga); + +void cga_out(uint16_t addr, uint8_t val, void *p) +{ + cga_t *cga = (cga_t *)p; uint8_t old; // pclog("CGA_OUT %04X %02X\n", addr, val); switch (addr) { case 0x3D4: - crtcreg=val&31; + cga->crtcreg = val & 31; return; case 0x3D5: - old=crtc[crtcreg]; - crtc[crtcreg]=val&crtcmask[crtcreg]; - if (old!=val) + old = cga->crtc[cga->crtcreg]; + cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (cga->crtcreg < 0xe || cga->crtcreg > 0x10) { - fullchange=changeframecount; - cga_recalctimings(); + fullchange = changeframecount; + cga_recalctimings(cga); } } return; case 0x3D8: - cgamode=val; + cga->cgamode = val; return; case 0x3D9: - cgacol=val; + cga->cgacol = val; return; } } -uint8_t cga_in(uint16_t addr, void *priv) +uint8_t cga_in(uint16_t addr, void *p) { + cga_t *cga = (cga_t *)p; // pclog("CGA_IN %04X\n", addr); switch (addr) { case 0x3D4: - return crtcreg; + return cga->crtcreg; case 0x3D5: - return crtc[crtcreg]; + return cga->crtc[cga->crtcreg]; case 0x3DA: - return cgastat; + return cga->cgastat; } return 0xFF; } -extern uint8_t charbuffer[256]; - -void cga_write(uint32_t addr, uint8_t val, void *priv) +void cga_write(uint32_t addr, uint8_t val, void *p) { + cga_t *cga = (cga_t *)p; // pclog("CGA_WRITE %04X %02X\n", addr, val); - vram[addr&0x3FFF]=val; - charbuffer[ ((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc] = val; - charbuffer[(((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val; + cga->vram[addr & 0x3fff] = val; + cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = val; + cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val; cycles -= 4; } -uint8_t cga_read(uint32_t addr, void *priv) +uint8_t cga_read(uint32_t addr, void *p) { + cga_t *cga = (cga_t *)p; cycles -= 4; - charbuffer[ ((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc] = vram[addr&0x3FFF]; - charbuffer[(((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc) | 1] = vram[addr&0x3FFF]; + cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = cga->vram[addr & 0x3fff]; + cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = cga->vram[addr & 0x3fff]; // pclog("CGA_READ %04X\n", addr); - return vram[addr&0x3FFF]; + return cga->vram[addr & 0x3fff]; } -void cga_recalctimings() +void cga_recalctimings(cga_t *cga) { + double disptime; double _dispontime, _dispofftime; - pclog("Recalc - %i %i %i\n", crtc[0], crtc[1], cgamode & 1); - if (cgamode&1) + pclog("Recalc - %i %i %i\n", cga->crtc[0], cga->crtc[1], cga->cgamode & 1); + if (cga->cgamode & 1) { - disptime=crtc[0]+1; - _dispontime=crtc[1]; + disptime = cga->crtc[0] + 1; + _dispontime = cga->crtc[1]; } else { - disptime=(crtc[0]+1)<<1; - _dispontime=crtc[1]<<1; + disptime = (cga->crtc[0] + 1) << 1; + _dispontime = cga->crtc[1] << 1; } - _dispofftime=disptime-_dispontime; + _dispofftime = disptime - _dispontime; // printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); - _dispontime*=CGACONST; - _dispofftime*=CGACONST; + _dispontime *= CGACONST; + _dispofftime *= CGACONST; // printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); - dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + cga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + cga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } -static int linepos,displine; -static int sc,vc; -static int cgadispon; -static int con,coff,cursoron,cgablink; -static int vsynctime,vadj; -static uint16_t ma,maback; -static int oddeven = 0; - static int ntsc_col[8][8]= { {0,0,0,0,0,0,0,0}, /*Black*/ @@ -117,326 +122,331 @@ static int ntsc_col[8][8]= {1,1,1,1,1,1,1,1} /*White*/ }; -int i_filt[8],q_filt[8]; - - -void cga_poll() +void cga_poll(void *p) { - uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF; + cga_t *cga = (cga_t *)p; + uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; int drawcursor; - int x,c; + int x, c; int oldvc; - uint8_t chr,attr; + uint8_t chr, attr; uint16_t dat; int cols[4]; int col; int oldsc; - int y_buf[8]={0,0,0,0,0,0,0,0},y_val,y_tot; - int i_buf[8]={0,0,0,0,0,0,0,0},i_val,i_tot; - int q_buf[8]={0,0,0,0,0,0,0,0},q_val,q_tot; - int r,g,b; - if (!linepos) + int y_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, y_val, y_tot; + int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_tot; + int q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot; + int r, g, b; + if (!cga->linepos) { - vidtime+=dispofftime; - cgastat|=1; - linepos=1; - oldsc=sc; - if ((crtc[8] & 3) == 3) - sc = ((sc << 1) + oddeven) & 7; - if (cgadispon) + cga->vidtime += cga->dispofftime; + cga->cgastat |= 1; + cga->linepos = 1; + oldsc = cga->sc; + if ((cga->crtc[8] & 3) == 3) + cga->sc = ((cga->sc << 1) + cga->oddeven) & 7; + if (cga->cgadispon) { - if (displinedispline < cga->firstline) { - firstline=displine; + cga->firstline = cga->displine; // printf("Firstline %i\n",firstline); } - lastline=displine; - for (c=0;c<8;c++) + cga->lastline = cga->displine; + for (c = 0; c < 8; c++) { - if ((cgamode&0x12)==0x12) + if ((cga->cgamode & 0x12) == 0x12) { - buffer->line[displine][c]=0; - if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0; - else buffer->line[displine][c+(crtc[1]<<4)+8]=0; + buffer->line[cga->displine][c] = 0; + if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = 0; + else buffer->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = 0; } else { - buffer->line[displine][c]=(cgacol&15)+16; - if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16; - else buffer->line[displine][c+(crtc[1]<<4)+8]=(cgacol&15)+16; + buffer->line[cga->displine][c] = (cga->cgacol & 15) + 16; + if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; + else buffer->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; } } - if (cgamode&1) + if (cga->cgamode & 1) { - for (x=0;xcrtc[1]; x++) { - chr=charbuffer[x<<1]; - attr=charbuffer[(x<<1)+1]; - drawcursor=((ma==ca) && con && cursoron); - if (cgamode&0x20) + chr = cga->charbuffer[x << 1]; + attr = cga->charbuffer[(x << 1) + 1]; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + if (cga->cgamode & 0x20) { - cols[1]=(attr&15)+16; - cols[0]=((attr>>4)&7)+16; - if ((cgablink&8) && (attr&0x80) && !drawcursor) cols[1]=cols[0]; + cols[1] = (attr & 15) + 16; + cols[0] = ((attr >> 4) & 7) + 16; + if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) + cols[1] = cols[0]; } else { - cols[1]=(attr&15)+16; - cols[0]=(attr>>4)+16; + cols[1] = (attr & 15) + 16; + cols[0] = (attr >> 4) + 16; } if (drawcursor) { - for (c=0;c<8;c++) - buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15; + for (c = 0; c < 8; c++) + buffer->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { - for (c=0;c<8;c++) - buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]; + for (c = 0; c < 8; c++) + buffer->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } - ma++; + cga->ma++; } } - else if (!(cgamode&2)) + else if (!(cga->cgamode & 2)) { - for (x=0;xcrtc[1]; x++) { - chr=vram[((ma<<1)&0x3FFF)]; - attr=vram[(((ma<<1)+1)&0x3FFF)]; - drawcursor=((ma==ca) && con && cursoron); - if (cgamode&0x20) + chr = cga->vram[((cga->ma << 1) & 0x3fff)]; + attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + if (cga->cgamode & 0x20) { - cols[1]=(attr&15)+16; - cols[0]=((attr>>4)&7)+16; - if ((cgablink&8) && (attr&0x80)) cols[1]=cols[0]; + cols[1] = (attr & 15) + 16; + cols[0] = ((attr >> 4) & 7) + 16; + if ((cga->cgablink & 8) && (attr & 0x80)) cols[1] = cols[0]; } else { - cols[1]=(attr&15)+16; - cols[0]=(attr>>4)+16; + cols[1] = (attr & 15) + 16; + cols[0] = (attr >> 4) + 16; } - ma++; + cga->ma++; if (drawcursor) { - for (c=0;c<8;c++) - buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15; + for (c = 0; c < 8; c++) + buffer->line[cga->displine][(x << 4)+(c << 1) + 8] = buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { - for (c=0;c<8;c++) - buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]; + for (c = 0; c < 8; c++) + buffer->line[cga->displine][(x << 4) + (c << 1) + 8] = buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } } - else if (!(cgamode&16)) + else if (!(cga->cgamode & 16)) { - cols[0]=(cgacol&15)|16; - col=(cgacol&16)?24:16; - if (cgamode&4) + cols[0] = (cga->cgacol & 15) | 16; + col = (cga->cgacol & 16) ? 24 : 16; + if (cga->cgamode & 4) { - cols[1]=col|3; - cols[2]=col|4; - cols[3]=col|7; + cols[1] = col | 3; + cols[2] = col | 4; + cols[3] = col | 7; } - else if (cgacol&32) + else if (cga->cgacol & 32) { - cols[1]=col|3; - cols[2]=col|5; - cols[3]=col|7; + cols[1] = col | 3; + cols[2] = col | 5; + cols[3] = col | 7; } else { - cols[1]=col|2; - cols[2]=col|4; - cols[3]=col|6; + cols[1] = col | 2; + cols[2] = col | 4; + cols[3] = col | 6; } - for (x=0;xcrtc[1]; x++) { - dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1]; - ma++; - for (c=0;c<8;c++) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + cga->ma++; + for (c = 0; c < 8; c++) { - buffer->line[displine][(x<<4)+(c<<1)+8]= - buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14]; - dat<<=2; + buffer->line[cga->displine][(x << 4) + (c << 1) + 8] = + buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + dat <<= 2; } } } else { - cols[0]=0; cols[1]=(cgacol&15)+16; - for (x=0;xcgacol & 15) + 16; + for (x = 0; x < cga->crtc[1]; x++) { - dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1]; - ma++; - for (c=0;c<16;c++) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + cga->ma++; + for (c = 0; c < 16; c++) { - buffer->line[displine][(x<<4)+c+8]=cols[dat>>15]; - dat<<=1; + buffer->line[cga->displine][(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; } } } } else { - cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16; - if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]); - else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]); + cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; + if (cga->cgamode & 1) hline(buffer, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]); + else hline(buffer, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]); } - if (cgamode&1) x=(crtc[1]<<3)+16; - else x=(crtc[1]<<4)+16; + if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16; + else x = (cga->crtc[1] << 4) + 16; if (cga_comp) { - for (c=0;cline[displine][c]&7][(c<<1)&6]?0x6000:0; - y_buf[(c<<1)&6]+=(buffer->line[displine][c]&8)?0x3000:0; - i_buf[(c<<1)&6]=y_buf[(c<<1)&6]*i_filt[(c<<1)&6]; - q_buf[(c<<1)&6]=y_buf[(c<<1)&6]*q_filt[(c<<1)&6]; - y_tot=y_buf[0]+y_buf[1]+y_buf[2]+y_buf[3]+y_buf[4]+y_buf[5]+y_buf[6]+y_buf[7]; - i_tot=i_buf[0]+i_buf[1]+i_buf[2]+i_buf[3]+i_buf[4]+i_buf[5]+i_buf[6]+i_buf[7]; - q_tot=q_buf[0]+q_buf[1]+q_buf[2]+q_buf[3]+q_buf[4]+q_buf[5]+q_buf[6]+q_buf[7]; + y_buf[(c << 1) & 6] = ntsc_col[buffer->line[cga->displine][c] & 7][(c << 1) & 6] ? 0x6000 : 0; + y_buf[(c << 1) & 6] += (buffer->line[cga->displine][c] & 8) ? 0x3000 : 0; + i_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * i_filt[(c << 1) & 6]; + q_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * q_filt[(c << 1) & 6]; + y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7]; + i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7]; + q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7]; - y_val=y_tot>>10; - if (y_val>255) y_val=255; - y_val<<=16; - i_val=i_tot>>12; - if (i_val>39041) i_val=39041; - if (i_val<-39041) i_val=-39041; - q_val=q_tot>>12; - if (q_val>34249) q_val=34249; - if (q_val<-34249) q_val=-34249; + y_val = y_tot >> 10; + if (y_val > 255) y_val = 255; + y_val <<= 16; + i_val = i_tot >> 12; + if (i_val > 39041) i_val = 39041; + if (i_val < -39041) i_val = -39041; + q_val = q_tot >> 12; + if (q_val > 34249) q_val = 34249; + if (q_val < -34249) q_val = -34249; - r=(y_val+249*i_val+159*q_val)>>16; - g=(y_val-70*i_val-166*q_val)>>16; - b=(y_val-283*i_val+436*q_val)>>16; + r = (y_val + 249*i_val + 159*q_val) >> 16; + g = (y_val - 70*i_val - 166*q_val) >> 16; + b = (y_val - 283*i_val + 436*q_val) >> 16; - y_buf[((c<<1)&6)+1]=ntsc_col[buffer->line[displine][c]&7][((c<<1)&6)+1]?0x6000:0; - y_buf[((c<<1)&6)+1]+=(buffer->line[displine][c]&8)?0x3000:0; - i_buf[((c<<1)&6)+1]=y_buf[((c<<1)&6)+1]*i_filt[((c<<1)&6)+1]; - q_buf[((c<<1)&6)+1]=y_buf[((c<<1)&6)+1]*q_filt[((c<<1)&6)+1]; - y_tot=y_buf[0]+y_buf[1]+y_buf[2]+y_buf[3]+y_buf[4]+y_buf[5]+y_buf[6]+y_buf[7]; - i_tot=i_buf[0]+i_buf[1]+i_buf[2]+i_buf[3]+i_buf[4]+i_buf[5]+i_buf[6]+i_buf[7]; - q_tot=q_buf[0]+q_buf[1]+q_buf[2]+q_buf[3]+q_buf[4]+q_buf[5]+q_buf[6]+q_buf[7]; + y_buf[((c << 1) & 6) + 1] = ntsc_col[buffer->line[cga->displine][c] & 7][((c << 1) & 6) + 1] ? 0x6000 : 0; + y_buf[((c << 1) & 6) + 1] += (buffer->line[cga->displine][c] & 8) ? 0x3000 : 0; + i_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * i_filt[((c << 1) & 6) + 1]; + q_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * q_filt[((c << 1) & 6) + 1]; + y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7]; + i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7]; + q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7]; - y_val=y_tot>>10; - if (y_val>255) y_val=255; - y_val<<=16; - i_val=i_tot>>12; - if (i_val>39041) i_val=39041; - if (i_val<-39041) i_val=-39041; - q_val=q_tot>>12; - if (q_val>34249) q_val=34249; - if (q_val<-34249) q_val=-34249; + y_val = y_tot >> 10; + if (y_val > 255) y_val = 255; + y_val <<= 16; + i_val = i_tot >> 12; + if (i_val > 39041) i_val = 39041; + if (i_val < -39041) i_val = -39041; + q_val = q_tot >> 12; + if (q_val > 34249) q_val = 34249; + if (q_val < -34249) q_val = -34249; - r+=(y_val+249*i_val+159*q_val)>>16; - g+=(y_val-70*i_val-166*q_val)>>16; - b+=(y_val-283*i_val+436*q_val)>>16; - if (r>511) r=511; - if (g>511) g=511; - if (b>511) b=511; + r = (y_val + 249*i_val + 159*q_val) >> 16; + g = (y_val - 70*i_val - 166*q_val) >> 16; + b = (y_val - 283*i_val + 436*q_val) >> 16; + if (r > 511) r = 511; + if (g > 511) g = 511; + if (b > 511) b = 511; - ((uint32_t *)buffer32->line[displine])[c]=makecol32(r/2,g/2,b/2); + ((uint32_t *)buffer32->line[cga->displine])[c] = makecol32(r / 2, g / 2, b / 2); } } - sc=oldsc; - if (vc==crtc[7] && !sc) - cgastat|=8; - displine++; - if (displine>=360) displine=0; + cga->sc = oldsc; + if (cga->vc == cga->crtc[7] && !cga->sc) + cga->cgastat |= 8; + cga->displine++; + if (cga->displine >= 360) + cga->displine = 0; } else { - vidtime+=dispontime; - if (cgadispon) cgastat&=~1; - linepos=0; - if (vsynctime) + cga->vidtime += cga->dispontime; + if (cga->cgadispon) cga->cgastat &= ~1; + cga->linepos = 0; + if (cga->vsynctime) { - vsynctime--; - if (!vsynctime) - cgastat&=~8; + cga->vsynctime--; + if (!cga->vsynctime) + cga->cgastat &= ~8; } - if (sc==(crtc[11]&31) || ((crtc[8]&3)==3 && sc==((crtc[11]&31)>>1))) { con=0; coff=1; } - if ((crtc[8] & 3) == 3 && sc == (crtc[9] >> 1)) - maback = ma; - if (vadj) + if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) + { + cga->con = 0; + cga->coff = 1; + } + if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1)) + cga->maback = cga->ma; + if (cga->vadj) { - sc++; - sc&=31; - ma=maback; - vadj--; - if (!vadj) + cga->sc++; + cga->sc &= 31; + cga->ma = cga->maback; + cga->vadj--; + if (!cga->vadj) { - cgadispon=1; - ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF; - sc=0; + cga->cgadispon = 1; + cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; + cga->sc = 0; } } - else if (sc==crtc[9]) + else if (cga->sc == cga->crtc[9]) { - maback=ma; - sc=0; - oldvc=vc; - vc++; - vc&=127; + cga->maback = cga->ma; + cga->sc = 0; + oldvc = cga->vc; + cga->vc++; + cga->vc &= 127; - if (vc==crtc[6]) cgadispon=0; + if (cga->vc == cga->crtc[6]) + cga->cgadispon = 0; - if (oldvc==crtc[4]) + if (oldvc == cga->crtc[4]) { - vc=0; - vadj=crtc[5]; - if (!vadj) cgadispon=1; - if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF; - if ((crtc[10]&0x60)==0x20) cursoron=0; - else cursoron=cgablink&8; + cga->vc = 0; + cga->vadj = cga->crtc[5]; + if (!cga->vadj) cga->cgadispon = 1; + if (!cga->vadj) cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; + if ((cga->crtc[10] & 0x60) == 0x20) cga->cursoron = 0; + else cga->cursoron = cga->cgablink & 8; } - if (vc==crtc[7]) + if (cga->vc == cga->crtc[7]) { - cgadispon=0; - displine=0; - vsynctime=(crtc[3]>>4)+1; - if (crtc[7]) + cga->cgadispon = 0; + cga->displine = 0; + cga->vsynctime = (cga->crtc[3] >> 4) + 1; + if (cga->crtc[7]) { - if (cgamode&1) x=(crtc[1]<<3)+16; - else x=(crtc[1]<<4)+16; - lastline++; - if (x!=xsize || (lastline-firstline)!=ysize) + if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16; + else x = (cga->crtc[1] << 4) + 16; + cga->lastline++; + if (x != xsize || (cga->lastline - cga->firstline) != ysize) { - xsize=x; - ysize=lastline-firstline; - if (xsize<64) xsize=656; - if (ysize<32) ysize=200; - updatewindowsize(xsize,(ysize<<1)+16); + xsize = x; + ysize = cga->lastline - cga->firstline; + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + updatewindowsize(xsize, (ysize << 1) + 16); } startblit(); if (cga_comp) - video_blit_memtoscreen(0, firstline-4, 0, (lastline-firstline)+8, xsize, (lastline-firstline)+8); + video_blit_memtoscreen(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, xsize, (cga->lastline - cga->firstline) + 8); else - video_blit_memtoscreen_8(0, firstline-4, xsize, (lastline-firstline)+8); - if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF); - readflash=0; + video_blit_memtoscreen_8(0, cga->firstline - 4, xsize, (cga->lastline - cga->firstline) + 8); + if (readflash) rectfill(screen, winsizex - 40, 8, winsizex - 8, 14, 0xffffffff); + readflash = 0; frames++; endblit(); video_res_x = xsize - 16; video_res_y = ysize; - if (cgamode & 1) + if (cga->cgamode & 1) { video_res_x /= 8; - video_res_y /= crtc[9] + 1; + video_res_y /= cga->crtc[9] + 1; video_bpp = 0; } - else if (!(cgamode & 2)) + else if (!(cga->cgamode & 2)) { video_res_x /= 16; - video_res_y /= crtc[9] + 1; + video_res_y /= cga->crtc[9] + 1; video_bpp = 0; } - else if (!(cgamode&16)) + else if (!(cga->cgamode & 16)) { video_res_x /= 2; video_bpp = 2; @@ -446,59 +456,72 @@ endblit(); video_bpp = 1; } } - firstline=1000; - lastline=0; - cgablink++; - oddeven ^= 1; + cga->firstline = 1000; + cga->lastline = 0; + cga->cgablink++; + cga->oddeven ^= 1; } } else { - sc++; - sc&=31; - ma=maback; + cga->sc++; + cga->sc &= 31; + cga->ma = cga->maback; } - if ((sc==(crtc[10]&31) || ((crtc[8]&3)==3 && sc==((crtc[10]&31)>>1)))) con=1; - if (cgadispon && (cgamode&1)) + if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))) + cga->con = 1; + if (cga->cgadispon && (cga->cgamode & 1)) { - for (x=0;x<(crtc[1]<<1);x++) - charbuffer[x]=vram[(((ma<<1)+x)&0x3FFF)]; + for (x = 0; x < (cga->crtc[1] << 1); x++) + cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)]; } } } +void cga_init(cga_t *cga) +{ +} -int cga_init() +void *cga_standalone_init() { int c; int cga_tint = -2; - for (c=0;c<8;c++) + cga_t *cga = malloc(sizeof(cga_t)); + memset(cga, 0, sizeof(cga_t)); + + cga->vram = malloc(0x4000); + + for (c = 0; c < 8; c++) { - i_filt[c]=512.0*cos((3.14*(cga_tint+c*4)/16.0) - 33.0/180.0); - q_filt[c]=512.0*sin((3.14*(cga_tint+c*4)/16.0) - 33.0/180.0); + i_filt[c] = 512.0 * cos((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0); + q_filt[c] = 512.0 * sin((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0); } - mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL); - return 0; + timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); + mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, cga); + io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); + return cga; } -GFXCARD vid_cga = +void cga_close(void *p) { - cga_init, - /*IO at 3Cx/3Dx*/ - cga_out, - cga_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, + cga_t *cga = (cga_t *)p; - cga_poll, - cga_recalctimings, + free(cga->vram); + free(cga); +} - video_write_null, - video_write_null, - cga_write, +void cga_speed_changed(void *p) +{ + cga_t *cga = (cga_t *)p; + + cga_recalctimings(cga); +} - video_read_null, - video_read_null, - cga_read +device_t cga_device = +{ + "CGA", + cga_standalone_init, + cga_close, + cga_speed_changed, + NULL }; diff --git a/src/vid_cga.h b/src/vid_cga.h index 6e2afdc..b9a52f1 100644 --- a/src/vid_cga.h +++ b/src/vid_cga.h @@ -1,7 +1,38 @@ -int cga_init(); -void cga_out(uint16_t addr, uint8_t val, void *priv); -uint8_t cga_in(uint16_t addr, void *priv); -void cga_poll(); -void cga_write(uint32_t addr, uint8_t val, void *priv); -uint8_t cga_read(uint32_t addr, void *priv); -void cga_recalctimings(); +typedef struct cga_t +{ + int crtcreg; + uint8_t crtc[32]; + + uint8_t cgastat; + + uint8_t cgamode, cgacol; + + int linepos, displine; + int sc, vc; + int cgadispon; + int con, coff, cursoron, cgablink; + int vsynctime, vadj; + uint16_t ma, maback; + int oddeven; + + int dispontime, dispofftime; + int vidtime; + + int firstline, lastline; + + int drawcursor; + + uint8_t *vram; + + uint8_t charbuffer[256]; +} cga_t; + +void cga_init(cga_t *cga); +void cga_out(uint16_t addr, uint8_t val, void *p); +uint8_t cga_in(uint16_t addr, void *p); +void cga_write(uint32_t addr, uint8_t val, void *p); +uint8_t cga_read(uint32_t addr, void *p); +void cga_recalctimings(cga_t *cga); +void cga_poll(void *p); + +extern device_t cga_device; diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 2214a9c..4cf03c2 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -1,14 +1,19 @@ /*Cirrus Logic CL-GD5429 emulation*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "video.h" +#include "vid_cl5429.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_unk_ramdac.h" -struct +typedef struct gd5429_t { + svga_t svga; + uint32_t bank[2]; struct @@ -24,60 +29,63 @@ struct int x_count; } blt; -} gd5429; +} gd5429_t; -void gd5429_write(uint32_t addr, uint8_t val, void *priv); -uint8_t gd5429_read(uint32_t addr, void *priv); +void gd5429_write(uint32_t addr, uint8_t val, void *p); +uint8_t gd5429_read(uint32_t addr, void *p); -void gd5429_mmio_write(uint32_t addr, uint8_t val, void *priv); -uint8_t gd5429_mmio_read(uint32_t addr, void *priv); +void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p); +uint8_t gd5429_mmio_read(uint32_t addr, void *p); -void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *priv); -void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *priv); +void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p); +void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p); -void gd5429_recalc_banking(); -void gd5429_recalc_mapping(); +void gd5429_recalc_banking(gd5429_t *gd5429); +void gd5429_recalc_mapping(gd5429_t *gd5429); -void gd5429_out(uint16_t addr, uint8_t val, void *priv) +void gd5429_out(uint16_t addr, uint8_t val, void *p) { + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; uint8_t old; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; pclog("gd5429 out %04X %02X\n", addr, val); switch (addr) { case 0x3c4: - seqaddr = val; + svga->seqaddr = val; break; case 0x3c5: - if (seqaddr > 5) + if (svga->seqaddr > 5) { - seqregs[seqaddr & 0x1f] = val; - switch (seqaddr & 0x1f) + svga->seqregs[svga->seqaddr & 0x1f] = val; + switch (svga->seqaddr & 0x1f) { case 0x10: case 0x30: case 0x50: case 0x70: case 0x90: case 0xb0: case 0xd0: case 0xf0: - svga_hwcursor.x = (val << 3) | ((seqaddr >> 5) & 7); - pclog("svga_hwcursor.x = %i\n", svga_hwcursor.x); + svga->hwcursor.x = (val << 3) | ((svga->seqaddr >> 5) & 7); + pclog("svga->hwcursor.x = %i\n", svga->hwcursor.x); break; case 0x11: case 0x31: case 0x51: case 0x71: case 0x91: case 0xb1: case 0xd1: case 0xf1: - svga_hwcursor.y = (val << 3) | ((seqaddr >> 5) & 7); - pclog("svga_hwcursor.y = %i\n", svga_hwcursor.y); + svga->hwcursor.y = (val << 3) | ((svga->seqaddr >> 5) & 7); + pclog("svga->hwcursor.y = %i\n", svga->hwcursor.y); break; case 0x12: - svga_hwcursor.ena = val & 1; - pclog("svga_hwcursor.ena = %i\n", svga_hwcursor.ena); + svga->hwcursor.ena = val & 1; + pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena); break; case 0x13: - svga_hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256); - pclog("svga_hwcursor.addr = %x\n", svga_hwcursor.addr); + svga->hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256); + pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); break; case 0x17: - gd5429_recalc_mapping(); + gd5429_recalc_mapping(gd5429); break; } return; @@ -85,38 +93,38 @@ void gd5429_out(uint16_t addr, uint8_t val, void *priv) break; case 0x3cf: - if (gdcaddr == 5) + if (svga->gdcaddr == 5) { - gdcreg[5] = val; - if (gdcreg[0xb] & 0x04) - writemode = gdcreg[5] & 7; + svga->gdcreg[5] = val; + if (svga->gdcreg[0xb] & 0x04) + svga->writemode = svga->gdcreg[5] & 7; else - writemode = gdcreg[5] & 3; - readmode = val & 8; - pclog("writemode = %i\n", writemode); + svga->writemode = svga->gdcreg[5] & 3; + svga->readmode = val & 8; + pclog("writemode = %i\n", svga->writemode); return; } - if (gdcaddr == 6) + if (svga->gdcaddr == 6) { - if ((gdcreg[6] & 0xc) != (val & 0xc)) + if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - gdcreg[6] = val; - gd5429_recalc_mapping(); + svga->gdcreg[6] = val; + gd5429_recalc_mapping(gd5429); } - gdcreg[6] = val; + svga->gdcreg[6] = val; return; } - if (gdcaddr > 8) + if (svga->gdcaddr > 8) { - gdcreg[gdcaddr & 0x3f] = val; - switch (gdcaddr) + svga->gdcreg[svga->gdcaddr & 0x3f] = val; + switch (svga->gdcaddr) { case 0x09: case 0x0a: case 0x0b: - gd5429_recalc_banking(); - if (gdcreg[0xb] & 0x04) - writemode = gdcreg[5] & 7; + gd5429_recalc_banking(gd5429); + if (svga->gdcreg[0xb] & 0x04) + svga->writemode = svga->gdcreg[5] & 7; else - writemode = gdcreg[5] & 3; + svga->writemode = svga->gdcreg[5] & 3; break; } return; @@ -124,135 +132,145 @@ void gd5429_out(uint16_t addr, uint8_t val, void *priv) break; case 0x3D4: - crtcreg = val & 0x3f; + svga->crtcreg = val & 0x3f; return; case 0x3D5: - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - if (old!=val) + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(svga); } } break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t gd5429_in(uint16_t addr, void *priv) +uint8_t gd5429_in(uint16_t addr, void *p) { - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3d0) && !(svga->miscout & 1)) + addr ^= 0x60; if (addr != 0x3da) pclog("IN gd5429 %04X\n", addr); switch (addr) { case 0x3c5: - if (seqaddr > 5) + if (svga->seqaddr > 5) { - switch (seqaddr) + switch (svga->seqaddr) { case 6: - return ((seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; + return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; } - return seqregs[seqaddr & 0x3f]; + return svga->seqregs[svga->seqaddr & 0x3f]; } break; case 0x3cf: - if (gdcaddr > 8) + if (svga->gdcaddr > 8) { - return gdcreg[seqaddr & 0x3f]; + return svga->gdcreg[svga->gdcaddr & 0x3f]; } break; case 0x3D4: - return crtcreg; + return svga->crtcreg; case 0x3D5: - switch (crtcreg) + switch (svga->crtcreg) { case 0x27: /*ID*/ return 0x9c; /*GD5429*/ } - return crtc[crtcreg]; + return svga->crtc[svga->crtcreg]; } - return svga_in(addr, NULL); + return svga_in(addr, svga); } -void gd5429_recalc_banking() +void gd5429_recalc_banking(gd5429_t *gd5429) { - if (gdcreg[0xb] & 0x20) - gd5429.bank[0] = (gdcreg[0x09] & 0x7f) << 14; + svga_t *svga = &gd5429->svga; + + if (svga->gdcreg[0xb] & 0x20) + gd5429->bank[0] = (svga->gdcreg[0x09] & 0x7f) << 14; else - gd5429.bank[0] = gdcreg[0x09] << 12; + gd5429->bank[0] = svga->gdcreg[0x09] << 12; - if (gdcreg[0xb] & 0x01) + if (svga->gdcreg[0xb] & 0x01) { - if (gdcreg[0xb] & 0x20) - gd5429.bank[1] = (gdcreg[0x0a] & 0x7f) << 14; + if (svga->gdcreg[0xb] & 0x20) + gd5429->bank[1] = (svga->gdcreg[0x0a] & 0x7f) << 14; else - gd5429.bank[1] = gdcreg[0x0a] << 12; + gd5429->bank[1] = svga->gdcreg[0x0a] << 12; } else - gd5429.bank[1] = gd5429.bank[0] + 0x8000; + gd5429->bank[1] = gd5429->bank[0] + 0x8000; } -void gd5429_recalc_mapping() +void gd5429_recalc_mapping(gd5429_t *gd5429) { - mem_removehandler(0xa0000, 0x20000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, NULL); - mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); - mem_removehandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, NULL); - pclog("Write mapping %02X %i\n", gdcreg[6], seqregs[0x17] & 0x04); - switch (gdcreg[6] & 0x0C) + svga_t *svga = &gd5429->svga; + + mem_removehandler(0xa0000, 0x20000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, gd5429); + mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); + mem_removehandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, gd5429); + pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); + switch (svga->gdcreg[6] & 0x0C) { case 0x0: /*128k at A0000*/ - mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, NULL); + mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, gd5429); break; case 0x4: /*64k at A0000*/ - mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, NULL); - if (seqregs[0x17] & 0x04) - mem_sethandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, NULL); + mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, gd5429); + if (svga->seqregs[0x17] & 0x04) + mem_sethandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, gd5429); break; case 0x8: /*32k at B0000*/ - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0xC: /*32k at B8000*/ - mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; } } -void gd5429_recalctimings() +void gd5429_recalctimings(svga_t *svga) { - if (seqregs[7] & 0x01) + gd5429_t *gd5429 = (gd5429_t *)svga->p; + + if (svga->seqregs[7] & 0x01) { - svga_render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_highres; } - svga_ma |= ((crtc[0x1b] & 0x01) << 16) | ((crtc[0x1b] & 0xc) << 15); - pclog("MA now %05X %02X\n", svga_ma, crtc[0x1b]); + svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); + pclog("MA now %05X %02X\n", svga->ma_latch, svga->crtc[0x1b]); } -void gd5429_hwcursor_draw(int displine) +void gd5429_hwcursor_draw(svga_t *svga, int displine) { int x; uint8_t dat[2]; int xx; - int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - pclog("HWcursor %i %i %i %i %x %02X %02X\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y, offset, displine, svga_hwcursor_latch.addr, vram[svga_hwcursor_latch.addr], vram[svga_hwcursor_latch.addr + 0x80]); + pclog("HWcursor %i %i %i %i %x %02X %02X\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y, offset, displine, svga->hwcursor_latch.addr, vram[svga->hwcursor_latch.addr], vram[svga->hwcursor_latch.addr + 0x80]); for (x = 0; x < 32; x += 8) { - dat[0] = vram[svga_hwcursor_latch.addr]; - dat[1] = vram[svga_hwcursor_latch.addr + 0x80]; + dat[0] = svga->vram[svga->hwcursor_latch.addr]; + dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; for (xx = 0; xx < 8; xx++) { - if (offset >= svga_hwcursor_latch.x) + if (offset >= svga->hwcursor_latch.x) { if (dat[1] & 0x80) ((uint32_t *)buffer32->line[displine])[offset + 32] = 0; @@ -264,54 +282,39 @@ void gd5429_hwcursor_draw(int displine) dat[0] <<= 1; dat[1] <<= 1; } - svga_hwcursor_latch.addr++; + svga->hwcursor_latch.addr++; } } -int gd5429_init() -{ - svga_recalctimings_ex = gd5429_recalctimings; - svga_hwcursor_draw = gd5429_hwcursor_draw; - svga_vram_limit = 2 << 20; /*2mb*/ - vrammask = 0x1fffff; - - svga_hwcursor.yoff = 32; - svga_hwcursor.xoff = 0; - - memset(&gd5429, 0, sizeof(gd5429)); - - gd5429.bank[1] = 0x8000; - - return svga_init(); -} - -static uint8_t la, lb, lc, ld; - -uint8_t gd5429_read_linear(uint32_t addr, void *priv); -void gd5429_write_linear(uint32_t addr, uint8_t val, void *priv); - -void gd5429_write(uint32_t addr, uint8_t val, void *priv) + +void gd5429_write_linear(uint32_t addr, uint8_t val, void *p); + +void gd5429_write(uint32_t addr, uint8_t val, void *p) { + gd5429_t *gd5429 = (gd5429_t *)p; // pclog("gd5429_write : %05X %02X ", addr, val); - addr = (addr & 0x7fff) + gd5429.bank[(addr >> 15) & 1]; + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; // pclog("%08X\n", addr); - gd5429_write_linear(addr, val, priv); + gd5429_write_linear(addr, val, p); } -uint8_t gd5429_read(uint32_t addr, void *priv) +uint8_t gd5429_read(uint32_t addr, void *p) { + gd5429_t *gd5429 = (gd5429_t *)p; uint8_t ret; // pclog("gd5429_read : %05X ", addr); - addr = (addr & 0x7fff) + gd5429.bank[(addr >> 15) & 1]; - ret = gd5429_read_linear(addr, priv); + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; + ret = svga_read_linear(addr, &gd5429->svga); // pclog("%08X %02X\n", addr, ret); return ret; } -void gd5429_write_linear(uint32_t addr, uint8_t val, void *priv) +void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) { - uint8_t vala,valb,valc,vald,wm=writemask; - int writemask2 = writemask; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + uint8_t vala, valb, valc, vald, wm = svga->writemask; + int writemask2 = svga->writemask; cycles -= video_timing_b; cycles_lost += video_timing_b; @@ -319,270 +322,231 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *priv) egawrites++; // if (svga_output) pclog("Write LFB %08X %02X ", addr, val); - if (!(gdcreg[6]&1)) fullchange=2; - if (chain4 && (writemode < 4)) + if (!(svga->gdcreg[6] & 1)) + fullchange = 2; + if (svga->chain4 && (svga->writemode < 4)) { - writemask2=1<<(addr&3); - addr&=~3; + writemask2 = 1 << (addr & 3); + addr &= ~3; } else { - addr<<=2; + addr <<= 2; } addr &= 0x7fffff; + if (addr >= svga->vram_limit) + return; // if (svga_output) pclog("%08X\n", addr); - changedvram[addr>>10]=changeframecount; + svga->changedvram[addr >> 10] = changeframecount; - switch (writemode) + switch (svga->writemode) { case 4: pclog("Writemode 4 : %X ", addr); addr <<= 1; - changedvram[addr>>10]=changeframecount; + svga->changedvram[addr >> 10] = changeframecount; pclog("%X %X\n", addr, val); if (val & 0x80) - vram[addr + 0] = gdcreg[1]; + svga->vram[addr + 0] = svga->gdcreg[1]; if (val & 0x40) - vram[addr + 1] = gdcreg[1]; + svga->vram[addr + 1] = svga->gdcreg[1]; if (val & 0x20) - vram[addr + 2] = gdcreg[1]; + svga->vram[addr + 2] = svga->gdcreg[1]; if (val & 0x10) - vram[addr + 3] = gdcreg[1]; + svga->vram[addr + 3] = svga->gdcreg[1]; if (val & 0x08) - vram[addr + 4] = gdcreg[1]; + svga->vram[addr + 4] = svga->gdcreg[1]; if (val & 0x04) - vram[addr + 5] = gdcreg[1]; + svga->vram[addr + 5] = svga->gdcreg[1]; if (val & 0x02) - vram[addr + 6] = gdcreg[1]; + svga->vram[addr + 6] = svga->gdcreg[1]; if (val & 0x01) - vram[addr + 7] = gdcreg[1]; + svga->vram[addr + 7] = svga->gdcreg[1]; break; case 5: pclog("Writemode 5 : %X ", addr); addr <<= 1; - changedvram[addr>>10]=changeframecount; + svga->changedvram[addr >> 10] = changeframecount; pclog("%X %X\n", addr, val); - vram[addr + 0] = (val & 0x80) ? gdcreg[1] : gdcreg[0]; - vram[addr + 1] = (val & 0x40) ? gdcreg[1] : gdcreg[0]; - vram[addr + 2] = (val & 0x20) ? gdcreg[1] : gdcreg[0]; - vram[addr + 3] = (val & 0x10) ? gdcreg[1] : gdcreg[0]; - vram[addr + 4] = (val & 0x08) ? gdcreg[1] : gdcreg[0]; - vram[addr + 5] = (val & 0x04) ? gdcreg[1] : gdcreg[0]; - vram[addr + 6] = (val & 0x02) ? gdcreg[1] : gdcreg[0]; - vram[addr + 7] = (val & 0x01) ? gdcreg[1] : gdcreg[0]; + svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 1] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 2] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 3] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 4] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 5] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 6] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 7] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; break; case 1: - if (writemask2&1) vram[addr]=la; - if (writemask2&2) vram[addr|0x1]=lb; - if (writemask2&4) vram[addr|0x2]=lc; - if (writemask2&8) vram[addr|0x3]=ld; + if (writemask2 & 1) svga->vram[addr] = svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld; break; case 0: - if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val]; - if (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) { - if (writemask2&1) vram[addr]=val; - if (writemask2&2) vram[addr|0x1]=val; - if (writemask2&4) vram[addr|0x2]=val; - if (writemask2&8) vram[addr|0x3]=val; + if (writemask2 & 1) svga->vram[addr] = val; + if (writemask2 & 2) svga->vram[addr | 0x1] = val; + if (writemask2 & 4) svga->vram[addr | 0x2] = val; + if (writemask2 & 8) svga->vram[addr | 0x3] = val; } else { - if (gdcreg[1]&1) vala=(gdcreg[0]&1)?0xFF:0; - else vala=val; - if (gdcreg[1]&2) valb=(gdcreg[0]&2)?0xFF:0; - else valb=val; - if (gdcreg[1]&4) valc=(gdcreg[0]&4)?0xFF:0; - else valc=val; - if (gdcreg[1]&8) vald=(gdcreg[0]&8)?0xFF:0; - else vald=val; + if (svga->gdcreg[1] & 1) vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + else vala = val; + if (svga->gdcreg[1] & 2) valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + else valb = val; + if (svga->gdcreg[1] & 4) valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + else valc = val; + if (svga->gdcreg[1] & 8) vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + else vald = val; - switch (gdcreg[3]&0x18) + switch (svga->gdcreg[3] & 0x18) { case 0: /*Set*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); break; case 8: /*AND*/ - if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; - if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; - if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; - if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; break; case 0x10: /*OR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; break; case 0x18: /*XOR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; break; } // pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); } break; case 2: - if (!(gdcreg[3]&0x18) && !gdcreg[1]) + if (!(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) { - if (writemask2&1) vram[addr]=(((val&1)?0xFF:0)&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(((val&2)?0xFF:0)&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(((val&4)?0xFF:0)&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(((val&8)?0xFF:0)&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); } else { - vala=((val&1)?0xFF:0); - valb=((val&2)?0xFF:0); - valc=((val&4)?0xFF:0); - vald=((val&8)?0xFF:0); - switch (gdcreg[3]&0x18) + vala = ((val & 1) ? 0xff : 0); + valb = ((val & 2) ? 0xff : 0); + valc = ((val & 4) ? 0xff : 0); + vald = ((val & 8) ? 0xff : 0); + switch (svga->gdcreg[3] & 0x18) { case 0: /*Set*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); break; case 8: /*AND*/ - if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; - if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; - if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; - if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; break; case 0x10: /*OR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; break; case 0x18: /*XOR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; break; } } break; case 3: - if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val]; - wm=gdcreg[8]; - gdcreg[8]&=val; + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= val; - vala=(gdcreg[0]&1)?0xFF:0; - valb=(gdcreg[0]&2)?0xFF:0; - valc=(gdcreg[0]&4)?0xFF:0; - vald=(gdcreg[0]&8)?0xFF:0; - switch (gdcreg[3]&0x18) + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + switch (svga->gdcreg[3] & 0x18) { case 0: /*Set*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); break; case 8: /*AND*/ - if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; - if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; - if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; - if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; break; case 0x10: /*OR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; break; case 0x18: /*XOR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; break; } - gdcreg[8]=wm; + svga->gdcreg[8] = wm; break; } } -uint8_t gd5429_read_linear(uint32_t addr, void *priv) +void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) { - uint8_t temp,temp2,temp3,temp4; - - cycles -= video_timing_b; - cycles_lost += video_timing_b; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - egareads++; - - if (chain4) - { - addr &= 0x7fffff; - if (addr >= svga_vram_limit) - return 0xff; - return vram[addr & 0x7fffff]; - } - else addr<<=2; - - addr &= 0x7fffff; - - if (addr >= svga_vram_limit) - return 0xff; - - la=vram[addr]; - lb=vram[addr|0x1]; - lc=vram[addr|0x2]; - ld=vram[addr|0x3]; - if (readmode) - { - temp= (colournocare&1) ?0xFF:0; - temp&=la; - temp^=(colourcompare&1)?0xFF:0; - temp2= (colournocare&2) ?0xFF:0; - temp2&=lb; - temp2^=(colourcompare&2)?0xFF:0; - temp3= (colournocare&4) ?0xFF:0; - temp3&=lc; - temp3^=(colourcompare&4)?0xFF:0; - temp4= (colournocare&8) ?0xFF:0; - temp4&=ld; - temp4^=(colourcompare&8)?0xFF:0; - return ~(temp|temp2|temp3|temp4); - } -//printf("Read %02X %04X %04X\n",vram[addr|readplane],addr,readplane); - return vram[addr|readplane]; -} - -void gd5429_start_blit(uint32_t cpu_dat, int count) -{ pclog("gd5429_start_blit %i\n", count); if (count == -1) { - gd5429.blt.dst_addr_backup = gd5429.blt.dst_addr; - gd5429.blt.src_addr_backup = gd5429.blt.src_addr; - gd5429.blt.width_backup = gd5429.blt.width; - gd5429.blt.height_internal = gd5429.blt.height; - gd5429.blt.x_count = gd5429.blt.mask & 7; - pclog("gd5429_start_blit : size %i, %i\n", gd5429.blt.width, gd5429.blt.height); + gd5429->blt.dst_addr_backup = gd5429->blt.dst_addr; + gd5429->blt.src_addr_backup = gd5429->blt.src_addr; + gd5429->blt.width_backup = gd5429->blt.width; + gd5429->blt.height_internal = gd5429->blt.height; + gd5429->blt.x_count = gd5429->blt.mask & 7; + pclog("gd5429_start_blit : size %i, %i\n", gd5429->blt.width, gd5429->blt.height); - if (gd5429.blt.mode & 0x04) + if (gd5429->blt.mode & 0x04) { // pclog("blt.mode & 0x04\n"); - mem_removehandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, NULL); - mem_sethandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l, NULL); + mem_removehandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, gd5429); + mem_sethandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l, gd5429); return; } else { - mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l, NULL); - gd5429_recalc_mapping(); + mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l, gd5429); + gd5429_recalc_mapping(gd5429); } } @@ -591,11 +555,11 @@ void gd5429_start_blit(uint32_t cpu_dat, int count) uint8_t src, dst; int mask; - if (gd5429.blt.mode & 0x04) + if (gd5429->blt.mode & 0x04) { - if (gd5429.blt.mode & 0x80) + if (gd5429->blt.mode & 0x80) { - src = (cpu_dat & 0x80) ? gd5429.blt.fg_col : gd5429.blt.bg_col; + src = (cpu_dat & 0x80) ? gd5429->blt.fg_col : gd5429->blt.bg_col; mask = cpu_dat & 0x80; cpu_dat <<= 1; count--; @@ -610,39 +574,39 @@ void gd5429_start_blit(uint32_t cpu_dat, int count) } else { - switch (gd5429.blt.mode & 0xc0) + switch (gd5429->blt.mode & 0xc0) { case 0x00: - src = vram[gd5429.blt.src_addr & vrammask]; - gd5429.blt.src_addr += ((gd5429.blt.mode & 0x01) ? -1 : 1); + src = svga->vram[gd5429->blt.src_addr & svga->vrammask]; + gd5429->blt.src_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); mask = 1; break; case 0x40: - src = vram[(gd5429.blt.src_addr & (vrammask & ~7)) | (gd5429.blt.dst_addr & 7)]; + src = svga->vram[(gd5429->blt.src_addr & (svga->vrammask & ~7)) | (gd5429->blt.dst_addr & 7)]; mask = 1; break; case 0x80: - mask = vram[gd5429.blt.src_addr & vrammask] & (0x80 >> gd5429.blt.x_count); - src = mask ? gd5429.blt.fg_col : gd5429.blt.bg_col; - gd5429.blt.x_count++; - if (gd5429.blt.x_count == 8) + mask = svga->vram[gd5429->blt.src_addr & svga->vrammask] & (0x80 >> gd5429->blt.x_count); + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + gd5429->blt.x_count++; + if (gd5429->blt.x_count == 8) { - gd5429.blt.x_count = 0; - gd5429.blt.src_addr++; + gd5429->blt.x_count = 0; + gd5429->blt.src_addr++; } break; case 0xc0: - mask = vram[gd5429.blt.src_addr & vrammask] & (0x80 >> (gd5429.blt.dst_addr & 7)); - src = mask ? gd5429.blt.fg_col : gd5429.blt.bg_col; + mask = svga->vram[gd5429->blt.src_addr & svga->vrammask] & (0x80 >> (gd5429->blt.dst_addr & 7)); + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; break; } count--; } - dst = vram[gd5429.blt.dst_addr & vrammask]; - changedvram[(gd5429.blt.dst_addr & vrammask) >> 10] = changeframecount; + dst = svga->vram[gd5429->blt.dst_addr & svga->vrammask]; + svga->changedvram[(gd5429->blt.dst_addr & svga->vrammask) >> 10] = changeframecount; - pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429.blt.width, gd5429.blt.height_internal, gd5429.blt.src_addr, gd5429.blt.dst_addr, gd5429.blt.src_addr & vrammask, vram[gd5429.blt.src_addr & vrammask], 0x80 >> (gd5429.blt.dst_addr & 7), src, dst); - switch (gd5429.blt.rop) + pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vrammask, svga->vram[gd5429->blt.src_addr & svga->vrammask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst); + switch (gd5429->blt.rop) { case 0x00: dst = 0; break; case 0x05: dst = src & dst; break; @@ -663,141 +627,145 @@ void gd5429_start_blit(uint32_t cpu_dat, int count) } pclog("%02X %02X\n", dst, mask); - if ((gd5429.blt.width_backup - gd5429.blt.width) >= (gd5429.blt.mask & 7) && - !((gd5429.blt.mode & 0x08) && !mask)) - vram[gd5429.blt.dst_addr & vrammask] = dst; + if ((gd5429->blt.width_backup - gd5429->blt.width) >= (gd5429->blt.mask & 7) && + !((gd5429->blt.mode & 0x08) && !mask)) + svga->vram[gd5429->blt.dst_addr & svga->vrammask] = dst; - gd5429.blt.dst_addr += ((gd5429.blt.mode & 0x01) ? -1 : 1); + gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); - gd5429.blt.width--; + gd5429->blt.width--; - if (gd5429.blt.width == 0xffff) + if (gd5429->blt.width == 0xffff) { - gd5429.blt.width = gd5429.blt.width_backup; + gd5429->blt.width = gd5429->blt.width_backup; - gd5429.blt.dst_addr = gd5429.blt.dst_addr_backup = gd5429.blt.dst_addr_backup + ((gd5429.blt.mode & 0x01) ? -gd5429.blt.dst_pitch : gd5429.blt.dst_pitch); + gd5429->blt.dst_addr = gd5429->blt.dst_addr_backup = gd5429->blt.dst_addr_backup + ((gd5429->blt.mode & 0x01) ? -gd5429->blt.dst_pitch : gd5429->blt.dst_pitch); - switch (gd5429.blt.mode & 0xc0) + switch (gd5429->blt.mode & 0xc0) { case 0x00: - gd5429.blt.src_addr = gd5429.blt.src_addr_backup = gd5429.blt.src_addr_backup + ((gd5429.blt.mode & 0x01) ? -gd5429.blt.src_pitch : gd5429.blt.src_pitch); + gd5429->blt.src_addr = gd5429->blt.src_addr_backup = gd5429->blt.src_addr_backup + ((gd5429->blt.mode & 0x01) ? -gd5429->blt.src_pitch : gd5429->blt.src_pitch); break; case 0x40: - gd5429.blt.src_addr = ((gd5429.blt.src_addr + ((gd5429.blt.mode & 0x01) ? -8 : 8)) & 0x38) | (gd5429.blt.src_addr & ~0x38); + gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -8 : 8)) & 0x38) | (gd5429->blt.src_addr & ~0x38); break; case 0x80: - if (gd5429.blt.x_count != 0) + if (gd5429->blt.x_count != 0) { - gd5429.blt.x_count = 0; - gd5429.blt.src_addr++; + gd5429->blt.x_count = 0; + gd5429->blt.src_addr++; } break; case 0xc0: - gd5429.blt.src_addr = ((gd5429.blt.src_addr + ((gd5429.blt.mode & 0x01) ? -1 : 1)) & 7) | (gd5429.blt.src_addr & ~7); + gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -1 : 1)) & 7) | (gd5429->blt.src_addr & ~7); break; } - gd5429.blt.height_internal--; - if (gd5429.blt.height_internal == 0xffff) + gd5429->blt.height_internal--; + if (gd5429->blt.height_internal == 0xffff) { - if (gd5429.blt.mode & 0x04) + if (gd5429->blt.mode & 0x04) { - mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l, NULL); - gd5429_recalc_mapping(); + mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l, gd5429); + gd5429_recalc_mapping(gd5429); } return; } - if (gd5429.blt.mode & 0x04) + if (gd5429->blt.mode & 0x04) return; } } } -void gd5429_mmio_write(uint32_t addr, uint8_t val, void *priv) +void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) { + gd5429_t *gd5429 = (gd5429_t *)p; + pclog("MMIO write %08X %02X\n", addr, val); switch (addr & 0xff) { case 0x00: - gd5429.blt.bg_col = (gd5429.blt.bg_col & 0xff00) | val; + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00) | val; break; case 0x01: - gd5429.blt.bg_col = (gd5429.blt.bg_col & 0x00ff) | (val << 8); + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ff) | (val << 8); break; case 0x04: - gd5429.blt.fg_col = (gd5429.blt.fg_col & 0xff00) | val; + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00) | val; break; case 0x05: - gd5429.blt.fg_col = (gd5429.blt.fg_col & 0x00ff) | (val << 8); + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ff) | (val << 8); break; case 0x08: - gd5429.blt.width = (gd5429.blt.width & 0xff00) | val; + gd5429->blt.width = (gd5429->blt.width & 0xff00) | val; break; case 0x09: - gd5429.blt.width = (gd5429.blt.width & 0x00ff) | (val << 8); + gd5429->blt.width = (gd5429->blt.width & 0x00ff) | (val << 8); break; case 0x0a: - gd5429.blt.height = (gd5429.blt.height & 0xff00) | val; + gd5429->blt.height = (gd5429->blt.height & 0xff00) | val; break; case 0x0b: - gd5429.blt.height = (gd5429.blt.height & 0x00ff) | (val << 8); + gd5429->blt.height = (gd5429->blt.height & 0x00ff) | (val << 8); break; case 0x0c: - gd5429.blt.dst_pitch = (gd5429.blt.dst_pitch & 0xff00) | val; + gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0xff00) | val; break; case 0x0d: - gd5429.blt.dst_pitch = (gd5429.blt.dst_pitch & 0x00ff) | (val << 8); + gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0x00ff) | (val << 8); break; case 0x0e: - gd5429.blt.src_pitch = (gd5429.blt.src_pitch & 0xff00) | val; + gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0xff00) | val; break; case 0x0f: - gd5429.blt.src_pitch = (gd5429.blt.src_pitch & 0x00ff) | (val << 8); + gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0x00ff) | (val << 8); break; case 0x10: - gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0xffff00) | val; + gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xffff00) | val; break; case 0x11: - gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0xff00ff) | (val << 8); + gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xff00ff) | (val << 8); break; case 0x12: - gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0x00ffff) | (val << 16); + gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0x00ffff) | (val << 16); break; case 0x14: - gd5429.blt.src_addr = (gd5429.blt.src_addr & 0xffff00) | val; + gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xffff00) | val; break; case 0x15: - gd5429.blt.src_addr = (gd5429.blt.src_addr & 0xff00ff) | (val << 8); + gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xff00ff) | (val << 8); break; case 0x16: - gd5429.blt.src_addr = (gd5429.blt.src_addr & 0x00ffff) | (val << 16); + gd5429->blt.src_addr = (gd5429->blt.src_addr & 0x00ffff) | (val << 16); break; case 0x17: - gd5429.blt.mask = val; + gd5429->blt.mask = val; break; case 0x18: - gd5429.blt.mode = val; + gd5429->blt.mode = val; break; case 0x1a: - gd5429.blt.rop = val; + gd5429->blt.rop = val; break; case 0x40: if (val & 0x02) - gd5429_start_blit(0, -1); + gd5429_start_blit(0, -1, gd5429); break; } } -uint8_t gd5429_mmio_read(uint32_t addr, void *priv) +uint8_t gd5429_mmio_read(uint32_t addr, void *p) { + gd5429_t *gd5429 = (gd5429_t *)p; + pclog("MMIO read %08X\n", addr); switch (addr & 0xff) { @@ -807,44 +775,70 @@ uint8_t gd5429_mmio_read(uint32_t addr, void *priv) return 0xff; /*All other registers read-only*/ } -void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *priv) +void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p) { pclog("gd5429_blt_write_w %08X %08X\n", addr, val); - gd5429_start_blit(val, 16); + gd5429_start_blit(val, 16, p); } -void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *priv) +void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p) { + gd5429_t *gd5429 = (gd5429_t *)p; + pclog("gd5429_blt_write_l %08X %08X %04X %04X\n", addr, val, ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00)); - if ((gd5429.blt.mode & 0x84) == 0x84) + if ((gd5429->blt.mode & 0x84) == 0x84) { - gd5429_start_blit( val & 0xff, 8); - gd5429_start_blit((val >> 8) & 0xff, 8); - gd5429_start_blit((val >> 16) & 0xff, 8); - gd5429_start_blit((val >> 24) & 0xff, 8); + gd5429_start_blit( val & 0xff, 8, p); + gd5429_start_blit((val >> 8) & 0xff, 8, p); + gd5429_start_blit((val >> 16) & 0xff, 8, p); + gd5429_start_blit((val >> 24) & 0xff, 8, p); } else - gd5429_start_blit(val, 32); + gd5429_start_blit(val, 32, p); } -GFXCARD vid_gd5429 = +void *gd5429_init() { + gd5429_t *gd5429 = malloc(sizeof(gd5429_t)); + svga_t *svga = &gd5429->svga; + memset(gd5429, 0, sizeof(gd5429_t)); + + svga_init(&gd5429->svga, gd5429, 1 << 21, /*2mb*/ + gd5429_recalctimings, + gd5429_in, gd5429_out, + gd5429_hwcursor_draw); + + io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + + svga->hwcursor.yoff = 32; + svga->hwcursor.xoff = 0; + + gd5429->bank[1] = 0x8000; + + return gd5429; +} + +void gd5429_close(void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + + svga_close(&gd5429->svga); + + free(gd5429); +} + +void gd5429_speed_changed(void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + + svga_recalctimings(&gd5429->svga); +} + +device_t gd5429_device = +{ + "Cirrus Logic GD5429", gd5429_init, - /*IO at 3Cx/3Dx*/ - gd5429_out, - gd5429_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - svga_poll, - svga_recalctimings, - - svga_write, - video_write_null, - video_write_null, - - svga_read, - video_read_null, - video_read_null + gd5429_close, + gd5429_speed_changed, + svga_add_status_info }; diff --git a/src/vid_cl5429.h b/src/vid_cl5429.h new file mode 100644 index 0000000..b4a159c --- /dev/null +++ b/src/vid_cl5429.h @@ -0,0 +1 @@ +extern device_t gd5429_device; diff --git a/src/vid_ega.c b/src/vid_ega.c index 7b95438..fab74e2 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -1,689 +1,777 @@ /*EGA emulation*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "timer.h" #include "video.h" #include "vid_ega.h" -#include "vid_svga.h" extern uint8_t edatlookup[4][4]; -uint8_t ega_3c2; - -static uint8_t la, lb, lc, ld; static uint8_t ega_rotate[8][256]; +static uint32_t pallook16[256], pallook64[256]; + /*3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour)*/ int egaswitchread,egaswitches=9; /*7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines)*/ -void ega_out(uint16_t addr, uint8_t val, void *priv) +void ega_out(uint16_t addr, uint8_t val, void *p) { + ega_t *ega = (ega_t *)p; int c; - uint8_t o,old; - if ((addr&0xFFF0) == 0x3B0) addr |= 0x20; + uint8_t o, old; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) + addr ^= 0x60; + switch (addr) { - case 0x3C0: - if (!attrff) - attraddr=val&31; + case 0x3c0: + if (!ega->attrff) + ega->attraddr = val & 31; else { - attrregs[attraddr&31]=val; - if (attraddr<16) fullchange=changeframecount; - if (attraddr==0x10 || attraddr==0x14 || attraddr<0x10) + ega->attrregs[ega->attraddr & 31] = val; + if (ega->attraddr < 16) + fullchange = changeframecount; + if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10) { - for (c=0;c<16;c++) + for (c = 0; c < 16; c++) { - if (attrregs[0x10]&0x80) egapal[c]=(attrregs[c]&0xF)|((attrregs[0x14]&0xF)<<4); - else egapal[c]=(attrregs[c]&0x3F)|((attrregs[0x14]&0xC)<<4); + if (ega->attrregs[0x10] & 0x80) ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0xf) << 4); + else ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4); } } } - attrff^=1; + ega->attrff ^= 1; break; - case 0x3C2: - egaswitchread=val&0xC; - vres=!(val&0x80); - pallook=(vres)?pallook16:pallook64; - vidclock=val&4; /*printf("3C2 write %02X\n",val);*/ - ega_3c2=val; + case 0x3c2: + egaswitchread = val & 0xc; + ega->vres = !(val & 0x80); + ega->pallook = ega->vres ? pallook16 : pallook64; + ega->vidclock = val & 4; /*printf("3C2 write %02X\n",val);*/ + ega->miscout=val; break; - case 0x3C4: seqaddr=val; break; - case 0x3C5: - o=seqregs[seqaddr&0xF]; - seqregs[seqaddr&0xF]=val; - if (o!=val && (seqaddr&0xF)==1) ega_recalctimings(); - switch (seqaddr&0xF) + case 0x3c4: + ega->seqaddr = val; + break; + case 0x3c5: + o = ega->seqregs[ega->seqaddr & 0xf]; + ega->seqregs[ega->seqaddr & 0xf] = val; + if (o != val && (ega->seqaddr & 0xf) == 1) + ega_recalctimings(ega); + switch (ega->seqaddr & 0xf) { - case 1: if (scrblank && !(val&0x20)) fullchange=3; scrblank=(scrblank&~0x20)|(val&0x20); break; - case 2: writemask=val&0xF; break; + case 1: + if (ega->scrblank && !(val & 0x20)) + fullchange = 3; + ega->scrblank = (ega->scrblank & ~0x20) | (val & 0x20); + break; + case 2: + ega->writemask = val & 0xf; + break; case 3: - charset=val&0xF; - charseta=((charset>>2)*0x10000)+2; - charsetb=((charset&3) *0x10000)+2; + ega->charseta = (((val >> 2) & 3) * 0x10000) + 2; + ega->charsetb = ((val & 3) * 0x10000) + 2; break; } break; - case 0x3CE: gdcaddr=val; break; - case 0x3CF: - gdcreg[gdcaddr&15]=val; - switch (gdcaddr&15) + case 0x3ce: + ega->gdcaddr = val; + break; + case 0x3cf: + ega->gdcreg[ega->gdcaddr & 15] = val; + switch (ega->gdcaddr & 15) { - case 2: colourcompare=val; break; - case 4: readplane=val&3; break; - case 5: writemode=val&3; readmode=val&8; break; + case 2: + ega->colourcompare = val; + break; + case 4: + ega->readplane = val & 3; + break; + case 5: + ega->writemode = val & 3; + ega->readmode = val & 8; + break; case 6: - 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, ega); // pclog("Write mapping %02X\n", val); - switch (val&0xC) + switch (val & 0xc) { case 0x0: /*128k at A0000*/ - mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); + mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, ega); break; case 0x4: /*64k at A0000*/ - mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); + mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, ega); break; case 0x8: /*32k at B0000*/ - mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); + mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, ega); break; case 0xC: /*32k at B8000*/ - mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); + mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, ega); break; } - break; - case 7: colournocare=val; break; + case 7: + ega->colournocare = val; + break; } break; - case 0x3D4: - crtcreg=val; + case 0x3d4: + pclog("Write 3d4 %02X %04X:%04X\n", val, CS, pc); + ega->crtcreg = val & 31; return; - case 0x3D5: - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; - if (old!=val) + case 0x3d5: + pclog("Write 3d5 %02X %02X %02X\n", ega->crtcreg, val, ega->crtc[0x11]); +// if (ega->crtcreg == 1 && val == 0x14) +// fatal("Here\n"); + if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) return; + old = ega->crtc[ega->crtcreg]; + ega->crtc[ega->crtcreg] = val; + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) { - fullchange=changeframecount; - ega_recalctimings(); + fullchange = changeframecount; + ega_recalctimings(ega); } } break; } } -uint8_t ega_in(uint16_t addr, void *priv) +uint8_t ega_in(uint16_t addr, void *p) { - if ((addr&0xFFF0) == 0x3B0) addr |= 0x20; + ega_t *ega = (ega_t *)p; + +if (addr != 0x3da && addr != 0x3ba) + pclog("ega_in %04X\n", addr); + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) + addr ^= 0x60; + switch (addr) { - case 0x3C0: return attraddr; - case 0x3C1: return attrregs[attraddr]; - case 0x3C2: + case 0x3c0: + return ega->attraddr; + case 0x3c1: + return ega->attrregs[ega->attraddr]; + case 0x3c2: // printf("Read egaswitch %02X %02X %i\n",egaswitchread,egaswitches,VGA); switch (egaswitchread) { - case 0xC: return (egaswitches&1)?0x10:0; - case 0x8: return (egaswitches&2)?0x10:0; - case 0x4: return (egaswitches&4)?0x10:0; - case 0x0: return (egaswitches&8)?0x10:0; + case 0xc: return (egaswitches & 1) ? 0x10 : 0; + case 0x8: return (egaswitches & 2) ? 0x10 : 0; + case 0x4: return (egaswitches & 4) ? 0x10 : 0; + case 0x0: return (egaswitches & 8) ? 0x10 : 0; } break; - case 0x3C4: return seqaddr; - case 0x3C5: - return seqregs[seqaddr&0xF]; - case 0x3CE: return gdcaddr; - case 0x3CF: - return gdcreg[gdcaddr&0xF]; - case 0x3D4: - return crtcreg; - case 0x3D5: - return crtc[crtcreg]; - case 0x3DA: - attrff=0; - cgastat^=0x30; /*Fools IBM EGA video BIOS self-test*/ - return cgastat; + case 0x3c4: + return ega->seqaddr; + case 0x3c5: + return ega->seqregs[ega->seqaddr & 0xf]; + case 0x3ce: + return ega->gdcaddr; + case 0x3cf: + return ega->gdcreg[ega->gdcaddr & 0xf]; + case 0x3d4: + return ega->crtcreg; + case 0x3d5: + return ega->crtc[ega->crtcreg]; + case 0x3da: + ega->attrff = 0; + ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ + return ega->stat; } // printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc); - return 0xFF; + return 0xff; } -static int linepos,displine,vslines; -static int egadispon; -static uint32_t ma,ca,maback; -static int vc,sc; -static int con,cursoron,cgablink; -static int scrollcache; -#define vrammask 0x3FFFF - -void ega_recalctimings() +void ega_recalctimings(ega_t *ega) { - double _dispontime, _dispofftime; + double _dispontime, _dispofftime, disptime; double crtcconst; - ega_vtotal=crtc[6]; - ega_dispend=crtc[0x12]; - ega_vsyncstart=crtc[0x10]; - ega_split=crtc[0x18]; + ega->vtotal = ega->crtc[6]; + ega->dispend = ega->crtc[0x12]; + ega->vsyncstart = ega->crtc[0x10]; + ega->split = ega->crtc[0x18]; - if (crtc[7]&1) ega_vtotal|=0x100; - if (crtc[7]&32) ega_vtotal|=0x200; - ega_vtotal++; + if (ega->crtc[7] & 1) ega->vtotal |= 0x100; + if (ega->crtc[7] & 32) ega->vtotal |= 0x200; + ega->vtotal++; - if (crtc[7]&2) ega_dispend|=0x100; - if (crtc[7]&64) ega_dispend|=0x200; - ega_dispend++; + if (ega->crtc[7] & 2) ega->dispend |= 0x100; + if (ega->crtc[7] & 64) ega->dispend |= 0x200; + ega->dispend++; - if (crtc[7]&4) ega_vsyncstart|=0x100; - if (crtc[7]&128) ega_vsyncstart|=0x200; - ega_vsyncstart++; + if (ega->crtc[7] & 4) ega->vsyncstart |= 0x100; + if (ega->crtc[7] & 128) ega->vsyncstart |= 0x200; + ega->vsyncstart++; - if (crtc[7]&0x10) ega_split|=0x100; - if (crtc[9]&0x40) ega_split|=0x200; - ega_split+=2; + if (ega->crtc[7] & 0x10) ega->split |= 0x100; + if (ega->crtc[9] & 0x40) ega->split |= 0x200; + ega->split+=2; - ega_hdisp=crtc[1]; - ega_hdisp++; + ega->hdisp = ega->crtc[1]; + ega->hdisp++; - ega_rowoffset=crtc[0x13]; + ega->rowoffset = ega->crtc[0x13]; - printf("Recalc! %i %i %i %i %i %02X\n",ega_vtotal,ega_dispend,ega_vsyncstart,ega_split,ega_hdisp,attrregs[0x16]); + printf("Recalc! %i %i %i %i %i %02X\n", ega->vtotal, ega->dispend, ega->vsyncstart, ega->split, ega->hdisp, ega->attrregs[0x16]); - if (vidclock) crtcconst=(seqregs[1]&1)?(MDACONST*(8.0/9.0)):MDACONST; - else crtcconst=(seqregs[1]&1)?(CGACONST*(8.0/9.0)):CGACONST; + if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); + else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); - disptime=crtc[0]+2; - _dispontime=crtc[1]+1; + disptime = ega->crtc[0] + 2; + _dispontime = ega->crtc[1] + 1; - printf("Disptime %f dispontime %f hdisp %i\n",disptime,_dispontime,crtc[1]*8); - if (seqregs[1]&8) { disptime*=2; _dispontime*=2; } - _dispofftime=disptime-_dispontime; - _dispontime*=crtcconst; - _dispofftime*=crtcconst; - - dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + printf("Disptime %f dispontime %f hdisp %i\n", disptime, _dispontime, ega->crtc[1] * 8); + if (ega->seqregs[1] & 8) + { + disptime*=2; + _dispontime*=2; + } + _dispofftime = disptime - _dispontime; + _dispontime *= crtcconst; + _dispofftime *= crtcconst; + ega->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + ega->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime / (1 << TIMER_SHIFT), + ega->dispofftime, (float)ega->dispofftime / (1 << TIMER_SHIFT)); // printf("EGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4)); // printf("EGA vert total %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart); // printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*ega_vtotal,(dispontime+dispofftime)*ega_vtotal*70,seqregs[1]); } -void ega_poll() +void ega_poll(void *p) { - uint8_t chr,dat,attr; + ega_t *ega = (ega_t *)p; + uint8_t chr, dat, attr; uint32_t charaddr; - int x,xx; - uint32_t fg,bg; + int x, xx; + uint32_t fg, bg; int offset; uint8_t edat[4]; - int drawcursor=0; + int drawcursor = 0; - if (!linepos) + if (!ega->linepos) { - vidtime+=dispofftime; + ega->vidtime += ega->dispofftime; - cgastat|=1; - linepos=1; + ega->stat |= 1; + ega->linepos = 1; - if (egadispon) + if (ega->dispon) { - if (firstline==2000) firstline=displine; + if (ega->firstline == 2000) + ega->firstline = ega->displine; - if (scrblank) + if (ega->scrblank) { - for (x=0;xhdisp; x++) { - switch (seqregs[1]&9) + switch (ega->seqregs[1] & 9) { case 0: - for (xx=0;xx<9;xx++) ((uint32_t *)buffer32->line[displine])[(x*9)+xx+32]=0; + for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[ega->displine])[(x * 9) + xx + 32] = 0; break; case 1: - for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[(x*8)+xx+32]=0; + for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[ega->displine])[(x * 8) + xx + 32] = 0; break; case 8: - for (xx=0;xx<18;xx++) ((uint32_t *)buffer32->line[displine])[(x*18)+xx+32]=0; + for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[ega->displine])[(x * 18) + xx + 32] = 0; break; case 9: - for (xx=0;xx<16;xx++) ((uint32_t *)buffer32->line[displine])[(x*16)+xx+32]=0; + for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[ega->displine])[(x * 16) + xx + 32] = 0; break; } } } - else if (!(gdcreg[6]&1)) + else if (!(ega->gdcreg[6] & 1)) { if (fullchange) { - for (x=0;xhdisp; x++) { - drawcursor=((ma==ca) && con && cursoron); - chr=vram[(ma<<1)]; - attr=vram[(ma<<1)+4]; + drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + chr = ega->vram[(ega->ma << 1) & ega->vrammask]; + attr = ega->vram[((ega->ma << 1) + 4) & ega->vrammask]; - if (attr&8) charaddr=charsetb+(chr*128); - else charaddr=charseta+(chr*128); + if (attr & 8) charaddr = ega->charsetb + (chr * 128); + else charaddr = ega->charseta + (chr * 128); - if (drawcursor) { bg=pallook[egapal[attr&15]]; fg=pallook[egapal[attr>>4]]; } + if (drawcursor) + { + bg = ega->pallook[ega->egapal[attr & 15]]; + fg = ega->pallook[ega->egapal[attr >> 4]]; + } else { - fg=pallook[egapal[attr&15]]; - bg=pallook[egapal[attr>>4]]; - if (attr&0x80 && attrregs[0x10]&8) + fg = ega->pallook[ega->egapal[attr & 15]]; + bg = ega->pallook[ega->egapal[attr >> 4]]; + if (attr & 0x80 && ega->attrregs[0x10] & 8) { - bg=pallook[egapal[(attr>>4)&7]]; - if (cgablink&16) fg=bg; + bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; + if (ega->blink & 16) + fg = bg; } } - dat=vram[charaddr+(sc<<2)]; - if (seqregs[1]&8) + dat = ega->vram[charaddr + (ega->sc << 2)]; + if (ega->seqregs[1] & 8) { - if (seqregs[1]&1) { for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x<<4)+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[((x<<4)+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; } + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x << 4) + 32 + (xx << 1)) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x << 4) + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + } else { - for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x*18)+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; - if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) ((uint32_t *)buffer32->line[displine])[((x*18)+32+16)&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+32+17)&2047]=bg; - else ((uint32_t *)buffer32->line[displine])[((x*18)+32+16)&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+32+17)&2047]=(dat&1)?fg:bg; + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + (xx << 1)) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = bg; + else + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = (dat & 1) ? fg : bg; } } else { - if (seqregs[1]&1) { for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x<<3)+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; } + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x << 3) + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + } else { - for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x*9)+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; - if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) ((uint32_t *)buffer32->line[displine])[((x*9)+32+8)&2047]=bg; - else ((uint32_t *)buffer32->line[displine])[((x*9)+32+8)&2047]=(dat&1)?fg:bg; + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = bg; + else + ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = (dat & 1) ? fg : bg; } } - ma+=4; ma&=vrammask; + ega->ma += 4; + ega->ma &= ega->vrammask; } } } else { - switch (gdcreg[5]&0x20) + switch (ega->gdcreg[5] & 0x20) { case 0x00: - if (seqregs[1]&8) + if (ega->seqregs[1] & 8) { - offset=((8-scrollcache)<<1)+16; - for (x=0;x<=ega_hdisp;x++) + offset = ((8 - ega->scrollcache) << 1) + 16; + for (x = 0; x <= ega->hdisp; x++) { - if (sc&1 && !(crtc[0x17]&1)) + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) { - edat[0] = vram[ma | 0x8000]; - edat[1] = vram[ma | 0x8001]; - edat[2] = vram[ma | 0x8002]; - edat[3] = vram[ma | 0x8003]; + edat[0] = ega->vram[ega->ma | 0x8000]; + edat[1] = ega->vram[ega->ma | 0x8001]; + edat[2] = ega->vram[ega->ma | 0x8002]; + edat[3] = ega->vram[ega->ma | 0x8003]; } else { - edat[0] = vram[ma]; - edat[1] = vram[ma | 0x1]; - edat[2] = vram[ma | 0x2]; - edat[3] = vram[ma | 0x3]; + edat[0] = ega->vram[ega->ma]; + edat[1] = ega->vram[ega->ma | 0x1]; + edat[2] = ega->vram[ega->ma | 0x2]; + edat[3] = ega->vram[ega->ma | 0x3]; } - ma+=4; ma&=vrammask; + ega->ma += 4; + ega->ma &= ega->vrammask; - dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2); - ((uint32_t *)buffer32->line[displine])[(x<<4)+14+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+15+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]]; - ((uint32_t *)buffer32->line[displine])[(x<<4)+12+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+13+offset]=pallook[egapal[(dat >> 4) & attrregs[0x12]]]; - 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<<4)+10+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+11+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]]; - ((uint32_t *)buffer32->line[displine])[(x<<4)+8+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+9+offset]=pallook[egapal[(dat >> 4) & attrregs[0x12]]]; - 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<<4)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+7+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]]; - ((uint32_t *)buffer32->line[displine])[(x<<4)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+5+offset]=pallook[egapal[(dat >> 4) & attrregs[0x12]]]; - dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); - ((uint32_t *)buffer32->line[displine])[(x<<4)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+3+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]]; - ((uint32_t *)buffer32->line[displine])[(x<<4)+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+1+offset]=pallook[egapal[(dat >> 4) & attrregs[0x12]]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 14 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 10 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 8 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 9 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 6 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 7 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 4 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 5 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 2 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 3 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 1 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; } } else { - offset=(8-scrollcache)+24; - for (x=0;x<=ega_hdisp;x++) + offset = (8 - ega->scrollcache) + 24; + for (x = 0; x <= ega->hdisp; x++) { - if (sc&1 && !(crtc[0x17]&1)) + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) { - edat[0] = vram[ma | 0x8000]; - edat[1] = vram[ma | 0x8001]; - edat[2] = vram[ma | 0x8002]; - edat[3] = vram[ma | 0x8003]; + edat[0] = ega->vram[ega->ma | 0x8000]; + edat[1] = ega->vram[ega->ma | 0x8001]; + edat[2] = ega->vram[ega->ma | 0x8002]; + edat[3] = ega->vram[ega->ma | 0x8003]; } else { - edat[0] = vram[ma]; - edat[1] = vram[ma | 0x1]; - edat[2] = vram[ma | 0x2]; - edat[3] = vram[ma | 0x3]; + edat[0] = ega->vram[ega->ma]; + edat[1] = ega->vram[ega->ma | 0x1]; + edat[2] = ega->vram[ega->ma | 0x2]; + edat[3] = ega->vram[ega->ma | 0x3]; } - ma+=4; ma&=vrammask; + ega->ma += 4; + ega->ma &= ega->vrammask; - dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2); - ((uint32_t *)buffer32->line[displine])[(x<<3)+7+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]]; - ((uint32_t *)buffer32->line[displine])[(x<<3)+6+offset]=pallook[egapal[(dat >> 4) & attrregs[0x12]]]; - 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<<3)+5+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]]; - ((uint32_t *)buffer32->line[displine])[(x<<3)+4+offset]=pallook[egapal[(dat >> 4) & attrregs[0x12]]]; - 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)+3+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]]; - ((uint32_t *)buffer32->line[displine])[(x<<3)+2+offset]=pallook[egapal[(dat >> 4) & attrregs[0x12]]]; - dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); - ((uint32_t *)buffer32->line[displine])[(x<<3)+1+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]]; - ((uint32_t *)buffer32->line[displine])[(x<<3)+offset]= pallook[egapal[(dat >> 4) & attrregs[0x12]]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 7 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 6 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 5 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 4 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 3 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 2 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 1 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; } } break; case 0x20: - offset=((8-scrollcache)<<1)+16; - for (x=0;x<=ega_hdisp;x++) + offset = ((8 - ega->scrollcache) << 1) + 16; + for (x = 0; x <= ega->hdisp; x++) { - if (sc&1 && !(crtc[0x17]&1)) + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) { - edat[0]=vram[(ma<<1)+0x8000]; - edat[1]=vram[(ma<<1)+0x8004]; + edat[0] = ega->vram[(ega->ma << 1) + 0x8000]; + edat[1] = ega->vram[(ega->ma << 1) + 0x8004]; } else { - edat[0]=vram[(ma<<1)]; - edat[1]=vram[(ma<<1)+4]; + edat[0] = ega->vram[(ega->ma << 1)]; + edat[1] = ega->vram[(ega->ma << 1) + 4]; } - ma+=4; ma&=vrammask; + ega->ma += 4; + ega->ma &= ega->vrammask; - ((uint32_t *)buffer32->line[displine])[(x<<4)+14+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+15+offset]=pallook[egapal[edat[1]&3]]; - ((uint32_t *)buffer32->line[displine])[(x<<4)+12+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+13+offset]=pallook[egapal[(edat[1]>>2)&3]]; - dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2); - ((uint32_t *)buffer32->line[displine])[(x<<4)+10+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+11+offset]=pallook[egapal[(edat[1]>>4)&3]]; - ((uint32_t *)buffer32->line[displine])[(x<<4)+8+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+9+offset]=pallook[egapal[(edat[1]>>6)&3]]; - dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2); - ((uint32_t *)buffer32->line[displine])[(x<<4)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+7+offset]=pallook[egapal[(edat[0]>>0)&3]]; - ((uint32_t *)buffer32->line[displine])[(x<<4)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+5+offset]=pallook[egapal[(edat[0]>>2)&3]]; - dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); - ((uint32_t *)buffer32->line[displine])[(x<<4)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+3+offset]=pallook[egapal[(edat[0]>>4)&3]]; - ((uint32_t *)buffer32->line[displine])[(x<<4)+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+1+offset]=pallook[egapal[(edat[0]>>6)&3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 14 + offset]= ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = ega->pallook[ega->egapal[edat[1] & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 10 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 8 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 9 + offset] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 6 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 7 + offset] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 4 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 5 + offset] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 2 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 3 + offset] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 1 + offset] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; } break; } } - if (lastlinelastline < ega->displine) + ega->lastline = ega->displine; } - displine++; - if ((cgastat&8) && ((displine&15)==(crtc[0x11]&15)) && vslines) - cgastat&=~8; - vslines++; - if (displine>500) displine=0; + ega->displine++; + if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) + ega->stat &= ~8; + ega->vslines++; + if (ega->displine > 500) + ega->displine = 0; } else { - vidtime+=dispontime; + ega->vidtime += ega->dispontime; // if (output) printf("Display on %f\n",vidtime); - if (egadispon) cgastat&=~1; - linepos=0; - if (sc==(crtc[11]&31)) - con=0; - if (egadispon) + if (ega->dispon) + ega->stat &= ~1; + ega->linepos = 0; + if (ega->sc == (ega->crtc[11] & 31)) + ega->con = 0; + if (ega->dispon) { - if (sc==(crtc[9]&31)) + if (ega->sc == (ega->crtc[9] & 31)) { - sc=0; + ega->sc = 0; - maback+=(ega_rowoffset<<3); - maback&=vrammask; - ma=maback; + ega->maback += (ega->rowoffset << 3); + ega->maback &= ega->vrammask; + ega->ma = ega->maback; } else { - sc++; - sc&=31; - ma=maback; + ega->sc++; + ega->sc &= 31; + ega->ma = ega->maback; } } - vc++; - vc&=1023; + ega->vc++; + ega->vc &= 1023; // printf("Line now %i %i ma %05X\n",vc,displine,ma); - if (vc==ega_split) + if (ega->vc == ega->split) { // printf("Split at line %i %i\n",displine,vc); - ma=maback=0; - if (attrregs[0x10]&0x20) scrollcache=0; + ega->ma = ega->maback = 0; + if (ega->attrregs[0x10] & 0x20) + ega->scrollcache = 0; } - if (vc==ega_dispend) + if (ega->vc == ega->dispend) { // printf("Display over at line %i %i\n",displine,vc); - egadispon=0; - if (crtc[10] & 0x20) cursoron=0; - else cursoron=cgablink&16; - if (!(gdcreg[6]&1) && !(cgablink&15)) fullchange=2; - cgablink++; + ega->dispon=0; + if (ega->crtc[10] & 0x20) ega->cursoron = 0; + else ega->cursoron = ega->blink & 16; + if (!(ega->gdcreg[6] & 1) && !(ega->blink & 15)) + fullchange = 2; + ega->blink++; - for (x=0;x<2048;x++) if (changedvram[x]) changedvram[x]--; -// memset(changedvram,0,2048); - if (fullchange) fullchange--; + if (fullchange) + fullchange--; } - if (vc==ega_vsyncstart) + if (ega->vc == ega->vsyncstart) { - egadispon=0; + int wx, wy; + ega->dispon = 0; // printf("Vsync on at line %i %i\n",displine,vc); - cgastat|=8; - if (seqregs[1]&8) x=ega_hdisp*((seqregs[1]&1)?8:9)*2; - else x=ega_hdisp*((seqregs[1]&1)?8:9); - wx=x; - wy=lastline-firstline; + ega->stat |= 8; + if (ega->seqregs[1] & 8) x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9) * 2; + else x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9); // pclog("Cursor %02X %02X\n",crtc[10],crtc[11]); // pclog("Firstline %i Lastline %i wx %i %i\n",firstline,lastline,wx,oddeven); // doblit(); - svga_doblit(firstline, lastline + 1); - - video_res_x = wx; - video_res_y = wy + 1; - if (!(gdcreg[6]&1)) /*Text mode*/ + if (x != xsize || (ega->lastline - ega->firstline) != ysize) { - video_res_x /= (seqregs[1] & 1) ? 8 : 9; - video_res_y /= (crtc[9] & 31) + 1; - video_bpp = 0; + xsize = x; + ysize = ega->lastline - ega->firstline; + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + if (ega->vres) + updatewindowsize(xsize, ysize << 1); + else + updatewindowsize(xsize, ysize); + } + +startblit(); + video_blit_memtoscreen(32, 0, ega->firstline, ega->lastline, xsize, ega->lastline - ega->firstline); +endblit(); + + frames++; + + ega->video_res_x = wx; + ega->video_res_y = wy + 1; + if (!(ega->gdcreg[6] & 1)) /*Text mode*/ + { + ega->video_res_x /= (ega->seqregs[1] & 1) ? 8 : 9; + ega->video_res_y /= (ega->crtc[9] & 31) + 1; + ega->video_bpp = 0; } else { - if (crtc[9] & 0x80) - video_res_y /= 2; - if (!(crtc[0x17] & 1)) - video_res_y *= 2; - video_res_y /= (crtc[9] & 31) + 1; - if (seqregs[1] & 8) - video_res_x /= 2; - video_bpp = (gdcreg[5] & 0x20) ? 2 : 4; + if (ega->crtc[9] & 0x80) + ega->video_res_y /= 2; + if (!(ega->crtc[0x17] & 1)) + ega->video_res_y *= 2; + ega->video_res_y /= (ega->crtc[9] & 31) + 1; + if (ega->seqregs[1] & 8) + ega->video_res_x /= 2; + ega->video_bpp = (ega->gdcreg[5] & 0x20) ? 2 : 4; } // wakeupblit(); readflash=0; //framecount++; - firstline=2000; - lastline=0; + ega->firstline = 2000; + ega->lastline = 0; - maback=ma=(crtc[0xC]<<8)|crtc[0xD]; - ca=(crtc[0xE]<<8)|crtc[0xF]; - ma<<=2; - maback<<=2; - ca<<=2; - changeframecount=2; - vslines=0; + ega->maback = ega->ma = (ega->crtc[0xc] << 8)| ega->crtc[0xd]; + ega->ca = (ega->crtc[0xe] << 8) | ega->crtc[0xf]; + ega->ma <<= 2; + ega->maback <<= 2; + ega->ca <<= 2; + changeframecount = 2; + ega->vslines = 0; } - if (vc==ega_vtotal) + if (ega->vc == ega->vtotal) { - vc=0; - sc=0; - egadispon=1; - displine=0; - scrollcache=attrregs[0x13]&7; + ega->vc = 0; + ega->sc = 0; + ega->dispon = 1; + ega->displine = 0; + ega->scrollcache = ega->attrregs[0x13] & 7; } - if (sc == (crtc[10] & 31)) con=1; + if (ega->sc == (ega->crtc[10] & 31)) + ega->con = 1; } } -void ega_write(uint32_t addr, uint8_t val, void *priv) +void ega_write(uint32_t addr, uint8_t val, void *p) { - uint8_t vala,valb,valc,vald; + ega_t *ega = (ega_t *)p; + uint8_t vala, valb, valc, vald; egawrites++; cycles -= video_timing_b; cycles_lost += video_timing_b; - if (addr>=0xB0000) addr &= 0x7fff; - else addr &= 0xffff; + if (addr >= 0xB0000) addr &= 0x7fff; + else addr &= 0xffff; - if (!(gdcreg[6]&1)) fullchange=2; + if (!(ega->gdcreg[6] & 1)) + fullchange = 2; addr <<= 2; // pclog("%i %08X %i %i %02X %02X %02X %02X %02X\n",chain4,addr,writemode,writemask,gdcreg[8],vram[0],vram[1],vram[2],vram[3]); - switch (writemode) + switch (ega->writemode) + { + case 1: + if (ega->writemask & 1) ega->vram[addr] = ega->la; + if (ega->writemask & 2) ega->vram[addr | 0x1] = ega->lb; + if (ega->writemask & 4) ega->vram[addr | 0x2] = ega->lc; + if (ega->writemask & 8) ega->vram[addr | 0x3] = ega->ld; + break; + case 0: + if (ega->gdcreg[3] & 7) + val = ega_rotate[ega->gdcreg[3] & 7][val]; + + if (ega->gdcreg[8] == 0xff && !(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) { - case 1: - if (writemask&1) vram[addr]=la; - if (writemask&2) vram[addr|0x1]=lb; - if (writemask&4) vram[addr|0x2]=lc; - if (writemask&8) vram[addr|0x3]=ld; - break; - case 0: - if (gdcreg[3]&7) val=ega_rotate[gdcreg[3]&7][val]; - if (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) - { -// pclog("Easy write %05X %02X\n",addr,val); - if (writemask&1) vram[addr]=val; - if (writemask&2) vram[addr|0x1]=val; - if (writemask&4) vram[addr|0x2]=val; - if (writemask&8) vram[addr|0x3]=val; - } - else - { - if (gdcreg[1]&1) vala=(gdcreg[0]&1)?0xFF:0; - else vala=val; - if (gdcreg[1]&2) valb=(gdcreg[0]&2)?0xFF:0; - else valb=val; - if (gdcreg[1]&4) valc=(gdcreg[0]&4)?0xFF:0; - else valc=val; - if (gdcreg[1]&8) vald=(gdcreg[0]&8)?0xFF:0; - else vald=val; -// pclog("Write %02X %01X %02X %02X %02X %02X %02X\n",gdcreg[3]&0x18,writemask,vala,valb,valc,vald,gdcreg[8]); - switch (gdcreg[3]&0x18) - { - case 0: /*Set*/ - if (writemask&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); - if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask&1) vram[addr]=(vala|~gdcreg[8])&la; - if (writemask&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; - if (writemask&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; - if (writemask&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; - break; - case 0x10: /*OR*/ - if (writemask&1) vram[addr]=(vala&gdcreg[8])|la; - if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; - if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; - if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; - break; - case 0x18: /*XOR*/ - if (writemask&1) vram[addr]=(vala&gdcreg[8])^la; - if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; - if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; - if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; - break; - } -// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); - } - break; - case 2: - if (!(gdcreg[3]&0x18) && !gdcreg[1]) - { - if (writemask&1) vram[addr]=(((val&1)?0xFF:0)&gdcreg[8])|(la&~gdcreg[8]); - if (writemask&2) vram[addr|0x1]=(((val&2)?0xFF:0)&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask&4) vram[addr|0x2]=(((val&4)?0xFF:0)&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask&8) vram[addr|0x3]=(((val&8)?0xFF:0)&gdcreg[8])|(ld&~gdcreg[8]); - } - else - { - vala=((val&1)?0xFF:0); - valb=((val&2)?0xFF:0); - valc=((val&4)?0xFF:0); - vald=((val&8)?0xFF:0); - switch (gdcreg[3]&0x18) - { - case 0: /*Set*/ - if (writemask&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); - if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask&1) vram[addr]=(vala|~gdcreg[8])&la; - if (writemask&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; - if (writemask&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; - if (writemask&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; - break; - case 0x10: /*OR*/ - if (writemask&1) vram[addr]=(vala&gdcreg[8])|la; - if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; - if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; - if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; - break; - case 0x18: /*XOR*/ - if (writemask&1) vram[addr]=(vala&gdcreg[8])^la; - if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; - if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; - if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; - break; - } - } - break; + if (ega->writemask & 1) ega->vram[addr] = val; + if (ega->writemask & 2) ega->vram[addr | 0x1] = val; + if (ega->writemask & 4) ega->vram[addr | 0x2] = val; + if (ega->writemask & 8) ega->vram[addr | 0x3] = val; } + else + { + if (ega->gdcreg[1] & 1) vala = (ega->gdcreg[0] & 1) ? 0xff : 0; + else vala = val; + if (ega->gdcreg[1] & 2) valb = (ega->gdcreg[0] & 2) ? 0xff : 0; + else valb = val; + if (ega->gdcreg[1] & 4) valc = (ega->gdcreg[0] & 4) ? 0xff : 0; + else valc = val; + if (ega->gdcreg[1] & 8) vald = (ega->gdcreg[0] & 8) ? 0xff : 0; + else vald = val; +// pclog("Write %02X %01X %02X %02X %02X %02X %02X\n",gdcreg[3]&0x18,writemask,vala,valb,valc,vald,gdcreg[8]); + switch (ega->gdcreg[3] & 0x18) + { + case 0: /*Set*/ + if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); + if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); + if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); + if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); + break; + case 8: /*AND*/ + if (ega->writemask & 1) ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; + if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; + if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; + if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; + break; + case 0x10: /*OR*/ + if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; + if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; + if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; + if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; + break; + case 0x18: /*XOR*/ + if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; + if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; + if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; + if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; + break; + } +// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); + } + break; + case 2: + if (!(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) + { + if (ega->writemask & 1) ega->vram[addr] = (((val & 1) ? 0xff : 0) & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); + if (ega->writemask & 2) ega->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); + if (ega->writemask & 4) ega->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); + if (ega->writemask & 8) ega->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); + } + else + { + vala = ((val & 1) ? 0xff : 0); + valb = ((val & 2) ? 0xff : 0); + valc = ((val & 4) ? 0xff : 0); + vald = ((val & 8) ? 0xff : 0); + switch (ega->gdcreg[3] & 0x18) + { + case 0: /*Set*/ + if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); + if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); + if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); + if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); + break; + case 8: /*AND*/ + if (ega->writemask & 1) ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; + if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; + if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; + if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; + break; + case 0x10: /*OR*/ + if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; + if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; + if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; + if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; + break; + case 0x18: /*XOR*/ + if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; + if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; + if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; + if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; + break; + } + } + break; + } } -uint8_t ega_read(uint32_t addr, void *priv) +uint8_t ega_read(uint32_t addr, void *p) { - uint8_t temp,temp2,temp3,temp4; + ega_t *ega = (ega_t *)p; + uint8_t temp, temp2, temp3, temp4; egareads++; cycles -= video_timing_b; cycles_lost += video_timing_b; // pclog("Readega %06X ",addr); - if (addr>=0xB0000) addr &= 0x7fff; - else addr &= 0xffff; - addr<<=2; - la=vram[addr]; - lb=vram[addr|0x1]; - lc=vram[addr|0x2]; - ld=vram[addr|0x3]; - if (readmode) + if (addr >= 0xb0000) addr &= 0x7fff; + else addr &= 0xffff; + addr <<= 2; + ega->la = ega->vram[addr]; + ega->lb = ega->vram[addr | 0x1]; + ega->lc = ega->vram[addr | 0x2]; + ega->ld = ega->vram[addr | 0x3]; + if (ega->readmode) { - temp= (colournocare&1) ?0xFF:0; - temp&=la; - temp^=(colourcompare&1)?0xFF:0; - temp2= (colournocare&2) ?0xFF:0; - temp2&=lb; - temp2^=(colourcompare&2)?0xFF:0; - temp3= (colournocare&4) ?0xFF:0; - temp3&=lc; - temp3^=(colourcompare&4)?0xFF:0; - temp4= (colournocare&8) ?0xFF:0; - temp4&=ld; - temp4^=(colourcompare&8)?0xFF:0; - return ~(temp|temp2|temp3|temp4); + temp = (ega->colournocare & 1) ? 0xff : 0; + temp &= ega->la; + temp ^= (ega->colourcompare & 1) ? 0xff : 0; + temp2 = (ega->colournocare & 2) ? 0xff : 0; + temp2 &= ega->lb; + temp2 ^= (ega->colourcompare & 2) ? 0xff : 0; + temp3 = (ega->colournocare & 4) ? 0xff : 0; + temp3 &= ega->lc; + temp3 ^= (ega->colourcompare & 4) ? 0xff : 0; + temp4 = (ega->colournocare & 8) ? 0xff : 0; + temp4 &= ega->ld; + temp4 ^= (ega->colourcompare & 8) ? 0xff : 0; + return ~(temp | temp2 | temp3 | temp4); } - return vram[addr|readplane]; + return ega->vram[addr | ega->readplane]; } -int ega_init() +void ega_init(ega_t *ega) { int c, d, e; + + ega->vram = malloc(0x40000); + ega->vrammask = 0x3ffff; + for (c = 0; c < 256; c++) { e = c; @@ -693,28 +781,64 @@ int ega_init() e = (e >> 1) | ((e & 1) ? 0x80 : 0); } } - return 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; + } + } + + 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); + } + ega->pallook = pallook16; } -GFXCARD vid_ega = +void *ega_standalone_init() { - ega_init, - /*IO at 3Cx/3Dx*/ - ega_out, - ega_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, + int c, d, e; + ega_t *ega = malloc(sizeof(ega_t)); + memset(ega, 0, sizeof(ega_t)); - ega_poll, - ega_recalctimings, + ega_init(ega); - ega_write, - video_write_null, - video_write_null, + timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); + io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + return ega; +} - ega_read, - video_read_null, - video_read_null +void ega_close(void *p) +{ + ega_t *ega = (ega_t *)p; + + free(ega->vram); + free(ega); +} + +void ega_speed_changed(void *p) +{ + ega_t *ega = (ega_t *)p; + + ega_recalctimings(ega); +} + +device_t ega_device = +{ + "EGA", + ega_standalone_init, + ega_close, + ega_speed_changed, + NULL }; - diff --git a/src/vid_ega.h b/src/vid_ega.h index ea8c286..c90a19f 100644 --- a/src/vid_ega.h +++ b/src/vid_ega.h @@ -1,7 +1,71 @@ -int ega_init(); -void ega_out(uint16_t addr, uint8_t val, void *priv); -uint8_t ega_in(uint16_t addr, void *priv); -void ega_poll(); -void ega_recalctimings(); -void ega_write(uint32_t addr, uint8_t val, void *priv); -uint8_t ega_read(uint32_t addr, void *priv); +typedef struct ega_t +{ + uint8_t crtcreg; + uint8_t crtc[32]; + uint8_t gdcreg[16]; + int gdcaddr; + uint8_t attrregs[32]; + int attraddr, attrff; + uint8_t seqregs[64]; + int seqaddr; + + uint8_t miscout; + int vidclock; + + uint8_t la, lb, lc, ld; + + uint8_t stat; + + int fast; + uint8_t colourcompare, colournocare; + int readmode, writemode, readplane; + int chain4; + uint8_t writemask; + uint32_t charseta, charsetb; + + uint8_t egapal[16]; + uint32_t *pallook; + + int vtotal, dispend, vsyncstart, split; + int hdisp, htotal, hdisp_time, rowoffset; + int lowres, interlace; + int linedbl, rowcount; + double clock; + uint32_t ma_latch; + + int vres; + + int dispontime, dispofftime; + int vidtime; + + uint8_t scrblank; + + int dispon; + int hdisp_on; + + uint32_t ma, maback, ca; + int vc; + int sc; + int linepos, vslines, linecountff, oddeven; + int con, cursoron, blink; + int scrollcache; + + int firstline, lastline; + int firstline_draw, lastline_draw; + int displine; + + uint8_t *vram; + int vrammask; + + int video_res_x, video_res_y, video_bpp; +} ega_t; + +void *ega_standalone_init(); +void ega_out(uint16_t addr, uint8_t val, void *p); +uint8_t ega_in(uint16_t addr, void *p); +void ega_poll(void *p); +void ega_recalctimings(struct ega_t *ega); +void ega_write(uint32_t addr, uint8_t val, void *p); +uint8_t ega_read(uint32_t addr, void *p); + +extern device_t ega_device; diff --git a/src/vid_et4000.c b/src/vid_et4000.c index a2966b8..8a84f11 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -1,141 +1,156 @@ /*ET4000 emulation*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "video.h" #include "vid_svga.h" #include "vid_unk_ramdac.h" -int et4k_b8000; +#include "vid_et4000.h" - -void et4000_out(uint16_t addr, uint8_t val, void *priv) +typedef struct et4000_t { + svga_t svga; + unk_ramdac_t ramdac; + + uint8_t banking; +} et4000_t; + +void et4000_out(uint16_t addr, uint8_t val, void *p) +{ + et4000_t *et4000 = (et4000_t *)p; + svga_t *svga = &et4000->svga; + uint8_t old; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; pclog("ET4000 out %04X %02X\n", addr, val); switch (addr) { case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - unk_ramdac_out(addr, val, NULL); + unk_ramdac_out(addr, val, &et4000->ramdac, svga); return; case 0x3CD: /*Banking*/ - svgawbank=(val&0xF)*65536; - svgarbank=((val>>4)&0xF)*65536; - svgaseg=val; - pclog("Banking write %08X %08X %02X\n", svgawbank, svgarbank, val); + svga->write_bank = (val & 0xf) * 0x10000; + svga->read_bank = ((val >> 4) & 0xf) * 0x10000; + et4000->banking = val; + pclog("Banking write %08X %08X %02X\n", svga->write_bank, svga->read_bank, val); return; - case 0x3CF: - switch (gdcaddr&15) - { - case 6: - et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4); - break; - } - break; case 0x3D4: - crtcreg = val & 0x3f; + svga->crtcreg = val & 0x3f; return; case 0x3D5: - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; - et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4); - if (old!=val) + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(svga); } } break; - case 0x3D8: - if (val==0xA0) svgaon=1; - if (val==0x29) svgaon=0; - break; } - svga_out(addr, val, priv); + svga_out(addr, val, svga); } -uint8_t et4000_in(uint16_t addr, void *priv) +uint8_t et4000_in(uint16_t addr, void *p) { - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + et4000_t *et4000 = (et4000_t *)p; + svga_t *svga = &et4000->svga; + + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr); switch (addr) { case 0x3C5: - if ((seqaddr&0xF)==7) return seqregs[seqaddr&0xF]|4; + if ((svga->seqaddr & 0xf) == 7) return svga->seqregs[svga->seqaddr & 0xf] | 4; break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return unk_ramdac_in(addr, NULL); + return unk_ramdac_in(addr, &et4000->ramdac, svga); case 0x3CD: /*Banking*/ - return svgaseg; + return et4000->banking; case 0x3D4: - return crtcreg; + return svga->crtcreg; case 0x3D5: - return crtc[crtcreg]; + return svga->crtc[svga->crtcreg]; } - return svga_in(addr, priv); + return svga_in(addr, svga); } -void et4000_recalctimings() +void et4000_recalctimings(svga_t *svga) { - svga_ma|=(crtc[0x33]&3)<<16; - if (crtc[0x35]&2) svga_vtotal+=0x400; - if (crtc[0x35]&4) svga_dispend+=0x400; - if (crtc[0x35]&8) svga_vsyncstart+=0x400; - if (crtc[0x35]&0x10) svga_split+=0x400; - if (!svga_rowoffset) svga_rowoffset=0x100; -// if (crtc[0x3F]&0x80) svga_rowoffset+=0x100; - if (crtc[0x3F]&1) svga_htotal+=256; - if (attrregs[0x16]&0x20) svga_hdisp<<=1; + et4000_t *et4000 = (et4000_t *)svga->p; + + svga->ma_latch |= (svga->crtc[0x33]&3)<<16; + if (svga->crtc[0x35] & 2) svga->vtotal += 0x400; + if (svga->crtc[0x35] & 4) svga->dispend += 0x400; + if (svga->crtc[0x35] & 8) svga->vsyncstart += 0x400; + if (svga->crtc[0x35] & 0x10) svga->split += 0x400; + if (!svga->rowoffset) svga->rowoffset = 0x100; + if (svga->crtc[0x3f] & 1) svga->htotal += 256; + if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; // pclog("Rowoffset %i\n",svga_rowoffset); - switch (((svga_miscout >> 2) & 3) | ((crtc[0x34] << 1) & 4)) + switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { case 0: case 1: break; - case 3: svga_clock = cpuclock/40000000.0; break; - case 5: svga_clock = cpuclock/65000000.0; break; - default: svga_clock = cpuclock/36000000.0; break; + case 3: svga->clock = cpuclock / 40000000.0; break; + case 5: svga->clock = cpuclock / 65000000.0; break; + default: svga->clock = cpuclock / 36000000.0; break; } } -int et4000_init() +void *et4000_init() { - svga_recalctimings_ex = et4000_recalctimings; - svga_vram_limit = 1 << 20; /*1mb*/ - vrammask = 0xfffff; - return svga_init(); + et4000_t *et4000 = malloc(sizeof(et4000_t)); + memset(et4000, 0, sizeof(et4000_t)); + + io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); + + svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ + et4000_recalctimings, + et4000_in, et4000_out, + NULL); + + return et4000; } -GFXCARD vid_et4000 = +void et4000_close(void *p) { + et4000_t *et4000 = (et4000_t *)p; + + svga_close(&et4000->svga); + + free(et4000); +} + +void et4000_speed_changed(void *p) +{ + et4000_t *et4000 = (et4000_t *)p; + + svga_recalctimings(&et4000->svga); +} + +device_t et4000_device = +{ + "Tseng Labs ET4000AX", et4000_init, - /*IO at 3Cx/3Dx*/ - et4000_out, - et4000_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - svga_poll, - svga_recalctimings, - - svga_write, - video_write_null, - video_write_null, - - svga_read, - video_read_null, - video_read_null + et4000_close, + et4000_speed_changed, + svga_add_status_info }; diff --git a/src/vid_et4000.h b/src/vid_et4000.h new file mode 100644 index 0000000..cc7e161 --- /dev/null +++ b/src/vid_et4000.h @@ -0,0 +1 @@ +extern device_t et4000_device; diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index 47493c2..6e5910f 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -3,8 +3,9 @@ - Accelerator doesn't work in planar modes */ - +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "pci.h" #include "video.h" @@ -13,719 +14,740 @@ #include "vid_stg_ramdac.h" #include "mem.h" -int et4k_b8000; - -void et4000w32p_recalcmapping(); - -uint8_t et4000w32p_mmu_read(uint32_t addr, void *priv); -void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv); - -static int et4000w32p_index; -static uint8_t et4000w32p_regs[256]; -static uint32_t et4000w32p_linearbase, et4000w32p_linearbase_old; - -void et4000w32p_out(uint16_t addr, uint8_t val, void *priv) +typedef struct et4000w32p_t { + svga_t svga; + stg_ramdac_t ramdac; + icd2061_t icd2061; + + int index; + uint8_t regs[256]; + uint32_t linearbase, linearbase_old; + + uint8_t banking, banking2; + + /*Accelerator*/ + struct + { + struct + { + uint32_t pattern_addr,source_addr,dest_addr,mix_addr; + uint16_t pattern_off,source_off,dest_off,mix_off; + uint8_t pixel_depth,xy_dir; + uint8_t pattern_wrap,source_wrap; + uint16_t count_x,count_y; + uint8_t ctrl_routing,ctrl_reload; + uint8_t rop_fg,rop_bg; + uint16_t pos_x,pos_y; + uint16_t error; + uint16_t dmin,dmaj; + } queued,internal; + uint32_t pattern_addr,source_addr,dest_addr,mix_addr; + uint32_t pattern_back,source_back,dest_back,mix_back; + int pattern_x,source_x; + int pattern_x_back,source_x_back; + int pattern_y,source_y; + uint8_t status; + uint64_t cpu_dat; + int cpu_dat_pos; + int pix_pos; + } acl; + + struct + { + uint32_t base[3]; + uint8_t ctrl; + } mmu; +} et4000w32p_t; + +void et4000w32p_recalcmapping(et4000w32p_t *et4000); + +uint8_t et4000w32p_mmu_read(uint32_t addr, void *p); +void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p); + +void et4000w32p_out(uint16_t addr, uint8_t val, void *p) +{ + et4000w32p_t *et4000 = (et4000w32p_t *)p; + svga_t *svga = &et4000->svga; uint8_t old; + pclog("et4000w32p_out: addr %04X val %02X %04X:%04X %02X %02X\n", addr, val, CS, pc, ram[0x487], ram[0x488]); + +/* if (ram[0x487] == 0x62) + fatal("mono\n");*/ // if (!(addr==0x3D4 && (val&~1)==0xE) && !(addr==0x3D5 && (crtcreg&~1)==0xE)) pclog("ET4000W32p out %04X %02X %04X:%04X ",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; // if (!(addr==0x3D4 && (val&~1)==0xE) && !(addr==0x3D5 && (crtcreg&~1)==0xE)) pclog("%04X\n",addr); switch (addr) { case 0x3c2: - icd2061_write((val >> 2) & 3); + icd2061_write(&et4000->icd2061, (val >> 2) & 3); break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - stg_ramdac_out(addr, val, NULL); + stg_ramdac_out(addr, val, &et4000->ramdac, svga); return; case 0x3CB: /*Banking extension*/ - svgawbank=(svgawbank&0xFFFFF)|((val&1)<<20); - svgarbank=(svgarbank&0xFFFFF)|((val&0x10)<<16); - svgaseg2=val; + svga->write_bank = (svga->write_bank & 0xfffff) | ((val & 1) << 20); + svga->read_bank = (svga->read_bank & 0xfffff) | ((val & 0x10) << 16); + et4000->banking2 = val; return; case 0x3CD: /*Banking*/ - svgawbank=(svgawbank&0x100000)|((val&0xF)*65536); - svgarbank=(svgarbank&0x100000)|(((val>>4)&0xF)*65536); - svgaseg=val; + svga->write_bank = (svga->write_bank & 0x100000) | ((val & 0xf) * 65536); + svga->read_bank = (svga->read_bank & 0x100000) | (((val >> 4) & 0xf) * 65536); + et4000->banking = val; return; case 0x3CF: - switch (gdcaddr&15) + switch (svga->gdcaddr & 15) { case 6: - gdcreg[gdcaddr&15]=val; + svga->gdcreg[svga->gdcaddr & 15] = val; //et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4); - et4000w32p_recalcmapping(); + et4000w32p_recalcmapping(et4000); return; } break; case 0x3D4: - crtcreg=val&63; + svga->crtcreg = val & 63; return; case 0x3D5: // pclog("Write CRTC R%02X %02X\n", crtcreg, val); - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; - et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4); -// if (crtcreg!=0xE && crtcreg!=0xF) pclog("CRTC R%02X = %02X\n",crtcreg,val); - if (old!=val) + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(svga); } } - if (crtcreg == 0x30) + if (svga->crtcreg == 0x30) { - et4000w32p_linearbase = val * 0x400000; + et4000->linearbase = val * 0x400000; // pclog("Linear base now at %08X %02X\n", et4000w32p_linearbase, val); - et4000w32p_recalcmapping(); + et4000w32p_recalcmapping(et4000); } - if (crtcreg == 0x36) et4000w32p_recalcmapping(); - break; - case 0x3D8: - if (val==0xA0) svgaon=1; - if (val==0x29) svgaon=0; + if (svga->crtcreg == 0x36) + et4000w32p_recalcmapping(et4000); break; case 0x210A: case 0x211A: case 0x212A: case 0x213A: case 0x214A: case 0x215A: case 0x216A: case 0x217A: - et4000w32p_index=val; + et4000->index=val; return; case 0x210B: case 0x211B: case 0x212B: case 0x213B: case 0x214B: case 0x215B: case 0x216B: case 0x217B: - et4000w32p_regs[et4000w32p_index] = val; - svga_hwcursor.x = et4000w32p_regs[0xE0] | ((et4000w32p_regs[0xE1] & 7) << 8); - svga_hwcursor.y = et4000w32p_regs[0xE4] | ((et4000w32p_regs[0xE5] & 7) << 8); - svga_hwcursor.addr = (et4000w32p_regs[0xE8] | (et4000w32p_regs[0xE9] << 8) | ((et4000w32p_regs[0xEA] & 7) << 16)) << 2; - svga_hwcursor.addr += (et4000w32p_regs[0xE6] & 63) * 16; - svga_hwcursor.ena = et4000w32p_regs[0xF7] & 0x80; - svga_hwcursor.xoff = et4000w32p_regs[0xE2] & 63; - svga_hwcursor.yoff = et4000w32p_regs[0xE6] & 63; -// pclog("HWCURSOR X %i Y %i\n",svga_hwcursor_x,svga_hwcursor_y); + et4000->regs[et4000->index] = val; + svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8); + svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8); + svga->hwcursor.addr = (et4000->regs[0xE8] | (et4000->regs[0xE9] << 8) | ((et4000->regs[0xEA] & 7) << 16)) << 2; + svga->hwcursor.addr += (et4000->regs[0xE6] & 63) * 16; + svga->hwcursor.ena = et4000->regs[0xF7] & 0x80; + svga->hwcursor.xoff = et4000->regs[0xE2] & 63; + svga->hwcursor.yoff = et4000->regs[0xE6] & 63; +// pclog("HWCURSOR X %i Y %i\n",svga->hwcursor_x,svga->hwcursor_y); return; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t et4000w32p_in(uint16_t addr, void *priv) +uint8_t et4000w32p_in(uint16_t addr, void *p) { + et4000w32p_t *et4000 = (et4000w32p_t *)p; + svga_t *svga = &et4000->svga; uint8_t temp; // if (addr==0x3DA) pclog("In 3DA %04X(%06X):%04X\n",CS,cs,pc); // pclog("ET4000W32p in %04X %04X:%04X ",addr,CS,pc); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (addr != 0x3da && addr != 0x3ba) + pclog("et4000w32p_in: addr %04X %04X:%04X %02X %02X\n", addr, CS, pc, ram[0x487], ram[0x488]); + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; // pclog("%04X\n",addr); switch (addr) { - case 0x3C5: - if ((seqaddr&0xF)==7) return seqregs[seqaddr&0xF]|4; + case 0x3c5: + if ((svga->seqaddr & 0xf) == 7) + return svga->seqregs[svga->seqaddr & 0xf] | 4; break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return stg_ramdac_in(addr, NULL); + return stg_ramdac_in(addr, &et4000->ramdac, svga); case 0x3CB: - return svgaseg2; + return et4000->banking2; case 0x3CD: - return svgaseg; + return et4000->banking; case 0x3D4: - return crtcreg; + return svga->crtcreg; case 0x3D5: // pclog("Read CRTC R%02X %02X\n", crtcreg, crtc[crtcreg]); - return crtc[crtcreg]; + return svga->crtc[svga->crtcreg]; case 0x3DA: - attrff=0; - cgastat^=0x30; - temp = cgastat & 0x39; - if (svga_hdisp_on) temp |= 2; - if (!(cgastat & 8)) temp |= 0x80; + svga->attrff = 0; + svga->cgastat ^= 0x30; + temp = svga->cgastat & 0x39; + if (svga->hdisp_on) temp |= 2; + if (!(svga->cgastat & 8)) temp |= 0x80; // pclog("3DA in %02X\n",temp); return temp; case 0x210A: case 0x211A: case 0x212A: case 0x213A: case 0x214A: case 0x215A: case 0x216A: case 0x217A: - return et4000w32p_index; + return et4000->index; case 0x210B: case 0x211B: case 0x212B: case 0x213B: case 0x214B: case 0x215B: case 0x216B: case 0x217B: - if (et4000w32p_index==0xEC) return (et4000w32p_regs[0xEC]&0xF)|0x60; /*ET4000/W32p rev D*/ - if (et4000w32p_index == 0xEF) + if (et4000->index==0xec) + return (et4000->regs[0xec] & 0xf) | 0x60; /*ET4000/W32p rev D*/ + if (et4000->index == 0xef) { - if (PCI) return et4000w32p_regs[0xEF] | 0xe0; /*PCI*/ - else return et4000w32p_regs[0xEF] | 0x60; /*VESA local bus*/ + if (PCI) return et4000->regs[0xef] | 0xe0; /*PCI*/ + else return et4000->regs[0xef] | 0x60; /*VESA local bus*/ } - return et4000w32p_regs[et4000w32p_index]; + return et4000->regs[et4000->index]; } - return svga_in(addr, NULL); + return svga_in(addr, svga); } -void et4000w32p_recalctimings() +void et4000w32p_recalctimings(svga_t *svga) { + et4000w32p_t *et4000 = (et4000w32p_t *)svga->p; // pclog("Recalc %08X ",svga_ma); - svga_ma|=(crtc[0x33]&0x7)<<16; + svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; // pclog("SVGA_MA %08X %i\n", svga_ma, (svga_miscout >> 2) & 3); - if (crtc[0x35]&2) svga_vtotal+=0x400; - if (crtc[0x35]&4) svga_dispend+=0x400; - if (crtc[0x35]&8) svga_vsyncstart+=0x400; - if (crtc[0x35]&0x10) svga_split+=0x400; - if (crtc[0x3F]&0x80) svga_rowoffset+=0x100; - if (crtc[0x3F]&1) svga_htotal+=256; - if (attrregs[0x16]&0x20) svga_hdisp<<=1; + if (svga->crtc[0x35] & 0x02) svga->vtotal += 0x400; + if (svga->crtc[0x35] & 0x04) svga->dispend += 0x400; + if (svga->crtc[0x35] & 0x08) svga->vsyncstart += 0x400; + if (svga->crtc[0x35] & 0x10) svga->split += 0x400; + if (svga->crtc[0x3F] & 0x80) svga->rowoffset += 0x100; + if (svga->crtc[0x3F] & 0x01) svga->htotal += 256; + if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; - switch ((svga_miscout >> 2) & 3) + switch ((svga->miscout >> 2) & 3) { case 0: case 1: break; - case 2: case 3: svga_clock = cpuclock/icd2061_getfreq(2); break; -/* default: - pclog("Unknown clock %i\n", ((svga_miscout >> 2) & 3) | ((crtc[0x34] << 1) & 4) | ((crtc[0x31] & 0xc0) >> 3)); - svga_clock = cpuclock/36000000.0; break;*/ + case 2: case 3: svga->clock = cpuclock / icd2061_getfreq(&et4000->icd2061, 2); break; } -// pclog("Recalctimings - %02X %02X %02X\n", crtc[6], crtc[7], crtc[0x35]); -} - -int et4000w32p_getclock() -{ - return ((svga_miscout >> 2) & 3) | ((crtc[0x34] << 1) & 4) | ((crtc[0x31] & 0xc0) >> 3); -} - - -void et4000w32p_recalcmapping() -{ - int map; - - mem_removehandler(et4000w32p_linearbase_old, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); - mem_removehandler( 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); - mem_removehandler( 0xb0000, 0x10000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL); - if (crtc[0x36] & 0x10) /*Linear frame buffer*/ + switch (svga->bpp) { - mem_sethandler(et4000w32p_linearbase, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); + case 15: case 16: + svga->hdisp >>= 1; + break; + case 24: + svga->hdisp /= 8; + break; + } +} + +void et4000w32p_recalcmapping(et4000w32p_t *et4000) +{ + svga_t *svga = &et4000->svga; + + pclog("recalcmapping %p\n", svga); + mem_removehandler(et4000->linearbase_old, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, svga); + mem_removehandler( 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); + mem_removehandler( 0xb0000, 0x10000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, et4000); + if (svga->crtc[0x36] & 0x10) /*Linear frame buffer*/ + { + mem_sethandler(et4000->linearbase, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, svga); } else { - map = (gdcreg[6] & 0xC) >> 2; - if (crtc[0x36] & 0x20) map |= 4; - if (crtc[0x36] & 0x08) map |= 8; + int map = (svga->gdcreg[6] & 0xc) >> 2; + if (svga->crtc[0x36] & 0x20) map |= 4; + if (svga->crtc[0x36] & 0x08) map |= 8; switch (map) { case 0x0: case 0x4: case 0x8: case 0xC: /*128k at A0000*/ - mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0x1: /*64k at A0000*/ - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0x2: /*32k at B0000*/ - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0x3: /*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; case 0x5: case 0x9: case 0xD: /*64k at A0000, MMU at B8000*/ - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); - mem_sethandler(0xb8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL); + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); + mem_sethandler(0xb8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, et4000); break; case 0x6: case 0xA: case 0xE: /*32k at B0000, MMU at A8000*/ - mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL); - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, et4000); + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0x7: case 0xB: case 0xF: /*32k at B8000, MMU at A8000*/ - mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL); - mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, et4000); + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; } // pclog("ET4K map %02X\n", map); } - et4000w32p_linearbase_old = et4000w32p_linearbase; + et4000->linearbase_old = et4000->linearbase; } -/*Accelerator*/ -struct -{ - struct - { - uint32_t pattern_addr,source_addr,dest_addr,mix_addr; - uint16_t pattern_off,source_off,dest_off,mix_off; - uint8_t pixel_depth,xy_dir; - uint8_t pattern_wrap,source_wrap; - uint16_t count_x,count_y; - uint8_t ctrl_routing,ctrl_reload; - uint8_t rop_fg,rop_bg; - uint16_t pos_x,pos_y; - uint16_t error; - uint16_t dmin,dmaj; - } queued,internal; - uint32_t pattern_addr,source_addr,dest_addr,mix_addr; - uint32_t pattern_back,source_back,dest_back,mix_back; - int pattern_x,source_x; - int pattern_x_back,source_x_back; - int pattern_y,source_y; - uint8_t status; - uint64_t cpu_dat; - int cpu_dat_pos; - int pix_pos; -} acl; - #define ACL_WRST 1 #define ACL_RDST 2 #define ACL_XYST 4 #define ACL_SSO 8 -struct -{ - uint32_t base[3]; - uint8_t ctrl; -} mmu; +void et4000w32_blit_start(et4000w32p_t *et4000); +void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000); -void et4000w32_reset() -{ - acl.status=0; -} - -void et4000w32_blit_start(); -void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input); - -void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv) +void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) { + et4000w32p_t *et4000 = (et4000w32p_t *)p; + svga_t *svga = &et4000->svga; int bank; -// pclog("ET4K write %08X %02X %02X %04X(%08X):%08X\n",addr,val,acl.status,acl.internal.ctrl_routing,CS,cs,pc); - switch (addr&0x6000) +// pclog("ET4K write %08X %02X %02X %04X(%08X):%08X\n",addr,val,et4000->acl.status,et4000->acl.internal.ctrl_routing,CS,cs,pc); + switch (addr & 0x6000) { case 0x0000: /*MMU 0*/ case 0x2000: /*MMU 1*/ case 0x4000: /*MMU 2*/ - bank=(addr>>13)&3; - if (mmu.ctrl&(1<> 13) & 3; + if (et4000->mmu.ctrl & (1 << bank)) { - if (!(acl.status&ACL_XYST)) return; - if (acl.internal.ctrl_routing&3) + if (!(et4000->acl.status & ACL_XYST)) return; + if (et4000->acl.internal.ctrl_routing & 3) { - if ((acl.internal.ctrl_routing&3)==2) + if ((et4000->acl.internal.ctrl_routing & 3) == 2) { - if (acl.mix_addr&7) - et4000w32_blit(8-(acl.mix_addr&7), val>>(acl.mix_addr&7), 0, 1); + if (et4000->acl.mix_addr & 7) + et4000w32_blit(8 - (et4000->acl.mix_addr & 7), val >> (et4000->acl.mix_addr & 7), 0, 1, et4000); else - et4000w32_blit(8, val, 0, 1); + et4000w32_blit(8, val, 0, 1, et4000); } - else if ((acl.internal.ctrl_routing&3)==1) - et4000w32_blit(1, ~0, val, 2); -// else -// pclog("Bad ET4K routing %i\n",acl.internal.ctrl_routing&7); + else if ((et4000->acl.internal.ctrl_routing & 3) == 1) + et4000w32_blit(1, ~0, val, 2, et4000); } } else { - vram[(addr&0x1FFF)+mmu.base[bank]]=val; - changedvram[((addr&0x1FFF)+mmu.base[bank])>>10]=changeframecount; + svga->vram[(addr & 0x1fff) + et4000->mmu.base[bank]] = val; + svga->changedvram[((addr & 0x1fff) + et4000->mmu.base[bank]) >> 10] = changeframecount; } break; case 0x6000: - switch (addr&0x7FFF) + switch (addr & 0x7fff) { - case 0x7F00: mmu.base[0]=(mmu.base[0]&0xFFFFFF00)|val; break; - case 0x7F01: mmu.base[0]=(mmu.base[0]&0xFFFF00FF)|(val<<8); break; - case 0x7F02: mmu.base[0]=(mmu.base[0]&0xFF00FFFF)|(val<<16); break; - case 0x7F03: mmu.base[0]=(mmu.base[0]&0x00FFFFFF)|(val<<24); break; - case 0x7F04: mmu.base[1]=(mmu.base[1]&0xFFFFFF00)|val; break; - case 0x7F05: mmu.base[1]=(mmu.base[1]&0xFFFF00FF)|(val<<8); break; - case 0x7F06: mmu.base[1]=(mmu.base[1]&0xFF00FFFF)|(val<<16); break; - case 0x7F07: mmu.base[1]=(mmu.base[1]&0x00FFFFFF)|(val<<24); break; - case 0x7F08: mmu.base[2]=(mmu.base[2]&0xFFFFFF00)|val; break; - case 0x7F09: mmu.base[2]=(mmu.base[2]&0xFFFF00FF)|(val<<8); break; - case 0x7F0A: mmu.base[2]=(mmu.base[2]&0xFF00FFFF)|(val<<16); break; - case 0x7F0B: mmu.base[2]=(mmu.base[2]&0x00FFFFFF)|(val<<24); break; - case 0x7F13: mmu.ctrl=val; break; + case 0x7f00: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFFFF00) | val; break; + case 0x7f01: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFF00FF) | (val << 8); break; + case 0x7f02: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFF00FFFF) | (val << 16); break; + case 0x7f03: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00FFFFFF) | (val << 24); break; + case 0x7f04: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFFFF00) | val; break; + case 0x7f05: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFF00FF) | (val << 8); break; + case 0x7f06: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFF00FFFF) | (val << 16); break; + case 0x7f07: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00FFFFFF) | (val << 24); break; + case 0x7f08: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFFFF00) | val; break; + case 0x7f09: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFF00FF) | (val << 8); break; + case 0x7f0a: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFF00FFFF) | (val << 16); break; + case 0x7f0d: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00FFFFFF) | (val << 24); break; + case 0x7f13: et4000->mmu.ctrl=val; break; - case 0x7F80: acl.queued.pattern_addr=(acl.queued.pattern_addr&0xFFFFFF00)|val; break; - case 0x7F81: acl.queued.pattern_addr=(acl.queued.pattern_addr&0xFFFF00FF)|(val<<8); break; - case 0x7F82: acl.queued.pattern_addr=(acl.queued.pattern_addr&0xFF00FFFF)|(val<<16); break; - case 0x7F83: acl.queued.pattern_addr=(acl.queued.pattern_addr&0x00FFFFFF)|(val<<24); break; - case 0x7F84: acl.queued.source_addr =(acl.queued.source_addr &0xFFFFFF00)|val; break; - case 0x7F85: acl.queued.source_addr =(acl.queued.source_addr &0xFFFF00FF)|(val<<8); break; - case 0x7F86: acl.queued.source_addr =(acl.queued.source_addr &0xFF00FFFF)|(val<<16); break; - case 0x7F87: acl.queued.source_addr =(acl.queued.source_addr &0x00FFFFFF)|(val<<24); break; - case 0x7F88: acl.queued.pattern_off=(acl.queued.pattern_off&0xFF00)|val; break; - case 0x7F89: acl.queued.pattern_off=(acl.queued.pattern_off&0x00FF)|(val<<8); break; - case 0x7F8A: acl.queued.source_off =(acl.queued.source_off &0xFF00)|val; break; - case 0x7F8B: acl.queued.source_off =(acl.queued.source_off &0x00FF)|(val<<8); break; - case 0x7F8C: acl.queued.dest_off =(acl.queued.dest_off &0xFF00)|val; break; - case 0x7F8D: acl.queued.dest_off =(acl.queued.dest_off &0x00FF)|(val<<8); break; - case 0x7F8E: acl.queued.pixel_depth=val; break; - case 0x7F8F: acl.queued.xy_dir=val; break; - case 0x7F90: acl.queued.pattern_wrap=val; break; - case 0x7F92: acl.queued.source_wrap=val; break; - case 0x7F98: acl.queued.count_x =(acl.queued.count_x &0xFF00)|val; break; - case 0x7F99: acl.queued.count_x =(acl.queued.count_x &0x00FF)|(val<<8); break; - case 0x7F9A: acl.queued.count_y =(acl.queued.count_y &0xFF00)|val; break; - case 0x7F9B: acl.queued.count_y =(acl.queued.count_y &0x00FF)|(val<<8); break; - case 0x7F9C: acl.queued.ctrl_routing=val; break; - case 0x7F9D: acl.queued.ctrl_reload =val; break; - case 0x7F9E: acl.queued.rop_bg =val; break; - case 0x7F9F: acl.queued.rop_fg =val; break; - case 0x7FA0: acl.queued.dest_addr =(acl.queued.dest_addr &0xFFFFFF00)|val; break; - case 0x7FA1: acl.queued.dest_addr =(acl.queued.dest_addr &0xFFFF00FF)|(val<<8); break; - case 0x7FA2: acl.queued.dest_addr =(acl.queued.dest_addr &0xFF00FFFF)|(val<<16); break; - case 0x7FA3: acl.queued.dest_addr =(acl.queued.dest_addr &0x00FFFFFF)|(val<<24); - acl.internal=acl.queued; - et4000w32_blit_start(); - if (!(acl.queued.ctrl_routing&0x43)) + case 0x7f80: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFFFF00) | val; break; + case 0x7f81: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFF00FF) | (val << 8); break; + case 0x7f82: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFF00FFFF) | (val << 16); break; + case 0x7f83: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00FFFFFF) | (val << 24); break; + case 0x7f84: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFFFF00) | val; break; + case 0x7f85: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFF00FF) | (val << 8); break; + case 0x7f86: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFF00FFFF) | (val << 16); break; + case 0x7f87: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00FFFFFF) | (val << 24); break; + case 0x7f88: et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0xFF00) | val; break; + case 0x7f89: et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00FF) | (val << 8); break; + case 0x7f8a: et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0xFF00) | val; break; + case 0x7f8b: et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00FF) | (val << 8); break; + case 0x7f8c: et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0xFF00) | val; break; + case 0x7f8d: et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00FF) | (val << 8); break; + case 0x7f8e: et4000->acl.queued.pixel_depth = val; break; + case 0x7f8f: et4000->acl.queued.xy_dir = val; break; + case 0x7f90: et4000->acl.queued.pattern_wrap = val; break; + case 0x7f92: et4000->acl.queued.source_wrap = val; break; + case 0x7f98: et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0xFF00) | val; break; + case 0x7f99: et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00FF) | (val << 8); break; + case 0x7f9a: et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0xFF00) | val; break; + case 0x7f9b: et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00FF) | (val << 8); break; + case 0x7f9c: et4000->acl.queued.ctrl_routing = val; break; + case 0x7f9d: et4000->acl.queued.ctrl_reload = val; break; + case 0x7f9e: et4000->acl.queued.rop_bg = val; break; + case 0x7f9f: et4000->acl.queued.rop_fg = val; break; + case 0x7fa0: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFFFF00) | val; break; + case 0x7fa1: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFF00FF) | (val << 8); break; + case 0x7fa2: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFF00FFFF) | (val << 16); break; + case 0x7fa3: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00FFFFFF) | (val << 24); + et4000->acl.internal = et4000->acl.queued; + et4000w32_blit_start(et4000); + if (!(et4000->acl.queued.ctrl_routing & 0x43)) { - et4000w32_blit(0xFFFFFF, ~0, 0, 0); + et4000w32_blit(0xFFFFFF, ~0, 0, 0, et4000); } - if ((acl.queued.ctrl_routing&0x40) && !(acl.internal.ctrl_routing&3)) - et4000w32_blit(4, ~0, 0, 0); + if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3)) + et4000w32_blit(4, ~0, 0, 0, et4000); break; - case 0x7FA4: acl.queued.mix_addr=(acl.queued.mix_addr&0xFFFFFF00)|val; break; - case 0x7FA5: acl.queued.mix_addr=(acl.queued.mix_addr&0xFFFF00FF)|(val<<8); break; - case 0x7FA6: acl.queued.mix_addr=(acl.queued.mix_addr&0xFF00FFFF)|(val<<16); break; - case 0x7FA7: acl.queued.mix_addr=(acl.queued.mix_addr&0x00FFFFFF)|(val<<24); break; - case 0x7FA8: acl.queued.mix_off =(acl.queued.mix_off &0xFF00)|val; break; - case 0x7FA9: acl.queued.mix_off =(acl.queued.mix_off &0x00FF)|(val<<8); break; - case 0x7FAA: acl.queued.error =(acl.queued.error &0xFF00)|val; break; - case 0x7FAB: acl.queued.error =(acl.queued.error &0x00FF)|(val<<8); break; - case 0x7FAC: acl.queued.dmin =(acl.queued.dmin &0xFF00)|val; break; - case 0x7FAD: acl.queued.dmin =(acl.queued.dmin &0x00FF)|(val<<8); break; - case 0x7FAE: acl.queued.dmaj =(acl.queued.dmaj &0xFF00)|val; break; - case 0x7FAF: acl.queued.dmaj =(acl.queued.dmaj &0x00FF)|(val<<8); break; + case 0x7fa4: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFFFF00) | val; break; + case 0x7fa5: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFF00FF) | (val << 8); break; + case 0x7fa6: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFF00FFFF) | (val << 16); break; + case 0x7fa7: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); break; + case 0x7fa8: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0xFF00) | val; break; + case 0x7fa9: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); break; + case 0x7faa: et4000->acl.queued.error = (et4000->acl.queued.error & 0xFF00) | val; break; + case 0x7fab: et4000->acl.queued.error = (et4000->acl.queued.error & 0x00FF) | (val << 8); break; + case 0x7fac: et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0xFF00) | val; break; + case 0x7fad: et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0x00FF) | (val << 8); break; + case 0x7fae: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0xFF00) | val; break; + case 0x7faf: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); break; } break; } } -uint8_t et4000w32p_mmu_read(uint32_t addr, void *priv) +uint8_t et4000w32p_mmu_read(uint32_t addr, void *p) { + et4000w32p_t *et4000 = (et4000w32p_t *)p; + svga_t *svga = &et4000->svga; int bank; uint8_t temp; // pclog("ET4K read %08X %04X(%08X):%08X\n",addr,CS,cs,pc); - switch (addr&0x6000) + switch (addr & 0x6000) { case 0x0000: /*MMU 0*/ case 0x2000: /*MMU 1*/ case 0x4000: /*MMU 2*/ - bank=(addr>>13)&3; - if (mmu.ctrl&(1<> 13) & 3; + if (et4000->mmu.ctrl & (1 << bank)) { - temp=0xFF; - if (acl.cpu_dat_pos) + temp = 0xff; + if (et4000->acl.cpu_dat_pos) { - acl.cpu_dat_pos--; - temp=acl.cpu_dat&0xFF; - acl.cpu_dat>>=8; + et4000->acl.cpu_dat_pos--; + temp = et4000->acl.cpu_dat & 0xff; + et4000->acl.cpu_dat >>= 8; } - if ((acl.queued.ctrl_routing&0x40) && !acl.cpu_dat_pos && !(acl.internal.ctrl_routing&3)) - et4000w32_blit(4, ~0, 0, 0); + if ((et4000->acl.queued.ctrl_routing & 0x40) && !et4000->acl.cpu_dat_pos && !(et4000->acl.internal.ctrl_routing & 3)) + et4000w32_blit(4, ~0, 0, 0, et4000); /*???*/ return temp; } - return vram[(addr&0x1FFF)+mmu.base[bank]]; + return svga->vram[(addr&0x1fff) + et4000->mmu.base[bank]]; + case 0x6000: - switch (addr&0x7FFF) + switch (addr&0x7fff) { - case 0x7F00: return mmu.base[0]; - case 0x7F01: return mmu.base[0]>>8; - case 0x7F02: return mmu.base[0]>>16; - case 0x7F03: return mmu.base[0]>>24; - case 0x7F04: return mmu.base[1]; - case 0x7F05: return mmu.base[1]>>8; - case 0x7F06: return mmu.base[1]>>16; - case 0x7F07: return mmu.base[1]>>24; - case 0x7F08: return mmu.base[2]; - case 0x7F09: return mmu.base[2]>>8; - case 0x7F0A: return mmu.base[2]>>16; - case 0x7F0B: return mmu.base[2]>>24; - case 0x7F13: return mmu.ctrl; + case 0x7f00: return et4000->mmu.base[0]; + case 0x7f01: return et4000->mmu.base[0] >> 8; + case 0x7f02: return et4000->mmu.base[0] >> 16; + case 0x7f03: return et4000->mmu.base[0] >> 24; + case 0x7f04: return et4000->mmu.base[1]; + case 0x7f05: return et4000->mmu.base[1] >> 8; + case 0x7f06: return et4000->mmu.base[1] >> 16; + case 0x7f07: return et4000->mmu.base[1] >> 24; + case 0x7f08: return et4000->mmu.base[2]; + case 0x7f09: return et4000->mmu.base[2] >> 8; + case 0x7f0a: return et4000->mmu.base[2] >> 16; + case 0x7f0b: return et4000->mmu.base[2] >> 24; + case 0x7f13: return et4000->mmu.ctrl; - case 0x7F36: -// pclog("Read ACL status %02X\n",acl.status); -// if (acl.internal.pos_x!=acl.internal.count_x || acl.internal.pos_y!=acl.internal.count_y) return acl.status | ACL_XYST; - return acl.status; - case 0x7F80: return acl.internal.pattern_addr; - case 0x7F81: return acl.internal.pattern_addr>>8; - case 0x7F82: return acl.internal.pattern_addr>>16; - case 0x7F83: return acl.internal.pattern_addr>>24; - case 0x7F84: return acl.internal.source_addr; - case 0x7F85: return acl.internal.source_addr>>8; - case 0x7F86: return acl.internal.source_addr>>16; - case 0x7F87: return acl.internal.source_addr>>24; - case 0x7F88: return acl.internal.pattern_off; - case 0x7F89: return acl.internal.pattern_off>>8; - case 0x7F8A: return acl.internal.source_off; - case 0x7F8B: return acl.internal.source_off>>8; - case 0x7F8C: return acl.internal.dest_off; - case 0x7F8D: return acl.internal.dest_off>>8; - case 0x7F8E: return acl.internal.pixel_depth; - case 0x7F8F: return acl.internal.xy_dir; - case 0x7F90: return acl.internal.pattern_wrap; - case 0x7F92: return acl.internal.source_wrap; - case 0x7F98: return acl.internal.count_x; - case 0x7F99: return acl.internal.count_x>>8; - case 0x7F9A: return acl.internal.count_y; - case 0x7F9B: return acl.internal.count_y>>8; - case 0x7F9C: return acl.internal.ctrl_routing; - case 0x7F9D: return acl.internal.ctrl_reload; - case 0x7F9E: return acl.internal.rop_bg; - case 0x7F9F: return acl.internal.rop_fg; - case 0x7FA0: return acl.internal.dest_addr; - case 0x7FA1: return acl.internal.dest_addr>>8; - case 0x7FA2: return acl.internal.dest_addr>>16; - case 0x7FA3: return acl.internal.dest_addr>>24; + case 0x7f36: +// pclog("Read ACL status %02X\n",et4000->acl.status); +// if (et4000->acl.internal.pos_x!=et4000->acl.internal.count_x || et4000->acl.internal.pos_y!=et4000->acl.internal.count_y) return et4000->acl.status | ACL_XYST; + return et4000->acl.status; + case 0x7f80: return et4000->acl.internal.pattern_addr; + case 0x7f81: return et4000->acl.internal.pattern_addr >> 8; + case 0x7f82: return et4000->acl.internal.pattern_addr >> 16; + case 0x7f83: return et4000->acl.internal.pattern_addr >> 24; + case 0x7f84: return et4000->acl.internal.source_addr; + case 0x7f85: return et4000->acl.internal.source_addr >> 8; + case 0x7f86: return et4000->acl.internal.source_addr >> 16; + case 0x7f87: return et4000->acl.internal.source_addr >> 24; + case 0x7f88: return et4000->acl.internal.pattern_off; + case 0x7f89: return et4000->acl.internal.pattern_off >> 8; + case 0x7f8a: return et4000->acl.internal.source_off; + case 0x7f8b: return et4000->acl.internal.source_off >> 8; + case 0x7f8c: return et4000->acl.internal.dest_off; + case 0x7f8d: return et4000->acl.internal.dest_off >> 8; + case 0x7f8e: return et4000->acl.internal.pixel_depth; + case 0x7f8f: return et4000->acl.internal.xy_dir; + case 0x7f90: return et4000->acl.internal.pattern_wrap; + case 0x7f92: return et4000->acl.internal.source_wrap; + case 0x7f98: return et4000->acl.internal.count_x; + case 0x7f99: return et4000->acl.internal.count_x >> 8; + case 0x7f9a: return et4000->acl.internal.count_y; + case 0x7f9b: return et4000->acl.internal.count_y >> 8; + case 0x7f9c: return et4000->acl.internal.ctrl_routing; + case 0x7f9d: return et4000->acl.internal.ctrl_reload; + case 0x7f9e: return et4000->acl.internal.rop_bg; + case 0x7f9f: return et4000->acl.internal.rop_fg; + case 0x7fa0: return et4000->acl.internal.dest_addr; + case 0x7fa1: return et4000->acl.internal.dest_addr >> 8; + case 0x7fa2: return et4000->acl.internal.dest_addr >> 16; + case 0x7fa3: return et4000->acl.internal.dest_addr >> 24; } - return 0xFF; + return 0xff; } return 0xff; } -int et4000w32_max_x[8]={0,0,4,8,16,32,64,0x70000000}; -int et4000w32_wrap_x[8]={0,0,3,7,15,31,63,0xFFFFFFFF}; -int et4000w32_wrap_y[8]={1,2,4,8,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; +static int et4000w32_max_x[8]={0,0,4,8,16,32,64,0x70000000}; +static int et4000w32_wrap_x[8]={0,0,3,7,15,31,63,0xFFFFFFFF}; +static int et4000w32_wrap_y[8]={1,2,4,8,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; int bltout=0; -void et4000w32_blit_start() +void et4000w32_blit_start(et4000w32p_t *et4000) { -// if (acl.queued.xy_dir&0x80) -// pclog("Blit - %02X %08X (%i,%i) %08X (%i,%i) %08X (%i,%i) %i %i %i %02X %02X %02X\n",acl.queued.xy_dir,acl.internal.pattern_addr,(acl.internal.pattern_addr/3)%640,(acl.internal.pattern_addr/3)/640,acl.internal.source_addr,(acl.internal.source_addr/3)%640,(acl.internal.source_addr/3)/640,acl.internal.dest_addr,(acl.internal.dest_addr/3)%640,(acl.internal.dest_addr/3)/640,acl.internal.xy_dir,acl.internal.count_x,acl.internal.count_y,acl.internal.rop_fg,acl.internal.rop_bg, acl.internal.ctrl_routing); +// if (et4000->acl.queued.xy_dir&0x80) +// pclog("Blit - %02X %08X (%i,%i) %08X (%i,%i) %08X (%i,%i) %i %i %i %02X %02X %02X\n",et4000->acl.queued.xy_dir,et4000->acl.internal.pattern_addr,(et4000->acl.internal.pattern_addr/3)%640,(et4000->acl.internal.pattern_addr/3)/640,et4000->acl.internal.source_addr,(et4000->acl.internal.source_addr/3)%640,(et4000->acl.internal.source_addr/3)/640,et4000->acl.internal.dest_addr,(et4000->acl.internal.dest_addr/3)%640,(et4000->acl.internal.dest_addr/3)/640,et4000->acl.internal.xy_dir,et4000->acl.internal.count_x,et4000->acl.internal.count_y,et4000->acl.internal.rop_fg,et4000->acl.internal.rop_bg, et4000->acl.internal.ctrl_routing); // bltout=1; -// bltout=(acl.internal.count_x==1541); - if (!(acl.queued.xy_dir&0x20)) - acl.internal.error = acl.internal.dmaj/2; - acl.pattern_addr=acl.internal.pattern_addr; - acl.source_addr =acl.internal.source_addr; - acl.mix_addr =acl.internal.mix_addr; - acl.mix_back =acl.mix_addr; - acl.dest_addr =acl.internal.dest_addr; - acl.dest_back =acl.dest_addr; - acl.internal.pos_x=acl.internal.pos_y=0; - acl.pattern_x=acl.source_x=acl.pattern_y=acl.source_y=0; - acl.status = ACL_XYST; - if ((!(acl.internal.ctrl_routing&7) || (acl.internal.ctrl_routing&4)) && !(acl.internal.ctrl_routing&0x40)) acl.status |= ACL_SSO; +// bltout=(et4000->acl.internal.count_x==1541); + if (!(et4000->acl.queued.xy_dir & 0x20)) + et4000->acl.internal.error = et4000->acl.internal.dmaj / 2; + et4000->acl.pattern_addr= et4000->acl.internal.pattern_addr; + et4000->acl.source_addr = et4000->acl.internal.source_addr; + et4000->acl.mix_addr = et4000->acl.internal.mix_addr; + et4000->acl.mix_back = et4000->acl.mix_addr; + et4000->acl.dest_addr = et4000->acl.internal.dest_addr; + et4000->acl.dest_back = et4000->acl.dest_addr; + et4000->acl.internal.pos_x = et4000->acl.internal.pos_y = 0; + et4000->acl.pattern_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0; + et4000->acl.status = ACL_XYST; + if ((!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) && !(et4000->acl.internal.ctrl_routing & 0x40)) + et4000->acl.status |= ACL_SSO; - if (et4000w32_wrap_x[acl.internal.pattern_wrap&7]) + if (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]) { - acl.pattern_x=acl.pattern_addr&et4000w32_wrap_x[acl.internal.pattern_wrap&7]; - acl.pattern_addr&=~et4000w32_wrap_x[acl.internal.pattern_wrap&7]; + et4000->acl.pattern_x = et4000->acl.pattern_addr & et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; + et4000->acl.pattern_addr &= ~et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; } - acl.pattern_back=acl.pattern_addr; - if (!(acl.internal.pattern_wrap&0x40)) + et4000->acl.pattern_back = et4000->acl.pattern_addr; + if (!(et4000->acl.internal.pattern_wrap & 0x40)) { - acl.pattern_y=(acl.pattern_addr/(et4000w32_wrap_x[acl.internal.pattern_wrap&7]+1))&(et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7]-1); - acl.pattern_back&=~(((et4000w32_wrap_x[acl.internal.pattern_wrap&7]+1)*et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7])-1); + et4000->acl.pattern_y = (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); + et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - 1); } - acl.pattern_x_back=acl.pattern_x; + et4000->acl.pattern_x_back = et4000->acl.pattern_x; - if (et4000w32_wrap_x[acl.internal.source_wrap&7]) + if (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]) { - acl.source_x=acl.source_addr&et4000w32_wrap_x[acl.internal.source_wrap&7]; - acl.source_addr&=~et4000w32_wrap_x[acl.internal.source_wrap&7]; + et4000->acl.source_x = et4000->acl.source_addr & et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; + et4000->acl.source_addr &= ~et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; } - acl.source_back=acl.source_addr; - if (!(acl.internal.source_wrap&0x40)) + et4000->acl.source_back = et4000->acl.source_addr; + if (!(et4000->acl.internal.source_wrap & 0x40)) { - acl.source_y=(acl.source_addr/(et4000w32_wrap_x[acl.internal.source_wrap&7]+1))&(et4000w32_wrap_y[(acl.internal.source_wrap>>4)&7]-1); - acl.source_back&=~(((et4000w32_wrap_x[acl.internal.source_wrap&7]+1)*et4000w32_wrap_y[(acl.internal.source_wrap>>4)&7])-1); + et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); + et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); } - acl.source_x_back=acl.source_x; + et4000->acl.source_x_back = et4000->acl.source_x; - et4000w32_max_x[2]=((acl.internal.pixel_depth&0x30)==0x20)?3:4; + et4000w32_max_x[2] = ((et4000->acl.internal.pixel_depth & 0x30) == 0x20) ? 3 : 4; - acl.internal.count_x += (acl.internal.pixel_depth>>4)&3; - acl.cpu_dat_pos=0; - acl.cpu_dat=0; + et4000->acl.internal.count_x += (et4000->acl.internal.pixel_depth >> 4) & 3; + et4000->acl.cpu_dat_pos = 0; + et4000->acl.cpu_dat = 0; - acl.pix_pos=0; + et4000->acl.pix_pos = 0; } -void et4000w32_incx(int c) +void et4000w32_incx(int c, et4000w32p_t *et4000) { - acl.dest_addr+=c; - acl.pattern_x+=c; - acl.source_x +=c; - acl.mix_addr +=c; - if (acl.pattern_x>=et4000w32_max_x[acl.internal.pattern_wrap&7]) - acl.pattern_x -=et4000w32_max_x[acl.internal.pattern_wrap&7]; - if (acl.source_x >=et4000w32_max_x[acl.internal.source_wrap &7]) - acl.source_x -=et4000w32_max_x[acl.internal.source_wrap &7]; + et4000->acl.dest_addr += c; + et4000->acl.pattern_x += c; + et4000->acl.source_x += c; + et4000->acl.mix_addr += c; + if (et4000->acl.pattern_x >= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]) + et4000->acl.pattern_x -= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; + if (et4000->acl.source_x >= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]) + et4000->acl.source_x -= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; } -void et4000w32_decx(int c) +void et4000w32_decx(int c, et4000w32p_t *et4000) { - acl.dest_addr-=c; - acl.pattern_x-=c; - acl.source_x -=c; - acl.mix_addr -=c; - if (acl.pattern_x<0) - acl.pattern_x +=et4000w32_max_x[acl.internal.pattern_wrap&7]; - if (acl.source_x <0) - acl.source_x +=et4000w32_max_x[acl.internal.source_wrap &7]; + et4000->acl.dest_addr -= c; + et4000->acl.pattern_x -= c; + et4000->acl.source_x -= c; + et4000->acl.mix_addr -= c; + if (et4000->acl.pattern_x < 0) + et4000->acl.pattern_x += et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; + if (et4000->acl.source_x < 0) + et4000->acl.source_x += et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; } -void et4000w32_incy() +void et4000w32_incy(et4000w32p_t *et4000) { - acl.pattern_addr+=acl.internal.pattern_off+1; - acl.source_addr +=acl.internal.source_off +1; - acl.mix_addr +=acl.internal.mix_off +1; - acl.dest_addr +=acl.internal.dest_off +1; - acl.pattern_y++; - if (acl.pattern_y == et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7]) + et4000->acl.pattern_addr += et4000->acl.internal.pattern_off + 1; + et4000->acl.source_addr += et4000->acl.internal.source_off + 1; + et4000->acl.mix_addr += et4000->acl.internal.mix_off + 1; + et4000->acl.dest_addr += et4000->acl.internal.dest_off + 1; + et4000->acl.pattern_y++; + if (et4000->acl.pattern_y == et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) { - acl.pattern_y = 0; - acl.pattern_addr = acl.pattern_back; + et4000->acl.pattern_y = 0; + et4000->acl.pattern_addr = et4000->acl.pattern_back; } - acl.source_y++; - if (acl.source_y == et4000w32_wrap_y[(acl.internal.source_wrap >>4)&7]) + et4000->acl.source_y++; + if (et4000->acl.source_y == et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) { - acl.source_y = 0; - acl.source_addr = acl.source_back; + et4000->acl.source_y = 0; + et4000->acl.source_addr = et4000->acl.source_back; } } -void et4000w32_decy() +void et4000w32_decy(et4000w32p_t *et4000) { - acl.pattern_addr-=acl.internal.pattern_off+1; - acl.source_addr -=acl.internal.source_off +1; - acl.mix_addr -=acl.internal.mix_off +1; - acl.dest_addr -=acl.internal.dest_off +1; - acl.pattern_y--; - if (acl.pattern_y<0 && !(acl.internal.pattern_wrap&0x40)) + et4000->acl.pattern_addr -= et4000->acl.internal.pattern_off + 1; + et4000->acl.source_addr -= et4000->acl.internal.source_off + 1; + et4000->acl.mix_addr -= et4000->acl.internal.mix_off + 1; + et4000->acl.dest_addr -= et4000->acl.internal.dest_off + 1; + et4000->acl.pattern_y--; + if (et4000->acl.pattern_y < 0 && !(et4000->acl.internal.pattern_wrap & 0x40)) { - acl.pattern_y=et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7]-1; - acl.pattern_addr=acl.pattern_back+(et4000w32_wrap_x[acl.internal.pattern_wrap&7]*(et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7]-1)); + et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; + et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); } - acl.source_y--; - if (acl.source_y<0 && !(acl.internal.source_wrap&0x40)) + et4000->acl.source_y--; + if (et4000->acl.source_y < 0 && !(et4000->acl.internal.source_wrap & 0x40)) { - acl.source_y =et4000w32_wrap_y[(acl.internal.source_wrap >>4)&7]-1; - acl.source_addr =acl.source_back +(et4000w32_wrap_x[acl.internal.source_wrap&7] *(et4000w32_wrap_y[(acl.internal.source_wrap>>4)&7]-1));; + et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; + et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] *(et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1));; } } -void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input) +void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000) { + svga_t *svga = &et4000->svga; int c,d; - uint8_t pattern,source,dest,out; + uint8_t pattern, source, dest, out; uint8_t rop; int mixdat; - if (!(acl.status & ACL_XYST)) return; -// if (count>400) pclog("New blit - %i,%i %06X (%i,%i) %06X %06X\n",acl.internal.count_x,acl.internal.count_y,acl.dest_addr,acl.dest_addr%640,acl.dest_addr/640,acl.source_addr,acl.pattern_addr); - //pclog("Blit exec - %i %i %i\n",count,acl.internal.pos_x,acl.internal.pos_y); - if (acl.internal.xy_dir&0x80) /*Line draw*/ + if (!(et4000->acl.status & ACL_XYST)) return; +// if (count>400) pclog("New blit - %i,%i %06X (%i,%i) %06X %06X\n",et4000->acl.internal.count_x,et4000->acl.internal.count_y,et4000->acl.dest_addr,et4000->acl.dest_addr%640,et4000->acl.dest_addr/640,et4000->acl.source_addr,et4000->acl.pattern_addr); + //pclog("Blit exec - %i %i %i\n",count,et4000->acl.internal.pos_x,et4000->acl.internal.pos_y); + if (et4000->acl.internal.xy_dir & 0x80) /*Line draw*/ { while (count--) { - if (bltout) pclog("%i,%i : ",acl.internal.pos_x,acl.internal.pos_y); - pattern=vram[(acl.pattern_addr+acl.pattern_x)&0x1FFFFF]; - source =vram[(acl.source_addr +acl.source_x) &0x1FFFFF]; - if (bltout) pclog("%06X %06X ",(acl.pattern_addr+acl.pattern_x)&0x1FFFFF,(acl.source_addr +acl.source_x) &0x1FFFFF); - if (cpu_input==2) + if (bltout) pclog("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff]; + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff]; + if (bltout) pclog("%06X %06X ", (et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff, (et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff); + if (cpu_input == 2) { - source=sdat&0xFF; - sdat>>=8; + source = sdat & 0xff; + sdat >>= 8; } - dest=vram[acl.dest_addr &0x1FFFFF]; - out=0; - if (bltout) pclog("%06X ",acl.dest_addr); - if ((acl.internal.ctrl_routing&0xA)==8) + dest = svga->vram[et4000->acl.dest_addr & 0x1fffff]; + out = 0; + if (bltout) pclog("%06X ", et4000->acl.dest_addr); + if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { - mixdat = vram[(acl.mix_addr>>3)&0x1FFFFF] & (1<<(acl.mix_addr&7)); - if (bltout) pclog("%06X %02X ",acl.mix_addr,vram[(acl.mix_addr>>3)&0x1FFFFF]); + mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff] & (1 << (et4000->acl.mix_addr & 7)); + if (bltout) pclog("%06X %02X ", et4000->acl.mix_addr, svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff]); } else { mixdat = mix & 1; - mix>>=1; mix|=0x80000000; + mix >>= 1; + mix |= 0x80000000; } - acl.mix_addr++; - rop = (mixdat) ? acl.internal.rop_fg:acl.internal.rop_bg; - for (c=0;c<8;c++) + et4000->acl.mix_addr++; + rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; + for (c = 0; c < 8; c++) { - d=(dest & (1<acl.dest_addr & 0x1fffff, out); + if (!(et4000->acl.internal.ctrl_routing & 0x40)) { - vram[acl.dest_addr&0x1FFFFF]=out; - changedvram[(acl.dest_addr&0x1FFFFF)>>10]=changeframecount; + svga->vram[et4000->acl.dest_addr & 0x1fffff] = out; + svga->changedvram[(et4000->acl.dest_addr & 0x1fffff) >> 10] = changeframecount; } else { - acl.cpu_dat|=((uint64_t)out<<(acl.cpu_dat_pos*8)); - acl.cpu_dat_pos++; + et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); + et4000->acl.cpu_dat_pos++; } -// pclog("%i %i\n",acl.pix_pos,(acl.internal.pixel_depth>>4)&3); - acl.pix_pos++; - acl.internal.pos_x++; - if (acl.pix_pos<=((acl.internal.pixel_depth>>4)&3)) +// pclog("%i %i\n",et4000->acl.pix_pos,(et4000->acl.internal.pixel_depth>>4)&3); + et4000->acl.pix_pos++; + et4000->acl.internal.pos_x++; + if (et4000->acl.pix_pos <= ((et4000->acl.internal.pixel_depth >> 4) & 3)) { - if (acl.internal.xy_dir&1) et4000w32_decx(1); - else et4000w32_incx(1); + if (et4000->acl.internal.xy_dir & 1) et4000w32_decx(1, et4000); + else et4000w32_incx(1, et4000); } else { - if (acl.internal.xy_dir&1) et4000w32_incx((acl.internal.pixel_depth>>4)&3); - else et4000w32_decx((acl.internal.pixel_depth>>4)&3); - acl.pix_pos=0; + if (et4000->acl.internal.xy_dir & 1) + et4000w32_incx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); + else + et4000w32_decx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); + et4000->acl.pix_pos = 0; /*Next pixel*/ - switch (acl.internal.xy_dir&7) + switch (et4000->acl.internal.xy_dir & 7) { case 0: case 1: /*Y+*/ - et4000w32_incy(); - acl.internal.pos_y++; - acl.internal.pos_x-=((acl.internal.pixel_depth>>4)&3)+1; + et4000w32_incy(et4000); + et4000->acl.internal.pos_y++; + et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; break; case 2: case 3: /*Y-*/ - et4000w32_decy(); - acl.internal.pos_y++; - acl.internal.pos_x-=((acl.internal.pixel_depth>>4)&3)+1; + et4000w32_decy(et4000); + et4000->acl.internal.pos_y++; + et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; break; case 4: case 6: /*X+*/ - et4000w32_incx(((acl.internal.pixel_depth>>4)&3)+1); - //acl.internal.pos_x++; + et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + //et4000->acl.internal.pos_x++; break; case 5: case 7: /*X-*/ - et4000w32_decx(((acl.internal.pixel_depth>>4)&3)+1); - //acl.internal.pos_x++; + et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + //et4000->acl.internal.pos_x++; break; } - acl.internal.error+=acl.internal.dmin; - if (acl.internal.error > acl.internal.dmaj) + et4000->acl.internal.error += et4000->acl.internal.dmin; + if (et4000->acl.internal.error > et4000->acl.internal.dmaj) { - acl.internal.error-=acl.internal.dmaj; - switch (acl.internal.xy_dir&7) + et4000->acl.internal.error -= et4000->acl.internal.dmaj; + switch (et4000->acl.internal.xy_dir & 7) { case 0: case 2: /*X+*/ - et4000w32_incx(((acl.internal.pixel_depth>>4)&3)+1); - acl.internal.pos_x++; + et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + et4000->acl.internal.pos_x++; break; case 1: case 3: /*X-*/ - et4000w32_decx(((acl.internal.pixel_depth>>4)&3)+1); - acl.internal.pos_x++; + et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + et4000->acl.internal.pos_x++; break; case 4: case 5: /*Y+*/ - et4000w32_incy(); - acl.internal.pos_y++; + et4000w32_incy(et4000); + et4000->acl.internal.pos_y++; break; case 6: case 7: /*Y-*/ - et4000w32_decy(); - acl.internal.pos_y++; + et4000w32_decy(et4000); + et4000->acl.internal.pos_y++; break; } } - if (acl.internal.pos_x > acl.internal.count_x || - acl.internal.pos_y > acl.internal.count_y) + if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x || + et4000->acl.internal.pos_y > et4000->acl.internal.count_y) { - acl.status = 0; + et4000->acl.status = 0; // pclog("Blit line over\n"); return; } @@ -736,85 +758,87 @@ void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input) { while (count--) { - if (bltout) pclog("%i,%i : ",acl.internal.pos_x,acl.internal.pos_y); + if (bltout) pclog("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); - pattern=vram[(acl.pattern_addr+acl.pattern_x)&0x1FFFFF]; - source =vram[(acl.source_addr +acl.source_x) &0x1FFFFF]; - if (bltout) pclog("%i %06X %06X %02X %02X ",acl.pattern_y,(acl.pattern_addr+acl.pattern_x)&0x1FFFFF,(acl.source_addr +acl.source_x) &0x1FFFFF,pattern,source); + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff]; + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff]; + if (bltout) pclog("%i %06X %06X %02X %02X ", et4000->acl.pattern_y, (et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff, (et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff, pattern, source); - if (cpu_input==2) + if (cpu_input == 2) { - source=sdat&0xFF; - sdat>>=8; + source = sdat & 0xff; + sdat >>= 8; } - dest=vram[acl.dest_addr &0x1FFFFF]; - out=0; - if (bltout) pclog("%06X %02X %i %08X %08X ",dest,acl.dest_addr,mix&1,mix,acl.mix_addr); - if ((acl.internal.ctrl_routing&0xA)==8) + dest = svga->vram[et4000->acl.dest_addr & 0x1fffff]; + out = 0; + if (bltout) pclog("%06X %02X %i %08X %08X ", dest, et4000->acl.dest_addr, mix & 1, mix, et4000->acl.mix_addr); + if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { - mixdat = vram[(acl.mix_addr>>3)&0x1FFFFF] & (1<<(acl.mix_addr&7)); - if (bltout) pclog("%06X %02X ",acl.mix_addr,vram[(acl.mix_addr>>3)&0x1FFFFF]); + mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff] & (1 << (et4000->acl.mix_addr & 7)); + if (bltout) pclog("%06X %02X ", et4000->acl.mix_addr, svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff]); } else { mixdat = mix & 1; - mix>>=1; mix|=0x80000000; + mix >>= 1; + mix |= 0x80000000; } - rop = (mixdat) ? acl.internal.rop_fg:acl.internal.rop_bg; - for (c=0;c<8;c++) + rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; + for (c = 0; c < 8; c++) { - d=(dest & (1<acl.dest_addr & 0x1fffff, out); + if (!(et4000->acl.internal.ctrl_routing & 0x40)) { - vram[acl.dest_addr&0x1FFFFF]=out; - changedvram[(acl.dest_addr&0x1FFFFF)>>10]=changeframecount; + svga->vram[et4000->acl.dest_addr & 0x1fffff] = out; + svga->changedvram[(et4000->acl.dest_addr & 0x1fffff) >> 10] = changeframecount; } else { - acl.cpu_dat|=((uint64_t)out<<(acl.cpu_dat_pos*8)); - acl.cpu_dat_pos++; + et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); + et4000->acl.cpu_dat_pos++; } - if (acl.internal.xy_dir&1) et4000w32_decx(1); - else et4000w32_incx(1); + if (et4000->acl.internal.xy_dir & 1) et4000w32_decx(1, et4000); + else et4000w32_incx(1, et4000); - acl.internal.pos_x++; - if (acl.internal.pos_x>acl.internal.count_x) + et4000->acl.internal.pos_x++; + if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x) { - if (acl.internal.xy_dir&2) + if (et4000->acl.internal.xy_dir & 2) { - et4000w32_decy(); - acl.mix_back =acl.mix_addr =acl.mix_back -(acl.internal.mix_off +1); - acl.dest_back=acl.dest_addr=acl.dest_back-(acl.internal.dest_off+1); + et4000w32_decy(et4000); + et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back - (et4000->acl.internal.mix_off + 1); + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); } else { - et4000w32_incy(); - acl.mix_back =acl.mix_addr =acl.mix_back +acl.internal.mix_off +1; - acl.dest_back=acl.dest_addr=acl.dest_back+acl.internal.dest_off+1; + et4000w32_incy(et4000); + et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back + et4000->acl.internal.mix_off + 1; + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1; } - acl.pattern_x = acl.pattern_x_back; - acl.source_x = acl.source_x_back; + et4000->acl.pattern_x = et4000->acl.pattern_x_back; + et4000->acl.source_x = et4000->acl.source_x_back; - acl.internal.pos_y++; - acl.internal.pos_x=0; - if (acl.internal.pos_y>acl.internal.count_y) + et4000->acl.internal.pos_y++; + et4000->acl.internal.pos_x = 0; + if (et4000->acl.internal.pos_y > et4000->acl.internal.count_y) { - acl.status = 0; + et4000->acl.status = 0; // pclog("Blit over\n"); return; } if (cpu_input) return; - if (acl.internal.ctrl_routing&0x40) + if (et4000->acl.internal.ctrl_routing & 0x40) { - if (acl.cpu_dat_pos&3) acl.cpu_dat_pos+=4-(acl.cpu_dat_pos&3); + if (et4000->acl.cpu_dat_pos & 3) + et4000->acl.cpu_dat_pos += 4 - (et4000->acl.cpu_dat_pos & 3); return; } } @@ -823,34 +847,38 @@ void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input) } -void et4000w32p_cursor_draw(int displine) +void et4000w32p_hwcursor_draw(svga_t *svga, int displine) { int x, offset; uint8_t dat; - offset = svga_hwcursor_latch.xoff; - for (x = 0; x < 64 - svga_hwcursor_latch.xoff; x += 4) + offset = svga->hwcursor_latch.xoff; + for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { - dat = vram[svga_hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32] ^= 0xFFFFFF; + dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF; dat >>= 2; offset += 4; } - svga_hwcursor_latch.addr += 16; + svga->hwcursor_latch.addr += 16; } -uint8_t et4000w32p_pci_read(int func, int addr, void *priv) +uint8_t et4000w32p_pci_read(int func, int addr, void *p) { + et4000w32p_t *et4000 = (et4000w32p_t *)p; + svga_t *svga = &et4000->svga; + pclog("ET4000 PCI read %08X\n", addr); + switch (addr) { case 0x00: return 0x0c; /*Tseng Labs*/ @@ -871,8 +899,8 @@ uint8_t et4000w32p_pci_read(int func, int addr, void *priv) case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x11: return 0x00; - case 0x12: return crtc[0x5a] & 0x80; - case 0x13: return crtc[0x59]; + case 0x12: return svga->crtc[0x5a] & 0x80; + case 0x13: return svga->crtc[0x59]; case 0x30: return 0x01; /*BIOS ROM address*/ case 0x31: return 0x00; @@ -882,57 +910,66 @@ uint8_t et4000w32p_pci_read(int func, int addr, void *priv) return 0; } -void et4000w32p_pci_write(int func, int addr, uint8_t val, void *priv) +void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p) { + et4000w32p_t *et4000 = (et4000w32p_t *)p; + switch (addr) { - case 0x13: et4000w32p_linearbase = val << 24; et4000w32p_recalcmapping(); break; + case 0x13: + et4000->linearbase = val << 24; + et4000w32p_recalcmapping(et4000); + break; } } -int et4000w32p_init() +void *et4000w32p_init() { - svga_recalctimings_ex = et4000w32p_recalctimings; - svga_hwcursor_draw = et4000w32p_cursor_draw; - - io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); - io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); - io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); - io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); - io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); - io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); - io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); - io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); - - pci_add(et4000w32p_pci_read, et4000w32p_pci_write, NULL); - - svga_vram_limit = 2 << 20; /*2mb - chip supports 4mb but can't map both 4mb linear frame buffer and accelerator registers*/ - - vrammask = 0x1fffff; + et4000w32p_t *et4000 = malloc(sizeof(et4000w32p_t)); + memset(et4000, 0, sizeof(et4000w32p_t)); - return svga_init(); + svga_init(&et4000->svga, et4000, 1 << 21, /*2mb*/ + et4000w32p_recalctimings, + et4000w32p_in, et4000w32p_out, + et4000w32p_hwcursor_draw); + + io_sethandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + + io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + + pci_add(et4000w32p_pci_read, et4000w32p_pci_write, et4000); + + return et4000; } -GFXCARD vid_et4000w32p = +void et4000w32p_close(void *p) { + et4000w32p_t *et4000 = (et4000w32p_t *)p; + + svga_close(&et4000->svga); + + free(et4000); +} + +void et4000w32p_speed_changed(void *p) +{ + et4000w32p_t *et4000 = (et4000w32p_t *)p; + + svga_recalctimings(&et4000->svga); +} + +device_t et4000w32p_device = +{ + "Tseng Labs ET4000/w32p", et4000w32p_init, - /*IO at 3Cx/3Dx*/ - et4000w32p_out, - et4000w32p_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - svga_poll, - svga_recalctimings, - - svga_write, - video_write_null, - video_write_null, - - svga_read, - video_read_null, - video_read_null + et4000w32p_close, + et4000w32p_speed_changed, + svga_add_status_info }; - - diff --git a/src/vid_et4000w32.h b/src/vid_et4000w32.h index e69de29..39280d6 100644 --- a/src/vid_et4000w32.h +++ b/src/vid_et4000w32.h @@ -0,0 +1 @@ +extern device_t et4000w32p_device; diff --git a/src/vid_hercules.c b/src/vid_hercules.c index 6cc1826..f3bc7cf 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -1,296 +1,358 @@ /*Hercules emulation*/ +#include #include "ibm.h" +#include "device.h" #include "mem.h" #include "timer.h" #include "video.h" +#include "vid_hercules.h" -void hercules_recalctimings(); -void hercules_write(uint32_t addr, uint8_t val, void *priv); -uint8_t hercules_read(uint32_t addr, void *priv); - -static uint8_t hercules_ctrl, hercules_ctrl2, hercules_stat; -uint8_t crtcm[32],crtcmreg; - -void hercules_out(uint16_t addr, uint8_t val, void *priv) +typedef struct hercules_t { + uint8_t crtc[32]; + int crtcreg; + + uint8_t ctrl, ctrl2, stat; + + int dispontime, dispofftime; + int vidtime; + + int firstline, lastline; + + int linepos, displine; + int vc, sc; + uint16_t ma, maback; + int con, coff, cursoron; + int dispon, blink; + int vsynctime, vadj; + + uint8_t *vram; +} hercules_t; + +static int mdacols[256][2][2]; + +void hercules_recalctimings(hercules_t *hercules); +void hercules_write(uint32_t addr, uint8_t val, void *p); +uint8_t hercules_read(uint32_t addr, void *p); + + +void hercules_out(uint16_t addr, uint8_t val, void *p) +{ + hercules_t *hercules = (hercules_t *)p; // pclog("Herc out %04X %02X\n",addr,val); switch (addr) { - case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6: - crtcmreg = val & 31; + case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: + hercules->crtcreg = val & 31; return; - case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7: - crtcm[crtcmreg] = val; - if (crtcm[10]==6 && crtcm[11]==7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ + case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: + hercules->crtc[hercules->crtcreg] = val; + if (hercules->crtc[10] == 6 && hercules->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ { - crtcm[10]=0xB; - crtcm[11]=0xC; + hercules->crtc[10] = 0xb; + hercules->crtc[11] = 0xc; } - hercules_recalctimings(); + hercules_recalctimings(hercules); return; - case 0x3B8: - hercules_ctrl = val; + case 0x3b8: + hercules->ctrl = val; return; - case 0x3BF: - hercules_ctrl2 = val; - video_write_b800 = (val&2) ? hercules_write : video_write_null; - video_read_b800 = (val&2) ? hercules_read : video_read_null; + case 0x3bf: + hercules->ctrl2 = val; + mem_removehandler(0xb8000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, hercules); + if (val & 2) + mem_sethandler(0xb8000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, hercules); return; } } -uint8_t hercules_in(uint16_t addr, void *priv) +uint8_t hercules_in(uint16_t addr, void *p) { + hercules_t *hercules = (hercules_t *)p; // pclog("Herc in %04X %02X %04X:%04X %04X\n",addr,(hercules_stat & 0xF) | ((hercules_stat & 8) << 4),CS,pc,CX); switch (addr) { - case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6: - return crtcmreg; - case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7: - return crtcm[crtcmreg]; - case 0x3BA: - return (hercules_stat & 0xF) | ((hercules_stat & 8) << 4); + case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: + return hercules->crtcreg; + case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: + return hercules->crtc[hercules->crtcreg]; + case 0x3ba: + return (hercules->stat & 0xf) | ((hercules->stat & 8) << 4); } return 0xff; } -void hercules_write(uint32_t addr, uint8_t val, void *priv) +void hercules_write(uint32_t addr, uint8_t val, void *p) { + hercules_t *hercules = (hercules_t *)p; // pclog("Herc write %08X %02X\n",addr,val); - vram[addr&0xFFFF]=val; + hercules->vram[addr & 0xffff] = val; } -uint8_t hercules_read(uint32_t addr, void *priv) +uint8_t hercules_read(uint32_t addr, void *p) { - return vram[addr&0xFFFF]; + hercules_t *hercules = (hercules_t *)p; + return hercules->vram[addr & 0xffff]; } -void hercules_recalctimings() +void hercules_recalctimings(hercules_t *hercules) { + double disptime; double _dispontime, _dispofftime; - disptime=crtc[0]+1; - _dispontime=crtc[1]; - _dispofftime=disptime-_dispontime; - _dispontime*=MDACONST; - _dispofftime*=MDACONST; - dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + disptime = hercules->crtc[0] + 1; + _dispontime = hercules->crtc[1]; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + hercules->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + hercules->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } -int mdacols[256][2][2]; - -static int linepos,displine; -static int vc,sc; -static uint16_t ma,maback; -static int con,coff,cursoron; -static int cgadispon,cgablink; -static int vsynctime,vadj; - -void hercules_poll() +void hercules_poll(void *p) { - uint16_t ca=(crtcm[15]|(crtcm[14]<<8))&0x3FFF; + hercules_t *hercules = (hercules_t *)p; + uint16_t ca = (hercules->crtc[15] | (hercules->crtc[14] << 8)) & 0x3fff; int drawcursor; - int x,c; + int x, c; int oldvc; - uint8_t chr,attr; + uint8_t chr, attr; uint16_t dat; int cols[4]; int oldsc; int blink; - if (!linepos) + if (!hercules->linepos) { //pclog("Poll %i %i\n",vc,sc); - vidtime+=dispofftime; - hercules_stat|=1; - linepos=1; - oldsc=sc; - if ((crtcm[8]&3)==3) sc=(sc<<1)&7; - if (cgadispon) + hercules->vidtime += hercules->dispofftime; + hercules->stat |= 1; + hercules->linepos = 1; + oldsc = hercules->sc; + if ((hercules->crtc[8] & 3) == 3) + hercules->sc = (hercules->sc << 1) & 7; + if (hercules->dispon) { - if (displinedispline < hercules->firstline) { - firstline=displine; + hercules->firstline = hercules->displine; } - lastline=displine; - cols[0]=0; - cols[1]=7; - if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1)) + hercules->lastline = hercules->displine; + cols[0] = 0; + cols[1] = 7; + if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) { - ca=(sc&3)*0x2000; - if ((hercules_ctrl & 0x80) && (hercules_ctrl2 & 2)) ca+=0x8000; + ca = (hercules->sc & 3) * 0x2000; + if ((hercules->ctrl & 0x80) && (hercules->ctrl2 & 2)) + ca += 0x8000; // printf("Draw herc %04X\n",ca); - for (x=0;xcrtc[1]; x++) { - dat=(vram[((ma<<1)&0x1FFF)+ca]<<8)|vram[((ma<<1)&0x1FFF)+ca+1]; - ma++; - for (c=0;c<16;c++) - buffer->line[displine][(x<<4)+c]=(dat&(32768>>c))?7:0; + dat = (hercules->vram[((hercules->ma << 1) & 0x1fff) + ca] << 8) | hercules->vram[((hercules->ma << 1) & 0x1fff) + ca + 1]; + hercules->ma++; + for (c = 0; c < 16; c++) + buffer->line[hercules->displine][(x << 4) + c] = (dat & (32768 >> c)) ? 7 : 0; } } else { - for (x=0;xcrtc[1]; x++) { - chr=vram[(ma<<1)&0x3FFF]; - attr=vram[((ma<<1)+1)&0x3FFF]; - drawcursor=((ma==ca) && con && cursoron); - blink=((cgablink&16) && (hercules_ctrl&0x20) && (attr&0x80) && !drawcursor); - if (sc==12 && ((attr&7)==1)) + chr = hercules->vram[(hercules->ma << 1) & 0x3fff]; + attr = hercules->vram[((hercules->ma << 1) + 1) & 0x3fff]; + drawcursor = ((hercules->ma == ca) && hercules->con && hercules->cursoron); + blink = ((hercules->blink & 16) && (hercules->ctrl & 0x20) && (attr & 0x80) && !drawcursor); + if (hercules->sc == 12 && ((attr & 7) == 1)) { - for (c=0;c<9;c++) - buffer->line[displine][(x*9)+c]=mdacols[attr][blink][1]; + for (c = 0; c < 9; c++) + buffer->line[hercules->displine][(x * 9) + c] = mdacols[attr][blink][1]; } else { - for (c=0;c<8;c++) - buffer->line[displine][(x*9)+c]=mdacols[attr][blink][(fontdatm[chr][sc]&(1<<(c^7)))?1:0]; - if ((chr&~0x1F)==0xC0) buffer->line[displine][(x*9)+8]=mdacols[attr][blink][fontdatm[chr][sc]&1]; - else buffer->line[displine][(x*9)+8]=mdacols[attr][blink][0]; + for (c = 0; c < 8; c++) + buffer->line[hercules->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][hercules->sc] & (1 << (c ^ 7))) ? 1 : 0]; + if ((chr & ~0x1f) == 0xc0) buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][hercules->sc] & 1]; + else buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][0]; } - ma++; + hercules->ma++; if (drawcursor) { - for (c=0;c<9;c++) - buffer->line[displine][(x*9)+c]^=mdacols[attr][0][1]; + for (c = 0; c < 9; c++) + buffer->line[hercules->displine][(x * 9) + c] ^= mdacols[attr][0][1]; } } } } - sc=oldsc; - if (vc==crtcm[7] && !sc) + hercules->sc = oldsc; + if (hercules->vc == hercules->crtc[7] && !hercules->sc) { - hercules_stat|=8; + hercules->stat |= 8; // printf("VSYNC on %i %i\n",vc,sc); } - displine++; - if (displine>=500) displine=0; + hercules->displine++; + if (hercules->displine >= 500) + hercules->displine = 0; } else { - vidtime+=dispontime; - if (cgadispon) hercules_stat&=~1; - linepos=0; - if (vsynctime) + hercules->vidtime += hercules->dispontime; + if (hercules->dispon) + hercules->stat &= ~1; + hercules->linepos = 0; + if (hercules->vsynctime) { - vsynctime--; - if (!vsynctime) + hercules->vsynctime--; + if (!hercules->vsynctime) { - hercules_stat&=~8; + hercules->stat &= ~8; // printf("VSYNC off %i %i\n",vc,sc); } } - if (sc==(crtcm[11]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[11]&31)>>1))) { con=0; coff=1; } - if (vadj) + if (hercules->sc == (hercules->crtc[11] & 31) || ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[11] & 31) >> 1))) + { + hercules->con = 0; + hercules->coff = 1; + } + if (hercules->vadj) { - sc++; - sc&=31; - ma=maback; - vadj--; - if (!vadj) + hercules->sc++; + hercules->sc &= 31; + hercules->ma = hercules->maback; + hercules->vadj--; + if (!hercules->vadj) { - cgadispon=1; - ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF; - sc=0; + hercules->dispon = 1; + hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff; + hercules->sc = 0; } } - else if (sc==crtcm[9] || ((crtcm[8]&3)==3 && sc==(crtcm[9]>>1))) + else if (hercules->sc == hercules->crtc[9] || ((hercules->crtc[8] & 3) == 3 && hercules->sc == (hercules->crtc[9] >> 1))) { - maback=ma; - sc=0; - oldvc=vc; - vc++; - vc&=127; - if (vc==crtcm[6]) cgadispon=0; - if (oldvc==crtcm[4]) + hercules->maback = hercules->ma; + hercules->sc = 0; + oldvc = hercules->vc; + hercules->vc++; + hercules->vc &= 127; + if (hercules->vc == hercules->crtc[6]) + hercules->dispon = 0; + if (oldvc == hercules->crtc[4]) { // printf("Display over at %i\n",displine); - vc=0; - vadj=crtcm[5]; - if (!vadj) cgadispon=1; - if (!vadj) ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF; - if ((crtcm[10]&0x60)==0x20) cursoron=0; - else cursoron=cgablink&16; + hercules->vc = 0; + hercules->vadj = hercules->crtc[5]; + if (!hercules->vadj) hercules->dispon=1; + if (!hercules->vadj) hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff; + if ((hercules->crtc[10] & 0x60) == 0x20) hercules->cursoron = 0; + else hercules->cursoron = hercules->blink & 16; } - if (vc==crtcm[7]) + if (hercules->vc == hercules->crtc[7]) { - cgadispon=0; - displine=0; - vsynctime=16;//(crtcm[3]>>4)+1; - if (crtcm[7]) + hercules->dispon = 0; + hercules->displine = 0; + hercules->vsynctime = 16;//(crtcm[3]>>4)+1; + if (hercules->crtc[7]) { // printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline); - if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1)) x = crtcm[1] << 4; - else x = crtcm[1] * 9; - lastline++; - if (x!=xsize || (lastline-firstline)!=ysize) + if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) x = hercules->crtc[1] << 4; + else x = hercules->crtc[1] * 9; + hercules->lastline++; + if (x != xsize || (hercules->lastline - hercules->firstline) != ysize) { - xsize=x; - ysize=lastline-firstline; + xsize = x; + ysize = hercules->lastline - hercules->firstline; // printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]); - if (xsize<64) xsize=656; - if (ysize<32) ysize=200; - updatewindowsize(xsize,ysize); + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + updatewindowsize(xsize, ysize); } startblit(); - video_blit_memtoscreen_8(0, firstline, xsize, ysize); + video_blit_memtoscreen_8(0, hercules->firstline, xsize, ysize); endblit(); frames++; - if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1)) + if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) { - video_res_x = crtcm[1] * 16; - video_res_y = crtcm[6] * 4; + video_res_x = hercules->crtc[1] * 16; + video_res_y = hercules->crtc[6] * 4; video_bpp = 1; } else { - video_res_x = crtcm[1]; - video_res_y = crtcm[6]; + video_res_x = hercules->crtc[1]; + video_res_y = hercules->crtc[6]; video_bpp = 0; } } - firstline=1000; - lastline=0; - cgablink++; + hercules->firstline = 1000; + hercules->lastline = 0; + hercules->blink++; } } else { - sc++; - sc&=31; - ma=maback; + hercules->sc++; + hercules->sc &= 31; + hercules->ma = hercules->maback; } - if ((sc==(crtcm[10]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[10]&31)>>1)))) + if ((hercules->sc == (hercules->crtc[10] & 31) || ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[10] & 31) >> 1)))) { - con=1; + hercules->con = 1; // printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); } } } -int hercules_init() +void *hercules_init() { - mem_sethandler(0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL); - return 0; + int c; + hercules_t *hercules = malloc(sizeof(hercules_t)); + memset(hercules, 0, sizeof(hercules_t)); + + hercules->vram = malloc(0x10000); + + timer_add(hercules_poll, &hercules->vidtime, TIMER_ALWAYS_ENABLED, hercules); + mem_sethandler(0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, hercules); + io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules); + + for (c = 0; c < 256; c++) + { + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; + if (c & 8) mdacols[c][0][1] = 15 + 16; + else mdacols[c][0][1] = 7 + 16; + } + mdacols[0x70][0][1] = 16; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; + mdacols[0xF0][0][1] = 16; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; + mdacols[0x78][0][1] = 16 + 7; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; + mdacols[0xF8][0][1] = 16 + 7; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; + + return hercules; } -GFXCARD vid_hercules = +void hercules_close(void *p) { + hercules_t *hercules = (hercules_t *)p; + + free(hercules->vram); + free(hercules); +} + +void hercules_speed_changed(void *p) +{ + hercules_t *hercules = (hercules_t *)p; + + hercules_recalctimings(hercules); +} + +device_t hercules_device = +{ + "Hercules", hercules_init, - /*IO at 3Cx/3Dx*/ - video_out_null, - video_in_null, - /*IO at 3Ax/3Bx*/ - hercules_out, - hercules_in, - - hercules_poll, - hercules_recalctimings, - - video_write_null, - hercules_write, - video_write_null, - - video_read_null, - hercules_read, - video_read_null + hercules_close, + hercules_speed_changed, + NULL }; diff --git a/src/vid_hercules.h b/src/vid_hercules.h new file mode 100644 index 0000000..43ec0da --- /dev/null +++ b/src/vid_hercules.h @@ -0,0 +1 @@ +extern device_t hercules_device; diff --git a/src/vid_icd2061.c b/src/vid_icd2061.c index f43f668..cdfd47a 100644 --- a/src/vid_icd2061.c +++ b/src/vid_icd2061.c @@ -5,70 +5,62 @@ #include "ibm.h" #include "vid_icd2061.h" -static int icd2061_state; -static int icd2061_status = 0; -static int icd2061_pos = 0; -static int icd2061_unlock = 0; -static uint32_t icd2061_data; - -static double icd2061_freq[4]; -static uint32_t icd2061_ctrl; - -void icd2061_write(int val) +void icd2061_write(icd2061_t *icd2061, int val) { int q, p, m, i, a; - if ((val & 1) && !(icd2061_state & 1)) + if ((val & 1) && !(icd2061->state & 1)) { - pclog("ICD2061 write %02X %i %08X %i\n", val, icd2061_unlock, icd2061_data, icd2061_pos); - if (!icd2061_status) + pclog("ICD2061 write %02X %i %08X %i\n", val, icd2061->unlock, icd2061->data, icd2061->pos); + if (!icd2061->status) { - if (val & 2) icd2061_unlock++; + if (val & 2) + icd2061->unlock++; else { - if (icd2061_unlock >= 5) + if (icd2061->unlock >= 5) { - icd2061_status = 1; - icd2061_pos = 0; + icd2061->status = 1; + icd2061->pos = 0; } else - icd2061_unlock = 0; + icd2061->unlock = 0; } } else if (val & 1) { - icd2061_data = (icd2061_data >> 1) | (((val & 2) ? 1 : 0) << 24); - icd2061_pos++; - if (icd2061_pos == 26) + icd2061->data = (icd2061->data >> 1) | (((val & 2) ? 1 : 0) << 24); + icd2061->pos++; + if (icd2061->pos == 26) { - pclog("ICD2061 data - %08X\n", icd2061_data); - a = (icd2061_data >> 21) & 0x7; + pclog("ICD2061 data - %08X\n", icd2061->data); + a = (icd2061->data >> 21) & 0x7; if (!(a & 4)) { - q = (icd2061_data & 0x7f) - 2; - m = 1 << ((icd2061_data >> 7) & 0x7); - p = ((icd2061_data >> 10) & 0x7f) - 3; - i = (icd2061_data >> 17) & 0xf; + q = (icd2061->data & 0x7f) - 2; + m = 1 << ((icd2061->data >> 7) & 0x7); + p = ((icd2061->data >> 10) & 0x7f) - 3; + i = (icd2061->data >> 17) & 0xf; pclog("p %i q %i m %i\n", p, q, m); - if (icd2061_ctrl & (1 << a)) + if (icd2061->ctrl & (1 << a)) p <<= 1; - icd2061_freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m; - pclog("ICD2061 freq %i = %f\n", a, icd2061_freq[a]); + icd2061->freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m; + pclog("ICD2061 freq %i = %f\n", a, icd2061->freq[a]); } else if (a == 6) { - icd2061_ctrl = val; + icd2061->ctrl = val; pclog("ICD2061 ctrl = %08X\n", val); } - icd2061_unlock = icd2061_data = 0; - icd2061_status = 0; + icd2061->unlock = icd2061->data = 0; + icd2061->status = 0; } } } - icd2061_state = val; + icd2061->state = val; } -double icd2061_getfreq(int i) +double icd2061_getfreq(icd2061_t *icd2061, int i) { - pclog("Return freq %f\n", icd2061_freq[i]); - return icd2061_freq[i]; + pclog("Return freq %f\n", icd2061->freq[i]); + return icd2061->freq[i]; } diff --git a/src/vid_icd2061.h b/src/vid_icd2061.h index 3d8b3fe..27e3ddb 100644 --- a/src/vid_icd2061.h +++ b/src/vid_icd2061.h @@ -1,2 +1,14 @@ -void icd2061_write(int val); -double icd2061_getfreq(int i); +typedef struct icd2061_t +{ + int state; + int status; + int pos; + int unlock; + uint32_t data; + + double freq[4]; + uint32_t ctrl; +} icd2061_t; + +void icd2061_write(icd2061_t *icd2061, int val); +double icd2061_getfreq(icd2061_t *icd2061, int i); diff --git a/src/vid_ics2595.c b/src/vid_ics2595.c index af6946f..87c6253 100644 --- a/src/vid_ics2595.c +++ b/src/vid_ics2595.c @@ -6,58 +6,50 @@ enum { - ICS2595_IDLE, + ICS2595_IDLE = 0, ICS2595_WRITE, ICS2595_READ }; -static int ics2595_oldfs3, ics2595_oldfs2; -static int ics2595_dat; -static int ics2595_pos; -static int ics2595_state = ICS2595_IDLE; - static int ics2595_div[4] = {8, 4, 2, 1}; -static double ics2595_clocks[16]; -double ics2595_output_clock; - -void ics2595_write(int strobe, int dat) +void ics2595_write(ics2595_t *ics2595, int strobe, int dat) { pclog("ics2595_write : %i %i\n", strobe, dat); if (strobe) { - if ((dat & 8) && !ics2595_oldfs3) /*Data clock*/ + if ((dat & 8) && !ics2595->oldfs3) /*Data clock*/ { pclog(" - new dat %i\n", dat & 4); - switch (ics2595_state) + switch (ics2595->state) { case ICS2595_IDLE: - ics2595_state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE; - ics2595_pos = 0; + ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE; + ics2595->pos = 0; break; case ICS2595_WRITE: - ics2595_dat = (ics2595_dat >> 1); + ics2595->dat = (ics2595->dat >> 1); if (dat & 4) - ics2595_dat |= (1 << 19); - ics2595_pos++; - if (ics2595_pos == 20) + ics2595->dat |= (1 << 19); + ics2595->pos++; + if (ics2595->pos == 20) { int d, n, l; - pclog("ICS2595_WRITE : dat %08X\n", ics2595_dat); - l = (ics2595_dat >> 2) & 31; - n = ((ics2595_dat >> 7) & 255) + 257; - d = ics2595_div[(ics2595_dat >> 16) & 3]; + pclog("ICS2595_WRITE : dat %08X\n", ics2595->dat); + l = (ics2595->dat >> 2) & 0xf; + n = ((ics2595->dat >> 7) & 255) + 257; + d = ics2595_div[(ics2595->dat >> 16) & 3]; - ics2595_clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d; + ics2595->clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d; pclog("ICS2595 clock set - L %i N %i D %i freq = %f\n", l, n, d, (14318181.8 * ((double)n / 46.0)) / (double)d); - ics2595_state = ICS2595_IDLE; + ics2595->state = ICS2595_IDLE; } break; } } - ics2595_oldfs2 = dat & 4; - ics2595_oldfs3 = dat & 8; + ics2595->oldfs2 = dat & 4; + ics2595->oldfs3 = dat & 8; } - ics2595_output_clock = ics2595_clocks[dat]; + ics2595->output_clock = ics2595->clocks[dat]; } diff --git a/src/vid_ics2595.h b/src/vid_ics2595.h index dd975b1..8d9b7f4 100644 --- a/src/vid_ics2595.h +++ b/src/vid_ics2595.h @@ -1,2 +1,12 @@ -void ics2595_write(int strobe, int dat); -extern double ics2595_output_clock; +typedef struct ics2595_t +{ + int oldfs3, oldfs2; + int dat; + int pos; + int state; + + double clocks[16]; + double output_clock; +} ics2595_t; + +void ics2595_write(ics2595_t *ics2595, int strobe, int dat); diff --git a/src/vid_mda.c b/src/vid_mda.c index 42c2ed4..e8c191a 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -1,259 +1,316 @@ /*MDA emulation*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "timer.h" #include "video.h" +#include "vid_mda.h" -void mda_recalctimings(); - -static uint8_t mda_ctrl,mda_stat; -uint8_t crtcm[32],crtcmreg; - -void mda_out(uint16_t addr, uint8_t val, void *priv) +typedef struct mda_t { + uint8_t crtc[32]; + int crtcreg; + + uint8_t ctrl, stat; + + int dispontime, dispofftime; + int vidtime; + + int firstline, lastline; + + int linepos, displine; + int vc, sc; + uint16_t ma, maback; + int con, coff, cursoron; + int dispon, blink; + int vsynctime, vadj; + + uint8_t *vram; +} mda_t; + +static int mdacols[256][2][2]; + +void mda_recalctimings(mda_t *mda); + +void mda_out(uint16_t addr, uint8_t val, void *p) +{ + mda_t *mda = (mda_t *)p; switch (addr) { - case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6: - crtcmreg = val & 31; + case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: + mda->crtcreg = val & 31; return; - case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7: - crtcm[crtcmreg] = val; - if (crtcm[10]==6 && crtcm[11]==7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ + case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: + mda->crtc[mda->crtcreg] = val; + if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ { - crtcm[10]=0xB; - crtcm[11]=0xC; + mda->crtc[10] = 0xb; + mda->crtc[11] = 0xc; } - mda_recalctimings(); + mda_recalctimings(mda); return; - case 0x3B8: - mda_ctrl = val; + case 0x3b8: + mda->ctrl = val; return; } } -uint8_t mda_in(uint16_t addr, void *priv) +uint8_t mda_in(uint16_t addr, void *p) { + mda_t *mda = (mda_t *)p; switch (addr) { - case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6: - return crtcmreg; - case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7: - return crtcm[crtcmreg]; - case 0x3BA: - return mda_stat | 0xF0; + case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: + return mda->crtcreg; + case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: + return mda->crtc[mda->crtcreg]; + case 0x3ba: + return mda->stat | 0xF0; } return 0xff; } -void mda_write(uint32_t addr, uint8_t val, void *priv) +void mda_write(uint32_t addr, uint8_t val, void *p) { - vram[addr&0xFFF]=val; + mda_t *mda = (mda_t *)p; + mda->vram[addr & 0xfff] = val; } -uint8_t mda_read(uint32_t addr, void *priv) +uint8_t mda_read(uint32_t addr, void *p) { - return vram[addr&0xFFF]; + mda_t *mda = (mda_t *)p; + return mda->vram[addr & 0xfff]; } -void mda_recalctimings() +void mda_recalctimings(mda_t *mda) { - double _dispontime, _dispofftime; - disptime=crtc[0]+1; - _dispontime=crtc[1]; - _dispofftime=disptime-_dispontime; - _dispontime*=MDACONST; - _dispofftime*=MDACONST; - dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + double _dispontime, _dispofftime, disptime; + disptime = mda->crtc[0] + 1; + _dispontime = mda->crtc[1]; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + mda->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + mda->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } -int mdacols[256][2][2]; - -static int linepos,displine; -static int vc,sc; -static uint16_t ma,maback; -static int con,coff,cursoron; -static int cgadispon,cgablink; -static int vsynctime,vadj; - -void mda_poll() +void mda_poll(void *p) { - uint16_t ca=(crtcm[15]|(crtcm[14]<<8))&0x3FFF; + mda_t *mda = (mda_t *)p; + uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; int drawcursor; - int x,c; + int x, c; int oldvc; - uint8_t chr,attr; + uint8_t chr, attr; int cols[4]; int oldsc; int blink; - if (!linepos) + if (!mda->linepos) { - vidtime+=dispofftime; - mda_stat|=1; - linepos=1; - oldsc=sc; - if ((crtcm[8]&3)==3) sc=(sc<<1)&7; - if (cgadispon) + mda->vidtime += mda->dispofftime; + mda->stat |= 1; + mda->linepos = 1; + oldsc = mda->sc; + if ((mda->crtc[8] & 3) == 3) + mda->sc = (mda->sc << 1) & 7; + if (mda->dispon) { - if (displinedispline < mda->firstline) { - firstline=displine; + mda->firstline = mda->displine; } - lastline=displine; - cols[0]=0; - cols[1]=7; - for (x=0;xlastline = mda->displine; + cols[0] = 0; + cols[1] = 7; + for (x = 0; x < mda->crtc[1]; x++) { - chr=vram[(ma<<1)&0x3FFF]; - attr=vram[((ma<<1)+1)&0x3FFF]; - drawcursor=((ma==ca) && con && cursoron); - blink=((cgablink&16) && (mda_ctrl&0x20) && (attr&0x80) && !drawcursor); - if (sc==12 && ((attr&7)==1)) + chr = mda->vram[(mda->ma << 1) & 0x3fff]; + attr = mda->vram[((mda->ma << 1) + 1) & 0x3fff]; + drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); + blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); + if (mda->sc == 12 && ((attr & 7) == 1)) { - for (c=0;c<9;c++) - buffer->line[displine][(x*9)+c]=mdacols[attr][blink][1]; + for (c = 0; c < 9; c++) + buffer->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1]; } else { - for (c=0;c<8;c++) - buffer->line[displine][(x*9)+c]=mdacols[attr][blink][(fontdatm[chr][sc]&(1<<(c^7)))?1:0]; - if ((chr&~0x1F)==0xC0) buffer->line[displine][(x*9)+8]=mdacols[attr][blink][fontdatm[chr][sc]&1]; - else buffer->line[displine][(x*9)+8]=mdacols[attr][blink][0]; + for (c = 0; c < 8; c++) + buffer->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0]; + if ((chr & ~0x1f) == 0xc0) buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1]; + else buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0]; } - ma++; + mda->ma++; if (drawcursor) { - for (c=0;c<9;c++) - buffer->line[displine][(x*9)+c]^=mdacols[attr][0][1]; + for (c = 0; c < 9; c++) + buffer->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1]; } } } - sc=oldsc; - if (vc==crtcm[7] && !sc) + mda->sc = oldsc; + if (mda->vc == mda->crtc[7] && !mda->sc) { - mda_stat|=8; + mda->stat |= 8; // printf("VSYNC on %i %i\n",vc,sc); } - displine++; - if (displine>=500) displine=0; + mda->displine++; + if (mda->displine >= 500) + mda->displine=0; } else { - vidtime+=dispontime; - if (cgadispon) mda_stat&=~1; - linepos=0; - if (vsynctime) + mda->vidtime += mda->dispontime; + if (mda->dispon) mda->stat&=~1; + mda->linepos=0; + if (mda->vsynctime) { - vsynctime--; - if (!vsynctime) + mda->vsynctime--; + if (!mda->vsynctime) { - mda_stat&=~8; + mda->stat&=~8; // printf("VSYNC off %i %i\n",vc,sc); } } - if (sc==(crtcm[11]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[11]&31)>>1))) { con=0; coff=1; } - if (vadj) + if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) + { + mda->con = 0; + mda->coff = 1; + } + if (mda->vadj) { - sc++; - sc&=31; - ma=maback; - vadj--; - if (!vadj) + mda->sc++; + mda->sc &= 31; + mda->ma = mda->maback; + mda->vadj--; + if (!mda->vadj) { - cgadispon=1; - ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF; - sc=0; + mda->dispon = 1; + mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + mda->sc = 0; } } - else if (sc==crtcm[9] || ((crtcm[8]&3)==3 && sc==(crtcm[9]>>1))) + else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) { - maback=ma; - sc=0; - oldvc=vc; - vc++; - vc&=127; - if (vc==crtcm[6]) cgadispon=0; - if (oldvc==crtcm[4]) + mda->maback = mda->ma; + mda->sc = 0; + oldvc = mda->vc; + mda->vc++; + mda->vc &= 127; + if (mda->vc == mda->crtc[6]) + mda->dispon=0; + if (oldvc == mda->crtc[4]) { // printf("Display over at %i\n",displine); - vc=0; - vadj=crtcm[5]; - if (!vadj) cgadispon=1; - if (!vadj) ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF; - if ((crtcm[10]&0x60)==0x20) cursoron=0; - else cursoron=cgablink&16; + mda->vc = 0; + mda->vadj = mda->crtc[5]; + if (!mda->vadj) mda->dispon = 1; + if (!mda->vadj) mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + if ((mda->crtc[10] & 0x60) == 0x20) mda->cursoron = 0; + else mda->cursoron = mda->blink & 16; } - if (vc==crtcm[7]) + if (mda->vc == mda->crtc[7]) { - cgadispon=0; - displine=0; - vsynctime=16;//(crtcm[3]>>4)+1; - if (crtcm[7]) + mda->dispon = 0; + mda->displine = 0; + mda->vsynctime = 16; + if (mda->crtc[7]) { // printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline); - x=crtcm[1]*9; - lastline++; - if (x!=xsize || (lastline-firstline)!=ysize) + x = mda->crtc[1] * 9; + mda->lastline++; + if (x != xsize || (mda->lastline - mda->firstline) != ysize) { - xsize=x; - ysize=lastline-firstline; + xsize = x; + ysize = mda->lastline - mda->firstline; // printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]); - if (xsize<64) xsize=656; - if (ysize<32) ysize=200; - updatewindowsize(xsize,ysize); + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + updatewindowsize(xsize, ysize); } startblit(); - video_blit_memtoscreen_8(0, firstline, xsize, lastline - firstline); + video_blit_memtoscreen_8(0, mda->firstline, xsize, mda->lastline - mda->firstline); endblit(); frames++; - video_res_x = crtcm[1]; - video_res_y = crtcm[6]; + video_res_x = mda->crtc[1]; + video_res_y = mda->crtc[6]; video_bpp = 0; } - firstline=1000; - lastline=0; - cgablink++; + mda->firstline = 1000; + mda->lastline = 0; + mda->blink++; } } else { - sc++; - sc&=31; - ma=maback; + mda->sc++; + mda->sc &= 31; + mda->ma = mda->maback; } - if ((sc==(crtcm[10]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[10]&31)>>1)))) + if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))) { - con=1; + mda->con = 1; // printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); } } } -int mda_init() +void *mda_init() { - mem_sethandler(0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL); - return 0; + int c; + mda_t *mda = malloc(sizeof(mda_t)); + memset(mda, 0, sizeof(mda_t)); + + mda->vram = malloc(0x1000); + + timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda); + mem_sethandler(0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, mda); + io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); + + for (c = 0; c < 256; c++) + { + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; + if (c & 8) mdacols[c][0][1] = 15 + 16; + else mdacols[c][0][1] = 7 + 16; + } + mdacols[0x70][0][1] = 16; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; + mdacols[0xF0][0][1] = 16; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; + mdacols[0x78][0][1] = 16 + 7; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; + mdacols[0xF8][0][1] = 16 + 7; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; + + return mda; } -GFXCARD vid_mda = +void mda_close(void *p) { + mda_t *mda = (mda_t *)p; + + free(mda->vram); + free(mda); +} + +void mda_speed_changed(void *p) +{ + mda_t *mda = (mda_t *)p; + + mda_recalctimings(mda); +} + +device_t mda_device = +{ + "MDA", mda_init, - /*IO at 3Cx/3Dx*/ - video_out_null, - video_in_null, - /*IO at 3Ax/3Bx*/ - mda_out, - mda_in, - - mda_poll, - mda_recalctimings, - - video_write_null, - mda_write, - video_write_null, - - video_read_null, - mda_read, - video_read_null + mda_close, + mda_speed_changed, + NULL }; diff --git a/src/vid_mda.h b/src/vid_mda.h new file mode 100644 index 0000000..99aa13c --- /dev/null +++ b/src/vid_mda.h @@ -0,0 +1 @@ +extern device_t mda_device; diff --git a/src/vid_olivetti_m24.c b/src/vid_olivetti_m24.c index 3097ebd..701d5f9 100644 --- a/src/vid_olivetti_m24.c +++ b/src/vid_olivetti_m24.c @@ -1,436 +1,487 @@ /*Olivetti M24 video emulation Essentially double-res CGA*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "timer.h" #include "video.h" +#include "vid_olivetti_m24.h" -void m24_recalctimings(); - -static uint8_t m24_ctrl; -static uint32_t m24_base; - -void m24_out(uint16_t addr, uint8_t val, void *priv) +typedef struct m24_t { + uint8_t crtc[32]; + int crtcreg; + + uint8_t *vram; + uint8_t charbuffer[256]; + + uint8_t ctrl; + uint32_t base; + + uint8_t cgamode, cgacol; + uint8_t stat; + + int linepos, displine; + int sc, vc; + int con, coff, cursoron, blink; + int vsynctime, vadj; + int lineff; + uint16_t ma, maback; + int dispon; + + int dispontime, dispofftime, vidtime; + + int firstline, lastline; +} m24_t; + +static uint8_t crtcmask[32] = +{ + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +void m24_recalctimings(m24_t *m24); + + +void m24_out(uint16_t addr, uint8_t val, void *p) +{ + m24_t *m24 = (m24_t *)p; uint8_t old; + pclog("m24_out %04X %02X\n", addr, val); switch (addr) { - case 0x3D4: - crtcreg = val & 31; + case 0x3d4: + m24->crtcreg = val & 31; return; - case 0x3D5: - old = crtc[crtcreg]; - crtc[crtcreg] = val & crtcmask[crtcreg]; + case 0x3d5: + old = m24->crtc[m24->crtcreg]; + m24->crtc[m24->crtcreg] = val & crtcmask[m24->crtcreg]; if (old != val) { - if (crtcreg < 0xE || crtcreg > 0x10) + if (m24->crtcreg < 0xe || m24->crtcreg > 0x10) { fullchange = changeframecount; - m24_recalctimings(); + m24_recalctimings(m24); } } return; - case 0x3D8: - cgamode = val; + case 0x3d8: + m24->cgamode = val; return; - case 0x3D9: - cgacol = val; + case 0x3d9: + m24->cgacol = val; return; case 0x3de: - m24_ctrl = val; - m24_base = (val & 0x08) ? 0x4000 : 0; + m24->ctrl = val; + m24->base = (val & 0x08) ? 0x4000 : 0; return; } } -uint8_t m24_in(uint16_t addr, void *priv) +uint8_t m24_in(uint16_t addr, void *p) { + m24_t *m24 = (m24_t *)p; switch (addr) { - case 0x3D4: - return crtcreg; - case 0x3D5: - return crtc[crtcreg]; - case 0x3DA: - return cgastat; + case 0x3d4: + return m24->crtcreg; + case 0x3d5: + return m24->crtc[m24->crtcreg]; + case 0x3da: + return m24->stat; } - return 0xFF; + return 0xff; } -static uint8_t charbuffer[256]; - -void m24_write(uint32_t addr, uint8_t val, void *priv) +void m24_write(uint32_t addr, uint8_t val, void *p) { - vram[addr & 0x7FFF]=val; - charbuffer[ ((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val; - charbuffer[(((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val; + m24_t *m24 = (m24_t *)p; + m24->vram[addr & 0x7FFF]=val; + m24->charbuffer[ ((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val; + m24->charbuffer[(((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val; } -uint8_t m24_read(uint32_t addr, void *priv) +uint8_t m24_read(uint32_t addr, void *p) { - return vram[addr & 0x7FFF]; + m24_t *m24 = (m24_t *)p; + return m24->vram[addr & 0x7FFF]; } -void m24_recalctimings() +void m24_recalctimings(m24_t *m24) { - double _dispontime, _dispofftime; - if (cgamode & 1) + double _dispontime, _dispofftime, disptime; + if (m24->cgamode & 1) { - disptime = crtc[0] + 1; - _dispontime = crtc[1]; + disptime = m24->crtc[0] + 1; + _dispontime = m24->crtc[1]; } else { - disptime = (crtc[0] + 1) << 1; - _dispontime = crtc[1] << 1; + disptime = (m24->crtc[0] + 1) << 1; + _dispontime = m24->crtc[1] << 1; } _dispofftime = disptime - _dispontime; // printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); _dispontime *= CGACONST / 2; _dispofftime *= CGACONST / 2; // printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); - dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + m24->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + m24->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } -static int linepos,displine; -static int sc,vc; -static int cgadispon; -static int con,coff,cursoron,cgablink; -static int vsynctime,vadj; -static int m24_lineff = 0; -static uint16_t ma,maback; - -void m24_poll() +void m24_poll(void *p) { - uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF; + m24_t *m24 = (m24_t *)p; + uint16_t ca = (m24->crtc[15] | (m24->crtc[14] << 8)) & 0x3fff; int drawcursor; - int x,c; + int x, c; int oldvc; - uint8_t chr,attr; - uint16_t dat,dat2; + uint8_t chr, attr; + uint16_t dat, dat2; int cols[4]; int col; int oldsc; - if (!linepos) + if (!m24->linepos) { // pclog("Line poll %i %i %i %i - %04X %i %i %i\n", m24_lineff, vc, sc, vadj, ma, firstline, lastline, displine); - vidtime+=dispofftime; - cgastat|=1; - linepos=1; - oldsc=sc; - if ((crtc[8]&3)==3) sc=(sc<<1)&7; - if (cgadispon) + m24->vidtime += m24->dispofftime; + m24->stat |= 1; + m24->linepos = 1; + oldsc = m24->sc; + if ((m24->crtc[8] & 3) == 3) + m24->sc = (m24->sc << 1) & 7; + if (m24->dispon) { - if (displinelinepos); + if (m24->displine < m24->firstline) { - firstline=displine; + m24->firstline = m24->displine; // printf("Firstline %i\n",firstline); } - lastline=displine; - for (c=0;c<8;c++) + m24->lastline = m24->displine; + for (c = 0; c < 8; c++) { - if ((cgamode&0x12)==0x12) + if ((m24->cgamode & 0x12) == 0x12) { - buffer->line[displine][c]=0; - if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0; - else buffer->line[displine][c+(crtc[1]<<4)+8]=0; + buffer->line[m24->displine][c] = 0; + if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = 0; + else buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = 0; } else { - buffer->line[displine][c]=(cgacol&15)+16; - if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16; - else buffer->line[displine][c+(crtc[1]<<4)+8]=(cgacol&15)+16; + buffer->line[m24->displine][c] = (m24->cgacol & 15) + 16; + if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = (m24->cgacol & 15) + 16; + else buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = (m24->cgacol & 15) + 16; } } - if (cgamode&1) + if (m24->cgamode & 1) { - for (x=0;xcrtc[1]; x++) { - chr = charbuffer[ x << 1]; - attr = charbuffer[(x << 1) + 1]; - drawcursor=((ma==ca) && con && cursoron); - if (cgamode&0x20) + chr = m24->charbuffer[ x << 1]; + attr = m24->charbuffer[(x << 1) + 1]; + drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron); + if (m24->cgamode & 0x20) { - cols[1]=(attr&15)+16; - cols[0]=((attr>>4)&7)+16; - if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0]; + cols[1] = (attr & 15) + 16; + cols[0] = ((attr >> 4) & 7) + 16; + if ((m24->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; } else { - cols[1]=(attr&15)+16; - cols[0]=(attr>>4)+16; + cols[1] = (attr & 15) + 16; + cols[0] = (attr >> 4) + 16; } if (drawcursor) { - for (c=0;c<8;c++) - buffer->line[displine][(x<<3)+c+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0]^15; + for (c = 0; c < 8; c++) + buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { - for (c=0;c<8;c++) - buffer->line[displine][(x<<3)+c+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0]; + for (c = 0; c < 8; c++) + buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0]; } - ma++; + m24->ma++; } } - else if (!(cgamode&2)) + else if (!(m24->cgamode & 2)) { - for (x=0;xcrtc[1]; x++) { - chr=vram[((ma<<1)&0x3FFF) + m24_base]; - attr=vram[(((ma<<1)+1)&0x3FFF) + m24_base]; - drawcursor=((ma==ca) && con && cursoron); - if (cgamode&0x20) + chr = m24->vram[((m24->ma << 1) & 0x3fff) + m24->base]; + attr = m24->vram[(((m24->ma << 1) + 1) & 0x3fff) + m24->base]; + drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron); + if (m24->cgamode & 0x20) { - cols[1]=(attr&15)+16; - cols[0]=((attr>>4)&7)+16; - if ((cgablink&16) && (attr&0x80)) cols[1]=cols[0]; + cols[1] = (attr & 15) + 16; + cols[0] = ((attr >> 4) & 7) + 16; + if ((m24->blink & 16) && (attr & 0x80)) + cols[1] = cols[0]; } else { - cols[1]=(attr&15)+16; - cols[0]=(attr>>4)+16; + cols[1] = (attr & 15) + 16; + cols[0] = (attr >> 4) + 16; } - ma++; + m24->ma++; if (drawcursor) { - for (c=0;c<8;c++) - buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0]^15; + for (c = 0; c < 8; c++) + buffer->line[m24->displine][(x << 4) + (c << 1) + 8] = + buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { - for (c=0;c<8;c++) - buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0]; + for (c = 0; c < 8; c++) + buffer->line[m24->displine][(x << 4) + (c << 1) + 8] = + buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0]; } } } - else if (!(cgamode&16)) + else if (!(m24->cgamode & 16)) { - cols[0]=(cgacol&15)|16; - col=(cgacol&16)?24:16; - if (cgamode&4) + cols[0] = (m24->cgacol & 15) | 16; + col = (m24->cgacol & 16) ? 24 : 16; + if (m24->cgamode & 4) { - cols[1]=col|3; - cols[2]=col|4; - cols[3]=col|7; + cols[1] = col | 3; + cols[2] = col | 4; + cols[3] = col | 7; } - else if (cgacol&32) + else if (m24->cgacol & 32) { - cols[1]=col|3; - cols[2]=col|5; - cols[3]=col|7; + cols[1] = col | 3; + cols[2] = col | 5; + cols[3] = col | 7; } else { - cols[1]=col|2; - cols[2]=col|4; - cols[3]=col|6; + cols[1] = col | 2; + cols[2] = col | 4; + cols[3] = col | 6; } - for (x=0;xcrtc[1]; x++) { - dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000) + m24_base]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1 + m24_base]; - ma++; - for (c=0;c<8;c++) + dat = (m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + m24->base] << 8) | + m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + 1 + m24->base]; + m24->ma++; + for (c = 0; c < 8; c++) { - buffer->line[displine][(x<<4)+(c<<1)+8]= - buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14]; - dat<<=2; + buffer->line[m24->displine][(x << 4) + (c << 1) + 8] = + buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + dat <<= 2; } } } else { - - if (m24_ctrl & 1) + if (m24->ctrl & 1) { - dat2 = ((sc & 1) * 0x4000) | (m24_lineff * 0x2000); - cols[0]=0; cols[1]=/*(cgacol&15)*/15+16; + dat2 = ((m24->sc & 1) * 0x4000) | (m24->lineff * 0x2000); + cols[0] = 0; cols[1] = /*(m24->cgacol & 15)*/15 + 16; } else { - dat2 = (sc & 1) * 0x2000; - cols[0]=0; cols[1]=(cgacol&15)+16; + dat2 = (m24->sc & 1) * 0x2000; + cols[0] = 0; cols[1] = (m24->cgacol & 15) + 16; } - for (x=0;xcrtc[1]; x++) { - dat=(vram[((ma<<1)&0x1FFF) + dat2]<<8) | vram[((ma<<1)&0x1FFF) + dat2 + 1]; - ma++; - for (c=0;c<16;c++) + dat = (m24->vram[((m24->ma << 1) & 0x1fff) + dat2] << 8) | m24->vram[((m24->ma << 1) & 0x1fff) + dat2 + 1]; + m24->ma++; + for (c = 0; c < 16; c++) { - buffer->line[displine][(x<<4)+c+8]=cols[dat>>15]; - dat<<=1; + buffer->line[m24->displine][(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; } } } } else { - cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16; - if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]); - else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]); + cols[0] = ((m24->cgamode & 0x12) == 0x12) ? 0 : (m24->cgacol & 15) + 16; + if (m24->cgamode & 1) hline(buffer, 0, m24->displine, (m24->crtc[1] << 3) + 16, cols[0]); + else hline(buffer, 0, m24->displine, (m24->crtc[1] << 4) + 16, cols[0]); } - if (cgamode&1) x=(crtc[1]<<3)+16; - else x=(crtc[1]<<4)+16; + if (m24->cgamode & 1) x = (m24->crtc[1] << 3) + 16; + else x = (m24->crtc[1] << 4) + 16; - sc=oldsc; - if (vc==crtc[7] && !sc) - cgastat|=8; - displine++; - if (displine>=720) displine=0; + m24->sc = oldsc; + if (m24->vc == m24->crtc[7] && !m24->sc) + m24->stat |= 8; + m24->displine++; + if (m24->displine >= 720) m24->displine = 0; } else { // pclog("Line poll %i %i %i %i\n", m24_lineff, vc, sc, vadj); - vidtime+=dispontime; - if (cgadispon) cgastat&=~1; - linepos=0; - m24_lineff ^= 1; - if (m24_lineff) + m24->vidtime += m24->dispontime; + if (m24->dispon) m24->stat &= ~1; + m24->linepos = 0; + m24->lineff ^= 1; + if (m24->lineff) { - ma = maback; + m24->ma = m24->maback; } else { - if (vsynctime) + if (m24->vsynctime) { - vsynctime--; - if (!vsynctime) - cgastat&=~8; + m24->vsynctime--; + if (!m24->vsynctime) + m24->stat &= ~8; } - if (sc==(crtc[11]&31) || ((crtc[8]&3)==3 && sc==((crtc[11]&31)>>1))) { con=0; coff=1; } - if (vadj) + if (m24->sc == (m24->crtc[11] & 31) || ((m24->crtc[8] & 3) == 3 && m24->sc == ((m24->crtc[11] & 31) >> 1))) + { + m24->con = 0; + m24->coff = 1; + } + if (m24->vadj) { - sc++; - sc&=31; - ma=maback; - vadj--; - if (!vadj) + m24->sc++; + m24->sc &= 31; + m24->ma = m24->maback; + m24->vadj--; + if (!m24->vadj) { - cgadispon=1; - ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF; - sc=0; + m24->dispon = 1; + m24->ma = m24->maback = (m24->crtc[13] | (m24->crtc[12] << 8)) & 0x3fff; + m24->sc = 0; } } - else if (sc==crtc[9] || ((crtc[8]&3)==3 && sc==(crtc[9]>>1))) + else if (m24->sc == m24->crtc[9] || ((m24->crtc[8] & 3) == 3 && m24->sc == (m24->crtc[9] >> 1))) { - maback=ma; - sc=0; - oldvc=vc; - vc++; - vc&=127; + m24->maback = m24->ma; + m24->sc = 0; + oldvc = m24->vc; + m24->vc++; + m24->vc &= 127; - if (vc==crtc[6]) - cgadispon=0; + if (m24->vc == m24->crtc[6]) + m24->dispon=0; - if (oldvc==crtc[4]) + if (oldvc == m24->crtc[4]) { - vc=0; - vadj=crtc[5]; - if (!vadj) cgadispon=1; - if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF; - if ((crtc[10]&0x60)==0x20) cursoron=0; - else cursoron=cgablink&16; + m24->vc = 0; + m24->vadj = m24->crtc[5]; + if (!m24->vadj) m24->dispon = 1; + if (!m24->vadj) m24->ma = m24->maback = (m24->crtc[13] | (m24->crtc[12] << 8)) & 0x3fff; + if ((m24->crtc[10] & 0x60) == 0x20) m24->cursoron = 0; + else m24->cursoron = m24->blink & 16; } - if (vc==crtc[7]) + if (m24->vc == m24->crtc[7]) { - cgadispon=0; - displine=0; - vsynctime=(crtc[3]>>4)+1; - if (crtc[7]) + m24->dispon = 0; + m24->displine = 0; + m24->vsynctime = (m24->crtc[3] >> 4) + 1; + if (m24->crtc[7]) { - if (cgamode&1) x=(crtc[1]<<3)+16; - else x=(crtc[1]<<4)+16; - lastline++; - if (x!=xsize || (lastline-firstline)!=ysize) + if (m24->cgamode & 1) x = (m24->crtc[1] << 3) + 16; + else x = (m24->crtc[1] << 4) + 16; + m24->lastline++; + if (x != xsize || (m24->lastline - m24->firstline) != ysize) { - xsize=x; - ysize=lastline-firstline; - if (xsize<64) xsize=656; - if (ysize<32) ysize=200; + xsize = x; + ysize = m24->lastline - m24->firstline; + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; updatewindowsize(xsize, ysize + 16); } startblit(); - video_blit_memtoscreen_8(0, firstline - 8, xsize, (lastline - firstline) + 16); - if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF); - readflash=0; +pclog("m24 blit %i %i\n", m24->firstline, m24->lastline); + video_blit_memtoscreen_8(0, m24->firstline - 8, xsize, (m24->lastline - m24->firstline) + 16); + if (readflash) rectfill(screen, winsizex - 40, 8, winsizex - 8, 14, 0xFFFFFFFF); + readflash = 0; frames++; endblit(); video_res_x = xsize - 16; video_res_y = ysize; - if (cgamode & 1) + if (m24->cgamode & 1) { video_res_x /= 8; - video_res_y /= (crtc[9] + 1) * 2; + video_res_y /= (m24->crtc[9] + 1) * 2; video_bpp = 0; } - else if (!(cgamode & 2)) + else if (!(m24->cgamode & 2)) { video_res_x /= 16; - video_res_y /= (crtc[9] + 1) * 2; + video_res_y /= (m24->crtc[9] + 1) * 2; video_bpp = 0; } - else if (!(cgamode&16)) + else if (!(m24->cgamode & 16)) { video_res_x /= 2; video_res_y /= 2; video_bpp = 2; } - else if (!(m24_ctrl & 1)) + else if (!(m24->ctrl & 1)) { video_res_y /= 2; video_bpp = 1; } } - firstline=1000; - lastline=0; - cgablink++; + m24->firstline = 1000; + m24->lastline = 0; + m24->blink++; } } else { - sc++; - sc&=31; - ma=maback; + m24->sc++; + m24->sc &= 31; + m24->ma = m24->maback; } - if ((sc==(crtc[10]&31) || ((crtc[8]&3)==3 && sc==((crtc[10]&31)>>1)))) con=1; + if ((m24->sc == (m24->crtc[10] & 31) || ((m24->crtc[8] & 3) == 3 && m24->sc == ((m24->crtc[10] & 31) >> 1)))) + m24->con = 1; } - if (cgadispon && (cgamode&1)) + if (m24->dispon && (m24->cgamode & 1)) { - for (x=0;x<(crtc[1]<<1);x++) - charbuffer[x]=vram[(((ma<<1)+x)&0x3FFF) + m24_base]; + for (x = 0; x < (m24->crtc[1] << 1); x++) + m24->charbuffer[x] = m24->vram[(((m24->ma << 1) + x) & 0x3fff) + m24->base]; } } } - -int m24_init() +void *m24_init() { - mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, NULL); - return 0; + int c; + m24_t *m24 = malloc(sizeof(m24_t)); + memset(m24, 0, sizeof(m24_t)); + + m24->vram = malloc(0x8000); + + timer_add(m24_poll, &m24->vidtime, TIMER_ALWAYS_ENABLED, m24); + mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, m24); + io_sethandler(0x03d0, 0x0010, m24_in, NULL, NULL, m24_out, NULL, NULL, m24); + return m24; } -GFXCARD vid_m24 = +void m24_close(void *p) { + m24_t *m24 = (m24_t *)p; + + free(m24->vram); + free(m24); +} + +void m24_speed_changed(void *p) +{ + m24_t *m24 = (m24_t *)p; + + m24_recalctimings(m24); +} + +device_t m24_device = +{ + "Olivetti M24 (video)", m24_init, - /*IO at 3Cx/3Dx*/ - m24_out, - m24_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - m24_poll, - m24_recalctimings, - - video_write_null, - video_write_null, - m24_write, - - video_read_null, - video_read_null, - m24_read + m24_close, + m24_speed_changed, + NULL }; diff --git a/src/vid_olivetti_m24.h b/src/vid_olivetti_m24.h index e69de29..ce61ca0 100644 --- a/src/vid_olivetti_m24.h +++ b/src/vid_olivetti_m24.h @@ -0,0 +1 @@ +extern device_t m24_device; diff --git a/src/vid_oti067.c b/src/vid_oti067.c index d36fc07..1a48e44 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -1,126 +1,151 @@ /*Oak OTI067 emulation*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "video.h" +#include "vid_oti067.h" #include "vid_svga.h" -static int oti067_index; -static uint8_t oti067_regs[32]; - -void oti067_out(uint16_t addr, uint8_t val, void *priv) +typedef struct oti067_t { + svga_t svga; + + int index; + uint8_t regs[32]; +} oti067_t; + +void oti067_out(uint16_t addr, uint8_t val, void *p) +{ + oti067_t *oti067 = (oti067_t *)p; + svga_t *svga = &oti067->svga; uint8_t old; // pclog("oti067_out : %04X %02X %02X %i\n", addr, val, ram[0x489], ins); - if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga_miscout&1)) addr ^= 0x60; + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { case 0x3D4: - crtcreg=val&31; + svga->crtcreg = val & 31; return; case 0x3D5: - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; - if (old!=val) + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(svga); } } break; - case 0x3DE: oti067_index=val&0x1F; return; + case 0x3DE: + oti067->index = val & 0x1f; + return; case 0x3DF: - oti067_regs[oti067_index]=val; - switch (oti067_index) + oti067->regs[oti067->index] = val; + switch (oti067->index) { case 0xD: - vrammask=(val&0xC)?0x7FFFF:0x3FFFF; + svga->vrammask = (val & 0xc) ? 0x7ffff : 0x3ffff; break; case 0x11: - svgarbank=(val&0xF)*65536; - svgawbank=(val>>4)*65536; + svga->read_bank = (val & 0xf) * 65536; + svga->write_bank = (val >> 4) * 65536; break; } return; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t oti067_in(uint16_t addr, void *priv) +uint8_t oti067_in(uint16_t addr, void *p) { + oti067_t *oti067 = (oti067_t *)p; + svga_t *svga = &oti067->svga; uint8_t temp; // if (addr != 0x3da && addr != 0x3ba) pclog("oti067_in : %04X ", addr); - if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga_miscout&1)) addr ^= 0x60; + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { case 0x3D4: - temp = crtcreg; + temp = svga->crtcreg; break; case 0x3D5: - temp = crtc[crtcreg]; + temp = svga->crtc[svga->crtcreg]; break; case 0x3DE: - temp = oti067_index|(2<<5); + temp = oti067->index | (2 << 5); break; case 0x3DF: - if (oti067_index==0x10) temp = 0x18; - else if (oti067_index==0xD) temp = oti067_regs[oti067_index]|0xC0; - else temp = oti067_regs[oti067_index]; + if (oti067->index==0x10) temp = 0x18; + else if (oti067->index==0xD) temp = oti067->regs[oti067->index]|0xC0; + else temp = oti067->regs[oti067->index]; break; default: - temp = svga_in(addr, NULL); + temp = svga_in(addr, svga); break; } // if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,pc); return temp; } -void oti067_recalctimings() +void oti067_recalctimings(svga_t *svga) { - if (oti067_regs[0x14]&0x08) svga_ma|=0x10000; - if (oti067_regs[0x0D]&0x0C) svga_rowoffset<<=1; - svga_interlace = oti067_regs[0x14]&0x80; + oti067_t *oti067 = (oti067_t *)svga->p; + + if (oti067->regs[0x14] & 0x08) svga->ma_latch |= 0x10000; + if (oti067->regs[0x0d] & 0x0c) svga->rowoffset <<= 1; + svga->interlace = oti067->regs[0x14] & 0x80; } -int oti067_init() +void *oti067_init() { - svga_recalctimings_ex = oti067_recalctimings; - svga_vram_limit = 1 << 19; /*512kb*/ - vrammask = 0x7ffff; - bpp = 8; - svga_miscout = 1; - return svga_init(); + oti067_t *oti067 = malloc(sizeof(oti067_t)); + memset(oti067, 0, sizeof(oti067_t)); + + svga_init(&oti067->svga, oti067, 1 << 19, /*512kb*/ + oti067_recalctimings, + oti067_in, oti067_out, + NULL); + + io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); + + oti067->svga.miscout = 1; + return oti067; } -GFXCARD vid_oti067 = +void oti067_close(void *p) { + oti067_t *oti067 = (oti067_t *)p; + + svga_close(&oti067->svga); + + free(oti067); +} + +void oti067_speed_changed(void *p) +{ + oti067_t *oti067 = (oti067_t *)p; + + svga_recalctimings(&oti067->svga); +} + +device_t oti067_device = +{ + "Oak OTI-067", oti067_init, - /*IO at 3Cx/3Dx*/ - oti067_out, - oti067_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - svga_poll, - svga_recalctimings, - - svga_write, - video_write_null, - video_write_null, - - svga_read, - video_read_null, - video_read_null + oti067_close, + oti067_speed_changed, + svga_add_status_info }; diff --git a/src/vid_oti067.h b/src/vid_oti067.h new file mode 100644 index 0000000..3e28595 --- /dev/null +++ b/src/vid_oti067.h @@ -0,0 +1 @@ +extern device_t oti067_device; diff --git a/src/vid_paradise.c b/src/vid_paradise.c index b7fd63a..c756075 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -3,271 +3,335 @@ PC2086, PC3086 use PVGA1A MegaPC uses W90C11A */ +#include #include "ibm.h" +#include "device.h" #include "mem.h" #include "video.h" +#include "vid_paradise.h" #include "vid_svga.h" +#include "vid_svga_render.h" #include "vid_unk_ramdac.h" -void paradise_write(uint32_t addr, uint8_t val, void *priv); -uint8_t paradise_read(uint32_t addr, void *priv); -void paradise_remap(); - -enum +typedef struct paradise_t { - PVGA1A = 0, - WD90C11 -}; + svga_t svga; + + enum + { + PVGA1A = 0, + WD90C11 + } type; -static int paradise_type; + uint32_t read_bank[4], write_bank[4]; +} paradise_t; -static uint32_t paradise_bank_r[4], paradise_bank_w[4]; +void paradise_write(uint32_t addr, uint8_t val, void *p); +uint8_t paradise_read(uint32_t addr, void *p); +void paradise_remap(paradise_t *paradise); -void paradise_out(uint16_t addr, uint8_t val, void *priv) + +void paradise_out(uint16_t addr, uint8_t val, void *p) { + paradise_t *paradise = (paradise_t *)p; + svga_t *svga = ¶dise->svga; uint8_t old; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; // output = 3; pclog("Paradise out %04X %02X %04X:%04X\n", addr, val, CS, pc); switch (addr) { case 0x3c5: - if (seqaddr > 7) + if (svga->seqaddr > 7) { - if (paradise_type < WD90C11 || seqregs[6] != 0x48) + if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) return; - seqregs[seqaddr & 0x1f] = val; - if (seqaddr == 0x11) - paradise_remap(); + svga->seqregs[svga->seqaddr & 0x1f] = val; + if (svga->seqaddr == 0x11) + paradise_remap(paradise); return; } break; case 0x3cf: - if (gdcaddr >= 0x9 && gdcaddr < 0xf) + if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf) { - if ((gdcreg[0xf] & 7) != 5) + if ((svga->gdcreg[0xf] & 7) != 5) return; } - if (gdcaddr == 6) + if (svga->gdcaddr == 6) { - if ((gdcreg[6] & 0xc) != (val & 0xc)) + if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - mem_removehandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL); + mem_removehandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, paradise); // pclog("Write mapping %02X\n", val); switch (val&0xC) { case 0x0: /*128k at A0000*/ - mem_sethandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL); + mem_sethandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, paradise); break; case 0x4: /*64k at A0000*/ - mem_sethandler(0xa0000, 0x10000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL); + mem_sethandler(0xa0000, 0x10000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, paradise); break; case 0x8: /*32k at B0000*/ - mem_sethandler(0xb0000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL); + mem_sethandler(0xb0000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, paradise); break; case 0xC: /*32k at B8000*/ - mem_sethandler(0xb8000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL); + mem_sethandler(0xb8000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, paradise); break; } } - gdcreg[6] = val; - paradise_remap(); + svga->gdcreg[6] = val; + paradise_remap(paradise); return; } - if (gdcaddr == 0x9 || gdcaddr == 0xa) + if (svga->gdcaddr == 0x9 || svga->gdcaddr == 0xa) { - gdcreg[gdcaddr] = val; - paradise_remap(); + svga->gdcreg[svga->gdcaddr] = val; + paradise_remap(paradise); return; } - if (gdcaddr == 0xe) + if (svga->gdcaddr == 0xe) { - gdcreg[0xe] = val; - paradise_remap(); + svga->gdcreg[0xe] = val; + paradise_remap(paradise); return; } break; case 0x3D4: - if (paradise_type == PVGA1A) - crtcreg = val & 0x1f; + if (paradise->type == PVGA1A) + svga->crtcreg = val & 0x1f; else - crtcreg = val & 0x3f; + svga->crtcreg = val & 0x3f; return; case 0x3D5: - if (crtcreg <= 7 && crtc[0x11] & 0x80) + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; - if (crtcreg > 0x29 && (crtc[0x29] & 7) != 5) + if (svga->crtcreg > 0x29 && (svga->crtc[0x29] & 7) != 5) return; - if (crtcreg >= 0x31 && crtcreg <= 0x37) + if (svga->crtcreg >= 0x31 && svga->crtcreg <= 0x37) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - if (old!=val) + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(¶dise->svga); } } break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t paradise_in(uint16_t addr, void *priv) +uint8_t paradise_in(uint16_t addr, void *p) { - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + paradise_t *paradise = (paradise_t *)p; + svga_t *svga = ¶dise->svga; -// if (addr != 0x3da) pclog("Paradise in %04X\n", addr); + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + if (addr != 0x3da) pclog("Paradise in %04X\n", addr); switch (addr) { + case 0x3c2: + return 0x10; + case 0x3c5: - if (seqaddr > 7) + if (svga->seqaddr > 7) { - if (paradise_type < WD90C11 || seqregs[6] != 0x48) + if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) return 0xff; - if (seqaddr > 0x12) + if (svga->seqaddr > 0x12) return 0xff; - return seqregs[seqaddr & 0x1f]; + return svga->seqregs[svga->seqaddr & 0x1f]; } break; case 0x3cf: - if (gdcaddr >= 0x9 && gdcaddr < 0xf) + if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf) { - if (gdcreg[0xf] & 0x10) + if (svga->gdcreg[0xf] & 0x10) return 0xff; - switch (gdcaddr) + switch (svga->gdcaddr) { case 0xf: - return (gdcreg[0xf] & 0x17) | 0x80; + return (svga->gdcreg[0xf] & 0x17) | 0x80; } } break; case 0x3D4: - return crtcreg; + return svga->crtcreg; case 0x3D5: - if (crtcreg > 0x29 && crtcreg < 0x30 && (crtc[0x29] & 0x88) != 0x80) + if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80) return 0xff; - return crtc[crtcreg]; + return svga->crtc[svga->crtcreg]; } - return svga_in(addr, NULL); + return svga_in(addr, svga); } -void paradise_remap() +void paradise_remap(paradise_t *paradise) { - if (seqregs[0x11] & 0x80) + svga_t *svga = ¶dise->svga; + + if (svga->seqregs[0x11] & 0x80) { // pclog("Remap 1\n"); - paradise_bank_r[0] = paradise_bank_r[2] = (gdcreg[0x9] & 0x7f) << 12; - paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise_bank_w[0] = paradise_bank_w[2] = (gdcreg[0xa] & 0x7f) << 12; - paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0xa] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; + paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; + paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); } - else if (gdcreg[0xe] & 0x08) + else if (svga->gdcreg[0xe] & 0x08) { - if (gdcreg[0x6] & 0xc) + if (svga->gdcreg[0x6] & 0xc) { // pclog("Remap 2\n"); - paradise_bank_r[0] = paradise_bank_r[2] = (gdcreg[0xa] & 0x7f) << 12; - paradise_bank_w[0] = paradise_bank_w[2] = (gdcreg[0xa] & 0x7f) << 12; - paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; + paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; + paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); } else { // pclog("Remap 3\n"); - paradise_bank_r[0] = paradise_bank_w[0] = (gdcreg[0xa] & 0x7f) << 12; - paradise_bank_r[1] = paradise_bank_w[1] = ((gdcreg[0xa] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise_bank_r[2] = paradise_bank_w[2] = (gdcreg[0x9] & 0x7f) << 12; - paradise_bank_r[3] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->read_bank[0] = paradise->write_bank[0] = (svga->gdcreg[0xa] & 0x7f) << 12; + paradise->read_bank[1] = paradise->write_bank[1] = ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->read_bank[2] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; + paradise->read_bank[3] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); } } else { // pclog("Remap 4\n"); - paradise_bank_r[0] = paradise_bank_r[2] = (gdcreg[0x9] & 0x7f) << 12; - paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise_bank_w[0] = paradise_bank_w[2] = (gdcreg[0x9] & 0x7f) << 12; - paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; + paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; + paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); } -// pclog("Remap - %04X %04X\n", paradise_bank_r[0], paradise_bank_w[0]); +// pclog("Remap - %04X %04X\n", paradise->read_bank[0], paradise->write_bank[0]); } -void paradise_recalctimings() +void paradise_recalctimings(svga_t *svga) { - svga_lowres = !(gdcreg[0xe] & 0x01); + svga->lowres = !(svga->gdcreg[0xe] & 0x01); + if (svga->bpp == 8 && !svga->lowres) + svga->render = svga_render_8bpp_highres; } #define egacycles 1 #define egacycles2 1 -void paradise_write(uint32_t addr, uint8_t val, void *priv) +void paradise_write(uint32_t addr, uint8_t val, void *p) { + paradise_t *paradise = (paradise_t *)p; // pclog("paradise_write : %05X %02X ", addr, val); - addr = (addr & 0x7fff) + paradise_bank_w[(addr >> 15) & 3]; + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; // pclog("%08X\n", addr); - svga_write_linear(addr, val, priv); + svga_write_linear(addr, val, ¶dise->svga); } -uint8_t paradise_read(uint32_t addr, void *priv) +uint8_t paradise_read(uint32_t addr, void *p) { + paradise_t *paradise = (paradise_t *)p; // pclog("paradise_read : %05X ", addr); - addr = (addr & 0x7fff) + paradise_bank_r[(addr >> 15) & 3]; + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; // pclog("%08X\n", addr); - return svga_read_linear(addr, priv); + return svga_read_linear(addr, ¶dise->svga); } -int paradise_init() +void *paradise_pvga1a_init() { - if (romset == ROM_PC2086 || romset == ROM_PC3086) - { - paradise_type = PVGA1A; - vrammask = 0x3ffff; - pclog("Init PVGA1A\n"); - svga_vram_limit = 1 << 18; /*256kb*/ - } - if (romset == ROM_MEGAPC) - { - paradise_type = WD90C11; - vrammask = 0x7ffff; - crtc[0x36] = '1'; - crtc[0x37] = '1'; - pclog("Init WD90C11\n"); - svga_vram_limit = 1 << 19; /*512kb*/ - } - crtc[0x31] = 'W'; - crtc[0x32] = 'D'; - crtc[0x33] = '9'; - crtc[0x34] = '0'; - crtc[0x35] = 'C'; - svga_recalctimings_ex = paradise_recalctimings; - return svga_init(); + paradise_t *paradise = malloc(sizeof(paradise_t)); + svga_t *svga = ¶dise->svga; + memset(paradise, 0, sizeof(paradise_t)); + + io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + + svga_init(¶dise->svga, paradise, 1 << 18, /*256kb*/ + NULL, + paradise_in, paradise_out, + NULL); + + svga->crtc[0x31] = 'W'; + svga->crtc[0x32] = 'D'; + svga->crtc[0x33] = '9'; + svga->crtc[0x34] = '0'; + svga->crtc[0x35] = 'C'; + + svga->bpp = 8; + svga->miscout = 1; + + paradise->type = PVGA1A; + + return paradise; } -GFXCARD vid_paradise = +void *paradise_wd90c11_init() { - paradise_init, - /*IO at 3Cx/3Dx*/ - paradise_out, - paradise_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, + paradise_t *paradise = malloc(sizeof(paradise_t)); + svga_t *svga = ¶dise->svga; + memset(paradise, 0, sizeof(paradise_t)); + + io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - svga_poll, - svga_recalctimings, + svga_init(¶dise->svga, paradise, 1 << 19, /*512kb*/ + paradise_recalctimings, + paradise_in, paradise_out, + NULL); - paradise_write, - video_write_null, - video_write_null, + svga->crtc[0x31] = 'W'; + svga->crtc[0x32] = 'D'; + svga->crtc[0x33] = '9'; + svga->crtc[0x34] = '0'; + svga->crtc[0x35] = 'C'; + svga->crtc[0x36] = '1'; + svga->crtc[0x37] = '1'; - paradise_read, - video_read_null, - video_read_null + svga->bpp = 8; + svga->miscout = 1; + + paradise->type = WD90C11; + + return paradise; +} + +void paradise_close(void *p) +{ + paradise_t *paradise = (paradise_t *)p; + + svga_close(¶dise->svga); + + free(paradise); +} + +void paradise_speed_changed(void *p) +{ + paradise_t *paradise = (paradise_t *)p; + + svga_recalctimings(¶dise->svga); +} + +device_t paradise_pvga1a_device = +{ + "Paradise PVGA1A", + paradise_pvga1a_init, + paradise_close, + paradise_speed_changed, + svga_add_status_info +}; +device_t paradise_wd90c11_device = +{ + "Paradise WD90C11", + paradise_wd90c11_init, + paradise_close, + paradise_speed_changed, + svga_add_status_info }; diff --git a/src/vid_paradise.h b/src/vid_paradise.h new file mode 100644 index 0000000..b791d46 --- /dev/null +++ b/src/vid_paradise.h @@ -0,0 +1,2 @@ +extern device_t paradise_pvga1a_device; +extern device_t paradise_wd90c11_device; diff --git a/src/vid_pc1512.c b/src/vid_pc1512.c index de0c01e..918cd11 100644 --- a/src/vid_pc1512.c +++ b/src/vid_pc1512.c @@ -6,263 +6,289 @@ The Technical Reference Manual lists the video waitstate time as between 12 and 46 cycles. PCem currently always uses the lower number.*/ - +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "timer.h" #include "video.h" -#include "vid_cga.h" +#include "vid_pc1512.h" -static uint8_t pc1512_plane_write,pc1512_plane_read,pc1512_border; - -void pc1512_recalctimings(); - -void pc1512_out(uint16_t addr, uint8_t val, void *priv) +typedef struct pc1512_t { + uint8_t crtc[32]; + int crtcreg; + + uint8_t cgacol, cgamode, stat; + + uint8_t plane_write, plane_read, border; + + int linepos, displine; + int sc, vc; + int cgadispon; + int con, coff, cursoron, cgablink; + int vsynctime, vadj; + uint16_t ma, maback; + int dispon; + int blink; + + int dispontime, dispofftime, vidtime; + int firstline, lastline; + + uint8_t *vram; +} pc1512_t; + +static uint8_t crtcmask[32] = +{ + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static void pc1512_recalctimings(pc1512_t *pc1512); + +static void pc1512_out(uint16_t addr, uint8_t val, void *p) +{ + pc1512_t *pc1512 = (pc1512_t *)p; uint8_t old; -// pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc); + pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc); switch (addr) { - case 0x3D4: - crtcreg=val&31; + case 0x3d4: + pc1512->crtcreg = val & 31; return; - case 0x3D5: - old=crtc[crtcreg]; - crtc[crtcreg]=val&crtcmask[crtcreg]; - if (old!=val) + case 0x3d5: + old = pc1512->crtc[pc1512->crtcreg]; + pc1512->crtc[pc1512->crtcreg] = val & crtcmask[pc1512->crtcreg]; + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (pc1512->crtcreg < 0xe || pc1512->crtcreg > 0x10) { - fullchange=changeframecount; - pc1512_recalctimings(); + fullchange = changeframecount; + pc1512_recalctimings(pc1512); } } return; - case 0x3D8: - if ((val&0x12)==0x12 && (cgamode&0x12)!=0x12) + case 0x3d8: + if ((val & 0x12) == 0x12 && (pc1512->cgamode & 0x12) != 0x12) { - pc1512_plane_write=0xF; - pc1512_plane_read =0; + pc1512->plane_write = 0xf; + pc1512->plane_read = 0; } - cgamode=val; + pc1512->cgamode = val; return; - case 0x3D9: - cgacol=val; + case 0x3d9: + pc1512->cgacol = val; return; - case 0x3DD: - pc1512_plane_write=val; + case 0x3dd: + pc1512->plane_write = val; return; - case 0x3DE: - pc1512_plane_read=val&3; + case 0x3de: + pc1512->plane_read = val & 3; return; - case 0x3DF: - pc1512_border=val; + case 0x3df: + pc1512->border = val; return; } } -uint8_t pc1512_in(uint16_t addr, void *priv) +static uint8_t pc1512_in(uint16_t addr, void *p) { + pc1512_t *pc1512 = (pc1512_t *)p; // pclog("PC1512 in %04X %02X %04X:%04X\n",addr,CS,pc); switch (addr) { - case 0x3D4: - return crtcreg; - case 0x3D5: - return crtc[crtcreg]; - case 0x3DA: - return cgastat; + case 0x3d4: + return pc1512->crtcreg; + case 0x3d5: + return pc1512->crtc[pc1512->crtcreg]; + case 0x3da: + return pc1512->stat; } - return 0xFF; + return 0xff; } -void pc1512_write(uint32_t addr, uint8_t val, void *priv) +static void pc1512_write(uint32_t addr, uint8_t val, void *p) { -/* if (CS==0x023E && pc==0x524E) + pc1512_t *pc1512 = (pc1512_t *)p; + + cycles -= 12; + addr &= 0x3fff; + + if ((pc1512->cgamode & 0x12) == 0x12) { - dumpregs(); - exit(-1); - } - pclog("PC1512 write %08X %02X %02X %01X %04X:%04X\n",addr,val,cgamode&0x12,pc1512_plane_write,CS,pc);*/ - cycles-=12; - addr&=0x7FFF; - if ((cgamode&0x12)==0x12) - { - if (pc1512_plane_write&1) vram[addr]=val; - if (pc1512_plane_write&2) vram[addr|0x10000]=val; - if (pc1512_plane_write&4) vram[addr|0x20000]=val; - if (pc1512_plane_write&8) vram[addr|0x30000]=val; + if (pc1512->plane_write & 1) pc1512->vram[addr] = val; + if (pc1512->plane_write & 2) pc1512->vram[addr | 0x4000] = val; + if (pc1512->plane_write & 4) pc1512->vram[addr | 0x8000] = val; + if (pc1512->plane_write & 8) pc1512->vram[addr | 0xc000] = val; } else - vram[addr]=val; + pc1512->vram[addr] = val; } -uint8_t pc1512_read(uint32_t addr, void *priv) +static uint8_t pc1512_read(uint32_t addr, void *p) { -// pclog("PC1512 read %08X %02X %01X\n",addr,cgamode&0x12,pc1512_plane_read); - cycles-=12; - addr&=0x7FFF; - if ((cgamode&0x12)==0x12) - return vram[addr|(pc1512_plane_read<<16)]; - return vram[addr]; + pc1512_t *pc1512 = (pc1512_t *)p; + + cycles -= 12; + addr &= 0x3fff; + + if ((pc1512->cgamode & 0x12) == 0x12) + return pc1512->vram[addr | (pc1512->plane_read << 14)]; + return pc1512->vram[addr]; } -static int linepos,displine; -static int sc,vc; -static int cgadispon; -static int con,coff,cursoron,cgablink; -static int vsynctime,vadj; -static uint16_t ma,maback; - -int i_filt[8],q_filt[8]; - - -void pc1512_recalctimings() +static void pc1512_recalctimings(pc1512_t *pc1512) { - double _dispontime, _dispofftime; + double _dispontime, _dispofftime, disptime; disptime = 128; /*Fixed on PC1512*/ _dispontime = 80; - _dispofftime=disptime-_dispontime; + _dispofftime = disptime - _dispontime; // printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); - _dispontime*=CGACONST; - _dispofftime*=CGACONST; + _dispontime *= CGACONST; + _dispofftime *= CGACONST; // printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); - dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + pc1512->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + pc1512->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } -void pc1512_poll() +static void pc1512_poll(void *p) { - uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF; + pc1512_t *pc1512 = (pc1512_t *)p; + uint16_t ca = (pc1512->crtc[15] | (pc1512->crtc[14] << 8)) & 0x3fff; int drawcursor; - int x,c; + int x, c; int oldvc; - uint8_t chr,attr; - uint16_t dat,dat2,dat3,dat4; + uint8_t chr, attr; + uint16_t dat, dat2, dat3, dat4; int cols[4]; int col; int oldsc; - if (!linepos) + if (!pc1512->linepos) { - vidtime+=dispofftime; - cgastat|=1; - linepos=1; - oldsc=sc; - if (cgadispon) + pc1512->vidtime += pc1512->dispofftime; + pc1512->stat |= 1; + pc1512->linepos = 1; + oldsc = pc1512->sc; + if (pc1512->dispon) { - if (displinedispline < pc1512->firstline) + pc1512->firstline = pc1512->displine; + pc1512->lastline = pc1512->displine; + for (c = 0; c < 8; c++) { - if ((cgamode&0x12)==0x12) + if ((pc1512->cgamode & 0x12) == 0x12) { - buffer->line[displine][c]=(pc1512_border&15)+16; - if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0; - else buffer->line[displine][c+(crtc[1]<<4)+8]=0; + buffer->line[pc1512->displine][c] = (pc1512->border & 15) + 16; + if (pc1512->cgamode & 1) buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 3) + 8] = 0; + else buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 4) + 8] = 0; } else { - buffer->line[displine][c]=(cgacol&15)+16; - if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16; - else buffer->line[displine][c+(crtc[1]<<4)+8]=(cgacol&15)+16; + buffer->line[pc1512->displine][c] = (pc1512->cgacol & 15) + 16; + if (pc1512->cgamode & 1) buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 3) + 8] = (pc1512->cgacol & 15) + 16; + else buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 4) + 8] = (pc1512->cgacol & 15) + 16; } } - if (cgamode&1) + if (pc1512->cgamode & 1) { for (x = 0; x < 80; x++) { - chr=vram[((ma<<1)&0x3FFF)]; - attr=vram[(((ma<<1)+1)&0x3FFF)]; - drawcursor=((ma==ca) && con && cursoron); - if (cgamode&0x20) + chr = pc1512->vram[ ((pc1512->ma << 1) & 0x3fff)]; + attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)]; + drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron); + if (pc1512->cgamode & 0x20) { - cols[1]=(attr&15)+16; - cols[0]=((attr>>4)&7)+16; - if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0]; + cols[1] = (attr & 15) + 16; + cols[0] = ((attr >> 4) & 7) + 16; + if ((pc1512->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; } else { - cols[1]=(attr&15)+16; - cols[0]=(attr>>4)+16; + cols[1] = (attr & 15) + 16; + cols[0] = (attr >> 4) + 16; } if (drawcursor) { - for (c=0;c<8;c++) - buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15; + for (c = 0; c < 8; c++) + buffer->line[pc1512->displine][(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { - for (c=0;c<8;c++) - buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]; + for (c = 0; c < 8; c++) + buffer->line[pc1512->displine][(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } - ma++; + pc1512->ma++; } } - else if (!(cgamode&2)) + else if (!(pc1512->cgamode & 2)) { for (x = 0; x < 40; x++) { - chr=vram[((ma<<1)&0x3FFF)]; - attr=vram[(((ma<<1)+1)&0x3FFF)]; - drawcursor=((ma==ca) && con && cursoron); - if (cgamode&0x20) + chr = pc1512->vram[ ((pc1512->ma << 1) & 0x3fff)]; + attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)]; + drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron); + if (pc1512->cgamode & 0x20) { - cols[1]=(attr&15)+16; - cols[0]=((attr>>4)&7)+16; - if ((cgablink&16) && (attr&0x80)) cols[1]=cols[0]; + cols[1] = (attr & 15) + 16; + cols[0] = ((attr >> 4) & 7) + 16; + if ((pc1512->blink & 16) && (attr & 0x80)) + cols[1] = cols[0]; } else { - cols[1]=(attr&15)+16; - cols[0]=(attr>>4)+16; + cols[1] = (attr & 15) + 16; + cols[0] = (attr >> 4) + 16; } - ma++; + pc1512->ma++; if (drawcursor) { - for (c=0;c<8;c++) - buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15; + for (c = 0; c < 8; c++) + buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] = + buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { - for (c=0;c<8;c++) - buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]; + for (c = 0; c < 8; c++) + buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] = + buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } } - else if (!(cgamode&16)) + else if (!(pc1512->cgamode&16)) { - cols[0]=(cgacol&15)|16; - col=(cgacol&16)?24:16; - if (cgamode&4) + cols[0] = (pc1512->cgacol & 15) | 16; + col = (pc1512->cgacol & 16) ? 24 : 16; + if (pc1512->cgamode & 4) { - cols[1]=col|3; - cols[2]=col|4; - cols[3]=col|7; + cols[1] = col | 3; + cols[2] = col | 4; + cols[3] = col | 7; } - else if (cgacol&32) + else if (pc1512->cgacol & 32) { - cols[1]=col|3; - cols[2]=col|5; - cols[3]=col|7; + cols[1] = col | 3; + cols[2] = col | 5; + cols[3] = col | 7; } else { - cols[1]=col|2; - cols[2]=col|4; - cols[3]=col|6; + cols[1] = col | 2; + cols[2] = col | 4; + cols[3] = col | 6; } for (x = 0; x < 40; x++) { - dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1]; - ma++; - for (c=0;c<8;c++) + dat = (pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000)] << 8) | pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000) + 1]; + pc1512->ma++; + for (c = 0; c < 8; c++) { - buffer->line[displine][(x<<4)+(c<<1)+8]= - buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14]; - dat<<=2; + buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] = + buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + dat <<= 2; } } } @@ -270,169 +296,191 @@ void pc1512_poll() { for (x = 0; x < 40; x++) { - ca=((ma<<1)&0x1FFF)+((sc&1)*0x2000); - dat=(vram[ca]<<8)|vram[ca+1]; - dat2=(vram[ca+0x10000]<<8)|vram[ca+0x10001]; - dat3=(vram[ca+0x20000]<<8)|vram[ca+0x20001]; - dat4=(vram[ca+0x30000]<<8)|vram[ca+0x30001]; + ca = ((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000); + dat = (pc1512->vram[ca] << 8) | pc1512->vram[ca + 1]; + dat2 = (pc1512->vram[ca + 0x4000] << 8) | pc1512->vram[ca + 0x4001]; + dat3 = (pc1512->vram[ca + 0x8000] << 8) | pc1512->vram[ca + 0x8001]; + dat4 = (pc1512->vram[ca + 0xc000] << 8) | pc1512->vram[ca + 0xc001]; - ma++; - for (c=0;c<16;c++) + pc1512->ma++; + for (c = 0; c < 16; c++) { - buffer->line[displine][(x<<4)+c+8]=(((dat>>15)|((dat2>>15)<<1)|((dat3>>15)<<2)|((dat4>>15)<<3))&(cgacol&15))+16; - dat<<=1; - dat2<<=1; - dat3<<=1; - dat4<<=1; + buffer->line[pc1512->displine][(x << 4) + c + 8] = (((dat >> 15) | ((dat2 >> 15) << 1) | ((dat3 >> 15) << 2) | ((dat4 >> 15) << 3)) & (pc1512->cgacol & 15)) + 16; + dat <<= 1; + dat2 <<= 1; + dat3 <<= 1; + dat4 <<= 1; } } } } else { - cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16; - if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]); - else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]); + cols[0] = ((pc1512->cgamode & 0x12) == 0x12) ? 0 : (pc1512->cgacol & 15) + 16; + if (pc1512->cgamode & 1) hline(buffer, 0, pc1512->displine, (pc1512->crtc[1] << 3) + 16, cols[0]); + else hline(buffer, 0, pc1512->displine, (pc1512->crtc[1] << 4) + 16, cols[0]); } - sc=oldsc; - if (vsynctime) - cgastat|=8; - displine++; - if (displine>=360) displine=0; + pc1512->sc = oldsc; + if (pc1512->vsynctime) + pc1512->stat |= 8; + pc1512->displine++; + if (pc1512->displine >= 360) + pc1512->displine = 0; // pclog("Line %i %i %i %i %i %i\n",displine,cgadispon,firstline,lastline,vc,sc); } else { - vidtime+=dispontime; - if ((lastline-firstline)==199) cgadispon=0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/ - if (cgadispon) cgastat&=~1; - linepos=0; - if (vsynctime) + pc1512->vidtime += pc1512->dispontime; + if ((pc1512->lastline - pc1512->firstline) == 199) + pc1512->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/ + if (pc1512->dispon) + pc1512->stat &= ~1; + pc1512->linepos = 0; + if (pc1512->vsynctime) { - vsynctime--; - if (!vsynctime) - cgastat&=~8; + pc1512->vsynctime--; + if (!pc1512->vsynctime) + pc1512->stat &= ~8; } - if (sc==(crtc[11]&31)) { con=0; coff=1; } - if (vadj) + if (pc1512->sc == (pc1512->crtc[11] & 31)) + { + pc1512->con = 0; + pc1512->coff = 1; + } + if (pc1512->vadj) { - sc++; - sc&=31; - ma=maback; - vadj--; - if (!vadj) + pc1512->sc++; + pc1512->sc &= 31; + pc1512->ma = pc1512->maback; + pc1512->vadj--; + if (!pc1512->vadj) { - cgadispon=1; - ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF; - sc=0; + pc1512->dispon = 1; + pc1512->ma = pc1512->maback = (pc1512->crtc[13] | (pc1512->crtc[12] << 8)) & 0x3fff; + pc1512->sc = 0; } } - else if (sc==crtc[9]) + else if (pc1512->sc == pc1512->crtc[9]) { - maback=ma; - sc=0; - oldvc=vc; - vc++; - vc&=127; + pc1512->maback = pc1512->ma; + pc1512->sc = 0; + oldvc = pc1512->vc; + pc1512->vc++; + pc1512->vc &= 127; - if (displine == 32)//oldvc == (cgamode & 2) ? 127 : 31) + if (pc1512->displine == 32)//oldvc == (cgamode & 2) ? 127 : 31) { - vc=0; - vadj=6; - if ((crtc[10]&0x60)==0x20) cursoron=0; - else cursoron=cgablink&16; + pc1512->vc = 0; + pc1512->vadj = 6; + if ((pc1512->crtc[10] & 0x60) == 0x20) pc1512->cursoron = 0; + else pc1512->cursoron = pc1512->blink & 16; } - if (displine >= 262)//vc == (cgamode & 2) ? 111 : 27) + if (pc1512->displine >= 262)//vc == (cgamode & 2) ? 111 : 27) { - cgadispon=0; - displine=0; - vsynctime=46; + pc1512->dispon = 0; + pc1512->displine = 0; + pc1512->vsynctime = 46; - if (cgamode&1) x=(crtc[1]<<3)+16; - else x=(crtc[1]<<4)+16; - x = 640 + 16; - lastline++; - if (x!=xsize || (lastline-firstline)!=ysize) - { - xsize=x; - ysize=lastline-firstline; - if (xsize<64) xsize=656; - if (ysize<32) ysize=200; - updatewindowsize(xsize,(ysize<<1)+16); - } + if (pc1512->cgamode&1) x = (pc1512->crtc[1] << 3) + 16; + else x = (pc1512->crtc[1] << 4) + 16; + x = 640 + 16; + pc1512->lastline++; + + if (x != xsize || (pc1512->lastline - pc1512->firstline) != ysize) + { + xsize = x; + ysize = pc1512->lastline - pc1512->firstline; + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + updatewindowsize(xsize, (ysize << 1) + 16); + } startblit(); - video_blit_memtoscreen_8(0, firstline - 4, xsize, (lastline - firstline) + 8); + video_blit_memtoscreen_8(0, pc1512->firstline - 4, xsize, (pc1512->lastline - pc1512->firstline) + 8); // blit(buffer,vbuf,0,firstline-4,0,0,xsize,(lastline-firstline)+8+1); // if (vid_resize) stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,winsizex,winsizey); // else stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,xsize,((lastline-firstline)<<1)+16+2); // if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF); // readflash=0; endblit(); - video_res_x = xsize - 16; - video_res_y = ysize; - if (cgamode & 1) - { - video_res_x /= 8; - video_res_y /= crtc[9] + 1; - video_bpp = 0; - } - else if (!(cgamode & 2)) - { - video_res_x /= 16; - video_res_y /= crtc[9] + 1; - video_bpp = 0; - } - else if (!(cgamode&16)) - { - video_res_x /= 2; - video_bpp = 2; - } - else - { - video_bpp = 4; - } + video_res_x = xsize - 16; + video_res_y = ysize; + if (pc1512->cgamode & 1) + { + video_res_x /= 8; + video_res_y /= pc1512->crtc[9] + 1; + video_bpp = 0; + } + else if (!(pc1512->cgamode & 2)) + { + video_res_x /= 16; + video_res_y /= pc1512->crtc[9] + 1; + video_bpp = 0; + } + else if (!(pc1512->cgamode & 16)) + { + video_res_x /= 2; + video_bpp = 2; + } + else + { + video_bpp = 4; + } - firstline=1000; - lastline=0; - cgablink++; + pc1512->firstline = 1000; + pc1512->lastline = 0; + pc1512->blink++; } } else { - sc++; - sc&=31; - ma=maback; + pc1512->sc++; + pc1512->sc &= 31; + pc1512->ma = pc1512->maback; } - if (sc==(crtc[10]&31)) con=1; + if (pc1512->sc == (pc1512->crtc[10] & 31)) + pc1512->con = 1; } } -int pc1512_init() +static void *pc1512_init() { - mem_sethandler(0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, NULL); - return 0; + int c; + pc1512_t *pc1512 = malloc(sizeof(pc1512_t)); + memset(pc1512, 0, sizeof(pc1512_t)); + + pc1512->vram = malloc(0x10000); + + pc1512->cgacol = 7; + pc1512->cgamode = 0x12; + + timer_add(pc1512_poll, &pc1512->vidtime, TIMER_ALWAYS_ENABLED, pc1512); + mem_sethandler(0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, pc1512); + io_sethandler(0x03d0, 0x0010, pc1512_in, NULL, NULL, pc1512_out, NULL, NULL, pc1512); + return pc1512; } -GFXCARD vid_pc1512 = +static void pc1512_close(void *p) { + pc1512_t *pc1512 = (pc1512_t *)p; + + free(pc1512->vram); + free(pc1512); +} + +static void pc1512_speed_changed(void *p) +{ + pc1512_t *pc1512 = (pc1512_t *)p; + + pc1512_recalctimings(pc1512); +} + +device_t pc1512_device = +{ + "Amstrad PC1512 (video)", pc1512_init, - /*IO at 3Cx/3Dx*/ - pc1512_out, - pc1512_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - pc1512_poll, - pc1512_recalctimings, - - video_write_null, - video_write_null, - pc1512_write, - - video_read_null, - video_read_null, - pc1512_read + pc1512_close, + pc1512_speed_changed, + NULL }; diff --git a/src/vid_pc1512.h b/src/vid_pc1512.h new file mode 100644 index 0000000..b026c89 --- /dev/null +++ b/src/vid_pc1512.h @@ -0,0 +1 @@ +extern device_t pc1512_device; diff --git a/src/vid_pc1640.c b/src/vid_pc1640.c index 7b5888e..b49bda4 100644 --- a/src/vid_pc1640.c +++ b/src/vid_pc1640.c @@ -1,99 +1,145 @@ /*PC1640 video emulation. Mostly standard EGA, but with CGA & Hercules emulation*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" +#include "timer.h" #include "video.h" #include "vid_cga.h" #include "vid_ega.h" +#include "vid_pc1640.h" -static int pc1640_cga=1; - -void pc1640_out(uint16_t addr, uint8_t val, void *priv) +typedef struct pc1640_t { + cga_t cga; + ega_t ega; + + int cga_enabled; + int dispontime, dispofftime, vidtime; +} pc1640_t; + +void pc1640_out(uint16_t addr, uint8_t val, void *p) +{ + pc1640_t *pc1640 = (pc1640_t *)p; + switch (addr) { - case 0x3DB: - pc1640_cga=val&0x40; - mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); - mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL); - if (pc1640_cga) - mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL); + case 0x3db: + pc1640->cga_enabled = val & 0x40; + mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega); + mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, &pc1640->cga); + if (pc1640->cga_enabled) + mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, &pc1640->cga); else { - switch (gdcreg[6] & 0xC) + switch (pc1640->ega.gdcreg[6] & 0xc) { case 0x0: /*128k at A0000*/ - mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); + mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega); break; case 0x4: /*64k at A0000*/ - mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); + mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega); break; case 0x8: /*32k at B0000*/ - mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); + mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega); break; case 0xC: /*32k at B8000*/ - mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); + mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega); break; } } pclog("3DB write %02X\n", val); return; } - if (pc1640_cga) cga_out(addr, val, NULL); - else ega_out(addr, val, NULL); + if (pc1640->cga_enabled) cga_out(addr, val, &pc1640->cga); + else ega_out(addr, val, &pc1640->ega); } -uint8_t pc1640_in(uint16_t addr, void *priv) +uint8_t pc1640_in(uint16_t addr, void *p) { + pc1640_t *pc1640 = (pc1640_t *)p; + switch (addr) { } - if (pc1640_cga) return cga_in(addr, NULL); - else return ega_in(addr, NULL); -} - -void pc1640_recalctimings() -{ - if (pc1640_cga) cga_recalctimings(); - else ega_recalctimings(); -} - -void pc1640_poll() -{ - if (pc1640_cga) cga_poll(); - else ega_poll(); -} - -int pc1640_init() -{ - int r = ega_init(); - pc1640_cga = 1; - - mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL); - - return r; + if (pc1640->cga_enabled) return cga_in(addr, &pc1640->cga); + else return ega_in(addr, &pc1640->ega); } -GFXCARD vid_pc1640 = +void pc1640_recalctimings(pc1640_t *pc1640) { + if (pc1640->cga_enabled) + { + cga_recalctimings(&pc1640->cga); + pc1640->dispontime = pc1640->cga.dispontime; + pc1640->dispofftime = pc1640->cga.dispofftime; + } + else + { + ega_recalctimings(&pc1640->ega); + pc1640->dispontime = pc1640->ega.dispontime; + pc1640->dispofftime = pc1640->ega.dispofftime; + } +} + +void pc1640_poll(void *p) +{ + pc1640_t *pc1640 = (pc1640_t *)p; + if (pc1640->cga_enabled) + { + pc1640->cga.vidtime = pc1640->vidtime; + cga_poll(&pc1640->cga); + pc1640->vidtime = pc1640->cga.vidtime; + } + else + { + pc1640->ega.vidtime = pc1640->vidtime; + ega_poll(&pc1640->ega); + pc1640->vidtime = pc1640->ega.vidtime; + } +} + +void *pc1640_init() +{ + pc1640_t *pc1640 = malloc(sizeof(pc1640_t)); + cga_t *cga = &pc1640->cga; + ega_t *ega = &pc1640->ega; + memset(pc1640, 0, sizeof(pc1640_t)); + + ega_init(&pc1640->ega); + pc1640->cga.vram = pc1640->ega.vram; + pc1640->cga_enabled = 1; + cga_init(&pc1640->cga); + + timer_add(pc1640_poll, &pc1640->vidtime, TIMER_ALWAYS_ENABLED, pc1640); + mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, cga); + io_sethandler(0x03a0, 0x0040, pc1640_in, NULL, NULL, pc1640_out, NULL, NULL, pc1640); + return cga; +} + +void pc1640_close(void *p) +{ + pc1640_t *pc1640 = (pc1640_t *)p; + + free(pc1640->ega.vram); + free(pc1640); +} + +void pc1640_speed_changed(void *p) +{ + pc1640_t *pc1640 = (pc1640_t *)p; + + pc1640_recalctimings(pc1640); +} + +device_t pc1640_device = +{ + "Amstrad PC1640 (video)", pc1640_init, - /*IO at 3Cx/3Dx*/ - pc1640_out, - pc1640_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - pc1640_poll, - pc1640_recalctimings, - - ega_write, - video_write_null, - video_write_null, - - ega_read, - video_read_null, - video_read_null + pc1640_close, + pc1640_speed_changed, + NULL }; diff --git a/src/vid_pc1640.h b/src/vid_pc1640.h new file mode 100644 index 0000000..ccbf83d --- /dev/null +++ b/src/vid_pc1640.h @@ -0,0 +1 @@ +extern device_t pc1640_device; diff --git a/src/vid_pc200.c b/src/vid_pc200.c index d37b904..ce478b5 100644 --- a/src/vid_pc200.c +++ b/src/vid_pc200.c @@ -1,104 +1,139 @@ /*PC200 video emulation. CGA with some NMI stuff. But we don't need that as it's only used for TV and LCD displays, and we're emulating a CRT*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" +#include "timer.h" #include "video.h" #include "vid_cga.h" +#include "vid_pc200.h" -uint8_t pc200_3dd, pc200_3de, pc200_3df; - -void pc200_out(uint16_t addr, uint8_t val, void *priv) +typedef struct pc200_t { + cga_t cga; + + uint8_t reg_3dd, reg_3de, reg_3df; +} pc200_t; + +static uint8_t crtcmask[32] = +{ + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +void pc200_out(uint16_t addr, uint8_t val, void *p) +{ + pc200_t *pc200 = (pc200_t *)p; + cga_t *cga = &pc200->cga; uint8_t old; + switch (addr) { - case 0x3D5: - if (!(pc200_3de&0x40) && crtcreg<=11) + case 0x3d5: + if (!(pc200->reg_3de & 0x40) && cga->crtcreg <= 11) { - if (pc200_3de&0x80) nmi=1; - pc200_3dd=0x20|(crtcreg&0x1F); - pc200_3df=val; + if (pc200->reg_3de & 0x80) + nmi = 1; + + pc200->reg_3dd = 0x20 | (cga->crtcreg & 0x1f); + pc200->reg_3df = val; return; } - old=crtc[crtcreg]; - crtc[crtcreg]=val&crtcmask[crtcreg]; - if (old!=val) + old = cga->crtc[cga->crtcreg]; + cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (cga->crtcreg < 0xe || cga->crtcreg > 0x10) { - fullchange=changeframecount; - cga_recalctimings(); + fullchange = changeframecount; + cga_recalctimings(cga); } } return; - case 0x3D8: - old = cgamode; - cgamode=val; - if ((cgamode ^ old) & 3) - cga_recalctimings(); - pc200_3dd|=0x80; - if (pc200_3de&0x80) - nmi=1; + case 0x3d8: + old = cga->cgamode; + cga->cgamode = val; + if ((cga->cgamode ^ old) & 3) + cga_recalctimings(cga); + pc200->reg_3dd |= 0x80; + if (pc200->reg_3de & 0x80) + nmi = 1; return; - case 0x3DE: - pc200_3de=val; - pc200_3dd=0x1F; - if (val&0x80) pc200_3dd|=0x40; + case 0x3de: + pc200->reg_3de = val; + pc200->reg_3dd = 0x1f; + if (val & 0x80) + pc200->reg_3dd |= 0x40; return; } - cga_out(addr, val, NULL); + cga_out(addr, val, cga); } -uint8_t pc200_in(uint16_t addr, void *priv) +uint8_t pc200_in(uint16_t addr, void *p) { + pc200_t *pc200 = (pc200_t *)p; + cga_t *cga = &pc200->cga; uint8_t temp; + switch (addr) { case 0x3D8: - return cgamode; + return cga->cgamode; case 0x3DD: - temp = pc200_3dd; - pc200_3dd &= 0x1F; + temp = pc200->reg_3dd; + pc200->reg_3dd &= 0x1f; return temp; case 0x3DE: - return (pc200_3de&0xC7)| 0x18; /*External CGA*/ + return (pc200->reg_3de & 0xc7) | 0x18; /*External CGA*/ case 0x3DF: - return pc200_3df; + return pc200->reg_3df; } - return cga_in(addr, NULL); + return cga_in(addr, cga); } -int pc200_init() +void *pc200_init() { - mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL); - return cga_init(); + pc200_t *pc200 = malloc(sizeof(pc200_t)); + cga_t *cga = &pc200->cga; + memset(pc200, 0, sizeof(pc200_t)); + + pc200->cga.vram = malloc(0x4000); + cga_init(&pc200->cga); + + timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); + mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, cga); + io_sethandler(0x03d0, 0x0010, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200); + return cga; } -GFXCARD vid_pc200 = +void pc200_close(void *p) { + pc200_t *pc200 = (pc200_t *)p; + + free(pc200->cga.vram); + free(pc200); +} + +void pc200_speed_changed(void *p) +{ + pc200_t *pc200 = (pc200_t *)p; + + cga_recalctimings(&pc200->cga); +} + +device_t pc200_device = +{ + "Amstrad PC200 (video)", pc200_init, - /*IO at 3Cx/3Dx*/ - pc200_out, - pc200_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - cga_poll, - cga_recalctimings, - - video_write_null, - video_write_null, - cga_write, - - video_read_null, - video_read_null, - cga_read + pc200_close, + pc200_speed_changed, + NULL }; diff --git a/src/vid_pc200.h b/src/vid_pc200.h new file mode 100644 index 0000000..4b43090 --- /dev/null +++ b/src/vid_pc200.h @@ -0,0 +1 @@ +extern device_t pc200_device; diff --git a/src/vid_s3.c b/src/vid_s3.c index 7e54dbc..e2433de 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -1,120 +1,172 @@ /*S3 emulation*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "pci.h" #include "video.h" +#include "vid_s3.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_sdac_ramdac.h" +typedef struct s3_t +{ + svga_t svga; + sdac_ramdac_t ramdac; + + uint8_t bank; + uint8_t ma_ext; + int width; + int bpp; + + uint8_t id, id_ext; + + uint32_t linear_base, linear_size; + + struct + { + uint8_t subsys_cntl; + uint8_t setup_md; + uint8_t advfunc_cntl; + uint16_t cur_y; + uint16_t cur_x; + int16_t desty_axstp; + int16_t destx_distp; + int16_t err_term; + int16_t maj_axis_pcnt; + uint16_t cmd; + uint16_t short_stroke; + uint32_t bkgd_color; + uint32_t frgd_color; + uint32_t wrt_mask; + uint32_t rd_mask; + uint32_t color_cmp; + uint8_t bkgd_mix; + uint8_t frgd_mix; + uint16_t multifunc_cntl; + uint16_t multifunc[16]; + uint8_t pix_trans[4]; + + int cx, cy; + int sx, sy; + int dx, dy; + uint32_t src, dest, pattern; + int pix_trans_count; + + uint32_t dat_buf; + int dat_count; + } accel; +} s3_t; + void s3_updatemapping(); -void s3_accel_write(uint32_t addr, uint8_t val, void *priv); -void s3_accel_write_w(uint32_t addr, uint16_t val, void *priv); -void s3_accel_write_l(uint32_t addr, uint32_t val, void *priv); -uint8_t s3_accel_read(uint32_t addr, void *priv); +void s3_accel_write(uint32_t addr, uint8_t val, void *p); +void s3_accel_write_w(uint32_t addr, uint16_t val, void *p); +void s3_accel_write_l(uint32_t addr, uint32_t val, void *p); +uint8_t s3_accel_read(uint32_t addr, void *p); -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_id, s3_id_ext; - -void s3_out(uint16_t addr, uint8_t val, void *priv) +void s3_out(uint16_t addr, uint8_t val, void *p) { + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; uint8_t old; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; // pclog("S3 out %04X %02X\n", addr, val); switch (addr) { case 0x3c5: - if (seqaddr == 4) /*Chain-4 - update banking*/ + if (svga->seqaddr == 4) /*Chain-4 - update banking*/ { - if (val & 8) svgawbank = svgarbank = s3_bank << 16; - else svgawbank = svgarbank = s3_bank << 14; + if (val & 8) svga->write_bank = svga->read_bank = s3->bank << 16; + else svga->write_bank = svga->read_bank = s3->bank << 14; } break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: // pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); - sdac_ramdac_out(addr, val, NULL); + sdac_ramdac_out(addr, val, &s3->ramdac, svga); return; case 0x3D4: - crtcreg=val&0x7f; + svga->crtcreg = val & 0x7f; return; case 0x3D5: // if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val); - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - if (crtcreg >= 0x20 && crtcreg != 0x38 && (crtc[0x38] & 0xcc) != 0x48) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; - switch (crtcreg) + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; + if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + switch (svga->crtcreg) { case 0x31: - s3_ma_ext = (s3_ma_ext & 0x1c) | ((val & 0x30) >> 4); - vrammask = (val & 8) ? 0x3fffff : 0x3ffff; + s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); + svga->vrammask = (val & 8) ? 0x3fffff : 0x3ffff; break; case 0x50: - switch (crtc[0x50] & 0xc1) + switch (svga->crtc[0x50] & 0xc1) { - case 0x00: s3_width = (crtc[0x31] & 2) ? 2048 : 1024; break; - case 0x01: s3_width = 1152; break; - case 0x40: s3_width = 640; break; - case 0x80: s3_width = 800; break; - case 0x81: s3_width = 1600; break; - case 0xc0: s3_width = 1280; break; + case 0x00: s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; break; + case 0x01: s3->width = 1152; break; + case 0x40: s3->width = 640; break; + case 0x80: s3->width = 800; break; + case 0x81: s3->width = 1600; break; + case 0xc0: s3->width = 1280; break; } - s3_bpp = (crtc[0x50] >> 4) & 3; + s3->bpp = (svga->crtc[0x50] >> 4) & 3; break; case 0x69: - s3_ma_ext = val & 0x1f; + s3->ma_ext = val & 0x1f; break; case 0x35: - s3_bank = (s3_bank & 0x70) | (val & 0xf); + s3->bank = (s3->bank & 0x70) | (val & 0xf); // pclog("CRTC write R35 %02X\n", val); - if (chain4) svgawbank = svgarbank = s3_bank << 16; - else svgawbank = svgarbank = s3_bank << 14; + if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; + else svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x51: - s3_bank = (s3_bank & 0x4f) | ((val & 0xc) << 2); - if (chain4) svgawbank = svgarbank = s3_bank << 16; - else svgawbank = svgarbank = s3_bank << 14; - s3_ma_ext = (s3_ma_ext & ~0xc) | ((val & 3) << 2); + s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2); + if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; + else svga->write_bank = svga->read_bank = s3->bank << 14; + s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); break; case 0x6a: - s3_bank = val; + s3->bank = val; // pclog("CRTC write R6a %02X\n", val); - if (chain4) svgawbank = svgarbank = s3_bank << 16; - else svgawbank = svgarbank = s3_bank << 14; + if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; + else svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x3a: - if (val & 0x10) gdcreg[5] |= 0x40; /*Horrible cheat*/ + if (val & 0x10) + svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ break; case 0x45: - svga_hwcursor.ena = val & 1; + svga->hwcursor.ena = val & 1; break; case 0x48: - svga_hwcursor.x = ((crtc[0x46] << 8) | crtc[0x47]) & 0x7ff; - if (bpp == 32) svga_hwcursor.x >>= 1; - svga_hwcursor.y = ((crtc[0x48] << 8) | crtc[0x49]) & 0x7ff; - svga_hwcursor.xoff = crtc[0x4e] & 63; - svga_hwcursor.yoff = crtc[0x4f] & 63; - svga_hwcursor.addr = ((((crtc[0x4c] << 8) | crtc[0x4d]) & 0xfff) * 1024) + (svga_hwcursor.yoff * 16); + svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; + if (svga->bpp == 32) svga->hwcursor.x >>= 1; + svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; + svga->hwcursor.xoff = svga->crtc[0x4e] & 63; + svga->hwcursor.yoff = svga->crtc[0x4f] & 63; + svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); + if (gfxcard == GFX_N9_9FX && svga->bpp == 32) /*Trio64*/ + svga->hwcursor.x <<= 1; break; case 0x53: case 0x58: case 0x59: case 0x5a: - s3_updatemapping(); + s3_updatemapping(s3); break; case 0x67: @@ -122,469 +174,456 @@ void s3_out(uint16_t addr, uint8_t val, void *priv) { switch (val >> 4) { - case 3: bpp = 15; break; - case 5: bpp = 16; break; - case 7: bpp = 24; break; - case 13: bpp = 32; break; - default: bpp = 8; break; + case 3: svga->bpp = 15; break; + case 5: svga->bpp = 16; break; + case 7: svga->bpp = 24; break; + case 13: svga->bpp = 32; break; + default: svga->bpp = 8; break; } } break; //case 0x55: case 0x43: // pclog("Write CRTC R%02X %02X\n", crtcreg, val); } - if (old!=val) + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(svga); } } break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t s3_in(uint16_t addr, void *priv) +uint8_t s3_in(uint16_t addr, void *p) { - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; // if (addr != 0x3da) pclog("S3 in %04X\n", addr); switch (addr) { - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: + case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: // pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); - return sdac_ramdac_in(addr, NULL); + return sdac_ramdac_in(addr, &s3->ramdac, svga); - case 0x3D4: - return crtcreg; - case 0x3D5: + case 0x3d4: + return svga->crtcreg; + case 0x3d5: // pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc); - switch (crtcreg) + switch (svga->crtcreg) { - case 0x2d: return 0x88; /*Extended chip ID*/ - case 0x2e: return s3_id_ext; /*New chip ID*/ - case 0x30: return s3_id; /*Chip ID*/ - case 0x31: return (crtc[0x31] & 0xcf) | ((s3_ma_ext & 3) << 4); - case 0x35: return (crtc[0x35] & 0xf0) | (s3_bank & 0xf); - case 0x51: return (crtc[0x51] & 0xf0) | ((s3_bank >> 2) & 0xc) | ((s3_ma_ext >> 2) & 3); - case 0x69: return s3_ma_ext; - case 0x6a: return s3_bank; + case 0x2d: return 0x88; /*Extended chip ID*/ + case 0x2e: return s3->id_ext; /*New chip ID*/ + case 0x30: return s3->id; /*Chip ID*/ + case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); + case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); + case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); + case 0x69: return s3->ma_ext; + case 0x6a: return s3->bank; } - return crtc[crtcreg]; + return svga->crtc[svga->crtcreg]; } - return svga_in(addr, NULL); + return svga_in(addr, svga); } -void s3_recalctimings() +void s3_recalctimings(svga_t *svga) { + s3_t *s3 = (s3_t *)svga->p; + svga->hdisp = svga->hdisp_old; + + pclog("%i %i\n", svga->hdisp, svga->hdisp_time); // pclog("recalctimings\n"); - svga_ma |= (s3_ma_ext << 16); + svga->ma_latch |= (s3->ma_ext << 16); // pclog("SVGA_MA %08X\n", svga_ma); - if ((gdcreg[5] & 0x40) && (crtc[0x3a] & 0x10)) + if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; + if (svga->crtc[0x5d] & 0x02) { - switch (bpp) + svga->hdisp_time += 0x100; + svga->hdisp += 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + } + if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400; + if (svga->crtc[0x5e] & 0x02) svga->dispend += 0x400; + if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400; + if (svga->crtc[0x5e] & 0x40) svga->split += 0x400; + if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; + else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; + if (!svga->rowoffset) svga->rowoffset = 256; + svga->interlace = svga->crtc[0x42] & 0x20; + svga->clock = cpuclock / sdac_getclock((svga->miscout >> 2) & 3, &s3->ramdac); +// pclog("SVGA_CLOCK = %f %02X %f\n", svga_clock, svga_miscout, cpuclock); + if (svga->bpp > 8) svga->clock /= 2; + + svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) + { + switch (svga->bpp) { case 8: - svga_render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_highres; break; case 15: - svga_render = svga_render_15bpp_highres; + svga->render = svga_render_15bpp_highres; break; case 16: - svga_render = svga_render_16bpp_highres; + svga->render = svga_render_16bpp_highres; break; case 24: - svga_render = svga_render_24bpp_highres; + svga->render = svga_render_24bpp_highres; break; - case 32: - svga_render = svga_render_32bpp_highres; + case 32: + svga->render = svga_render_32bpp_highres; + if (gfxcard == GFX_N9_9FX) /*Trio64*/ + svga->hdisp *= 4; break; } } - if (crtc[0x5d] & 0x01) svga_htotal += 0x100; - if (crtc[0x5d] & 0x02) svga_hdisp += 0x100; - if (crtc[0x5e] & 0x01) svga_vtotal += 0x400; - if (crtc[0x5e] & 0x02) svga_dispend += 0x400; - if (crtc[0x5e] & 0x10) svga_vsyncstart += 0x400; - if (crtc[0x5e] & 0x40) svga_split += 0x400; - if (crtc[0x51] & 0x30) svga_rowoffset += (crtc[0x51] & 0x30) << 4; - else if (crtc[0x43] & 0x04) svga_rowoffset += 0x100; - if (!svga_rowoffset) svga_rowoffset = 256; - svga_interlace = crtc[0x42] & 0x20; - svga_clock = cpuclock / sdac_getclock((svga_miscout >> 2) & 3); -// pclog("SVGA_CLOCK = %f %02X %f\n", svga_clock, svga_miscout, cpuclock); - if (bpp > 8) svga_clock /= 2; + + // if (svga->bpp == 32) svga->hdisp *= 3; + pclog("svga->hdisp %i %02X %i\n", svga->hdisp, svga->crtc[0x5d], svga->hdisp_time); } -static uint32_t s3_linear_base = 0, s3_linear_size = 0; -void s3_updatemapping() +void s3_updatemapping(s3_t *s3) { - 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 = &s3->svga; + + 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, svga); // video_write_a000_w = video_write_a000_l = NULL; - mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); + + mem_removehandler(0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, s3); + // pclog("Update mapping - bank %02X ", gdcreg[6] & 0xc); - switch (gdcreg[6] & 0xc) /*Banked framebuffer*/ + switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ { case 0x0: /*128k at A0000*/ - mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0x4: /*64k at A0000*/ - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0x8: /*32k at B0000*/ - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0xC: /*32k at B8000*/ - mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; } // pclog("Linear framebuffer %02X ", crtc[0x58] & 0x10); - if (crtc[0x58] & 0x10) /*Linear framebuffer*/ + if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ { - s3_linear_base = (crtc[0x5a] << 16) | (crtc[0x59] << 24); - switch (crtc[0x58] & 3) + s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); + switch (svga->crtc[0x58] & 3) { case 0: /*64k*/ - s3_linear_size = 0x10000; + s3->linear_size = 0x10000; break; case 1: /*1mb*/ - s3_linear_size = 0x100000; + s3->linear_size = 0x100000; break; case 2: /*2mb*/ - s3_linear_size = 0x200000; + s3->linear_size = 0x200000; break; case 3: /*8mb*/ - s3_linear_size = 0x800000; + s3->linear_size = 0x800000; break; } - s3_linear_base &= ~(s3_linear_size - 1); + s3->linear_base &= ~(s3->linear_size - 1); // pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]); // pclog("Linear framebuffer at %08X size %08X\n", linear_base, linear_size); - if (s3_linear_base == 0xa0000) - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + if (s3->linear_base == 0xa0000) + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); else - mem_sethandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); + mem_sethandler(s3->linear_base, s3->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] & 0x10); - if (crtc[0x53] & 0x10) /*Memory mapped IO*/ - { - mem_sethandler(0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, NULL); -/* video_write_a000 = s3_accel_write; - video_write_a000_w = s3_accel_write_w; - video_write_a000_l = s3_accel_write_l; - video_read_a000 = s3_accel_read;*/ - } + if (svga->crtc[0x53] & 0x10) /*Memory mapped IO*/ + mem_sethandler(0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, s3); } -struct -{ - uint8_t subsys_cntl; - uint8_t setup_md; - uint8_t advfunc_cntl; - uint16_t cur_y; - uint16_t cur_x; - int16_t desty_axstp; - int16_t destx_distp; - int16_t err_term; - int16_t maj_axis_pcnt; - uint16_t cmd; - uint16_t short_stroke; - uint32_t bkgd_color; - uint32_t frgd_color; - uint32_t wrt_mask; - uint32_t rd_mask; - uint32_t color_cmp; - uint8_t bkgd_mix; - uint8_t frgd_mix; - uint16_t multifunc_cntl; - uint16_t multifunc[16]; - uint8_t pix_trans[4]; - - int cx, cy; - int sx, sy; - int dx, dy; - uint32_t src, dest, pattern; - int pix_trans_count; - - uint32_t dat_buf; - int dat_count; -} s3_accel; +void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); -void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat); - -void s3_accel_out(uint16_t port, uint8_t val, void *priv) +void s3_accel_out(uint16_t port, uint8_t val, void *p) { + s3_t *s3 = (s3_t *)p; // pclog("Accel out %04X %02X\n", port, val); switch (port) { case 0x42e8: break; case 0x42e9: - s3_accel.subsys_cntl = val; + s3->accel.subsys_cntl = val; break; case 0x46e8: - s3_accel.setup_md = val; + s3->accel.setup_md = val; break; case 0x4ae8: - s3_accel.advfunc_cntl = val; + s3->accel.advfunc_cntl = val; break; case 0x82e8: - s3_accel.cur_y = (s3_accel.cur_y & 0xf00) | val; + s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; break; case 0x82e9: - s3_accel.cur_y = (s3_accel.cur_y & 0xff) | ((val & 0x1f) << 8); + s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x1f) << 8); break; case 0x86e8: - s3_accel.cur_x = (s3_accel.cur_x & 0xf00) | val; + s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; break; case 0x86e9: - s3_accel.cur_x = (s3_accel.cur_x & 0xff) | ((val & 0x1f) << 8); + s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x1f) << 8); break; case 0x8ae8: - s3_accel.desty_axstp = (s3_accel.desty_axstp & 0x3f00) | val; + s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; break; case 0x8ae9: - s3_accel.desty_axstp = (s3_accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); + s3->accel.desty_axstp = (s3->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - s3_accel.desty_axstp |= ~0x3fff; + s3->accel.desty_axstp |= ~0x3fff; break; case 0x8ee8: - s3_accel.destx_distp = (s3_accel.destx_distp & 0x3f00) | val; + s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; break; case 0x8ee9: - s3_accel.destx_distp = (s3_accel.destx_distp & 0xff) | ((val & 0x3f) << 8); + s3->accel.destx_distp = (s3->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - s3_accel.destx_distp |= ~0x3fff; + s3->accel.destx_distp |= ~0x3fff; break; case 0x92e8: - s3_accel.err_term = (s3_accel.err_term & 0x3f00) | val; + s3->accel.err_term = (s3->accel.err_term & 0x3f00) | val; break; case 0x92e9: - s3_accel.err_term = (s3_accel.err_term & 0xff) | ((val & 0x3f) << 8); + s3->accel.err_term = (s3->accel.err_term & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - s3_accel.err_term |= ~0x3fff; + s3->accel.err_term |= ~0x3fff; break; case 0x96e8: - s3_accel.maj_axis_pcnt = (s3_accel.maj_axis_pcnt & 0x3f00) | val; + s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0x3f00) | val; break; case 0x96e9: - s3_accel.maj_axis_pcnt = (s3_accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8); + s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8); if (val & 0x08) - s3_accel.maj_axis_pcnt |= ~0x0fff; + s3->accel.maj_axis_pcnt |= ~0x0fff; break; case 0x9ae8: - s3_accel.cmd = (s3_accel.cmd & 0xff00) | val; + s3->accel.cmd = (s3->accel.cmd & 0xff00) | val; break; case 0x9ae9: - s3_accel.cmd = (s3_accel.cmd & 0xff) | (val << 8); - s3_accel_start(-1, 0, 0xffffffff, 0); - s3_accel.pix_trans_count = 0; + s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); + s3_accel_start(-1, 0, 0xffffffff, 0, s3); + s3->accel.pix_trans_count = 0; break; case 0x9ee8: - s3_accel.short_stroke = (s3_accel.short_stroke & 0xff00) | val; + s3->accel.short_stroke = (s3->accel.short_stroke & 0xff00) | val; break; case 0x9ee9: - s3_accel.short_stroke = (s3_accel.short_stroke & 0xff) | (val << 8); + s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); break; case 0xa2e8: - if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10) - s3_accel.bkgd_color = (s3_accel.bkgd_color & ~0x00ff0000) | (val << 16); + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); else - s3_accel.bkgd_color = (s3_accel.bkgd_color & ~0x000000ff) | val; + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; break; case 0xa2e9: - if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10) - s3_accel.bkgd_color = (s3_accel.bkgd_color & ~0xff000000) | (val << 24); + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); else - s3_accel.bkgd_color = (s3_accel.bkgd_color & ~0x0000ff00) | (val << 8); - s3_accel.multifunc[0xe] ^= 0x10; + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; break; case 0xa6e8: - if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10) - s3_accel.frgd_color = (s3_accel.frgd_color & ~0x00ff0000) | (val << 16); + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); else - s3_accel.frgd_color = (s3_accel.frgd_color & ~0x000000ff) | val; -// pclog("Foreground colour now %08X %i\n", s3_accel.frgd_color, s3_bpp); + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; +// pclog("Foreground colour now %08X %i\n", s3->accel.frgd_color, s3->bpp); break; case 0xa6e9: - if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10) - s3_accel.frgd_color = (s3_accel.frgd_color & ~0xff000000) | (val << 24); + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); else - s3_accel.frgd_color = (s3_accel.frgd_color & ~0x0000ff00) | (val << 8); - s3_accel.multifunc[0xe] ^= 0x10; -// pclog("Foreground colour now %08X\n", s3_accel.frgd_color); + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; +// pclog("Foreground colour now %08X\n", s3->accel.frgd_color); break; case 0xaae8: - if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10) - s3_accel.wrt_mask = (s3_accel.wrt_mask & ~0x00ff0000) | (val << 16); + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); else - s3_accel.wrt_mask = (s3_accel.wrt_mask & ~0x000000ff) | val; + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; break; case 0xaae9: - if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10) - s3_accel.wrt_mask = (s3_accel.wrt_mask & ~0xff000000) | (val << 24); + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); else - s3_accel.wrt_mask = (s3_accel.wrt_mask & ~0x0000ff00) | (val << 8); - s3_accel.multifunc[0xe] ^= 0x10; + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; break; case 0xaee8: - if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10) - s3_accel.rd_mask = (s3_accel.rd_mask & ~0x00ff0000) | (val << 16); + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); else - s3_accel.rd_mask = (s3_accel.rd_mask & ~0x000000ff) | val; + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; break; case 0xaee9: - if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10) - s3_accel.rd_mask = (s3_accel.rd_mask & ~0xff000000) | (val << 24); + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); else - s3_accel.rd_mask = (s3_accel.rd_mask & ~0x0000ff00) | (val << 8); - s3_accel.multifunc[0xe] ^= 0x10; + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; break; case 0xb2e8: - if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10) - s3_accel.color_cmp = (s3_accel.color_cmp & ~0x00ff0000) | (val << 16); + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); else - s3_accel.color_cmp = (s3_accel.color_cmp & ~0x000000ff) | val; + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; break; case 0xb2e9: - if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10) - s3_accel.color_cmp = (s3_accel.color_cmp & ~0xff000000) | (val << 24); + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); else - s3_accel.color_cmp = (s3_accel.color_cmp & ~0x0000ff00) | (val << 8); - s3_accel.multifunc[0xe] ^= 0x10; + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; break; case 0xb6e8: - s3_accel.bkgd_mix = val; + s3->accel.bkgd_mix = val; break; case 0xbae8: - s3_accel.frgd_mix = val; + s3->accel.frgd_mix = val; break; case 0xbee8: - s3_accel.multifunc_cntl = (s3_accel.multifunc_cntl & 0xff00) | val; + s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff00) | val; break; case 0xbee9: - s3_accel.multifunc_cntl = (s3_accel.multifunc_cntl & 0xff) | (val << 8); - s3_accel.multifunc[s3_accel.multifunc_cntl >> 12] = s3_accel.multifunc_cntl & 0xfff; + s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8); + s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; break; case 0xe2e8: - s3_accel.pix_trans[0] = val; - if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3_accel.cmd & 0x600) && (s3_accel.cmd & 0x100)) - s3_accel_start(8, 1, s3_accel.pix_trans[0], 0); - else if (!(s3_accel.cmd & 0x600) && (s3_accel.cmd & 0x100)) - s3_accel_start(1, 1, 0xffffffff, s3_accel.pix_trans[0]); + s3->accel.pix_trans[0] = val; + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) + s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + else if (!(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); break; case 0xe2e9: - s3_accel.pix_trans[1] = val; - if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && (s3_accel.cmd & 0x600) == 0x200 && (s3_accel.cmd & 0x100)) + s3->accel.pix_trans[1] = val; + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100)) { - if (s3_accel.cmd & 0x1000) s3_accel_start(16, 1, s3_accel.pix_trans[1] | (s3_accel.pix_trans[0] << 8), 0); - else s3_accel_start(16, 1, s3_accel.pix_trans[0] | (s3_accel.pix_trans[1] << 8), 0); + if (s3->accel.cmd & 0x1000) s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); + else s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); } - else if ((s3_accel.cmd & 0x600) == 0x200 && (s3_accel.cmd & 0x100)) + else if ((s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100)) { - if (s3_accel.cmd & 0x1000) s3_accel_start(2, 1, 0xffffffff, s3_accel.pix_trans[1] | (s3_accel.pix_trans[0] << 8)); - else s3_accel_start(2, 1, 0xffffffff, s3_accel.pix_trans[0] | (s3_accel.pix_trans[1] << 8)); + if (s3->accel.cmd & 0x1000) s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + else s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } break; case 0xe2ea: - s3_accel.pix_trans[2] = val; + s3->accel.pix_trans[2] = val; break; case 0xe2eb: - s3_accel.pix_trans[3] = val; - if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && (s3_accel.cmd & 0x600) == 0x400 && (s3_accel.cmd & 0x100)) - s3_accel_start(32, 1, s3_accel.pix_trans[0] | (s3_accel.pix_trans[1] << 8) | (s3_accel.pix_trans[2] << 16) | (s3_accel.pix_trans[3] << 24), 0); - else if ((s3_accel.cmd & 0x600) == 0x400 && (s3_accel.cmd & 0x100)) - s3_accel_start(4, 1, 0xffffffff, s3_accel.pix_trans[0] | (s3_accel.pix_trans[1] << 8) | (s3_accel.pix_trans[2] << 16) | (s3_accel.pix_trans[3] << 24)); + s3->accel.pix_trans[3] = val; + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x400 && (s3->accel.cmd & 0x100)) + s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + else if ((s3->accel.cmd & 0x600) == 0x400 && (s3->accel.cmd & 0x100)) + s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); break; } } -void s3_accel_out_w(uint16_t port, uint16_t val, void *priv) +void s3_accel_out_w(uint16_t port, uint16_t val, void *p) { + s3_t *s3 = (s3_t *)p; // pclog("Accel out w %04X %04X\n", port, val); - if (s3_accel.cmd & 0x100) + if (s3->accel.cmd & 0x100) { - if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80) + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { - if (s3_accel.cmd & 0x1000) + if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(16, 1, val | (val << 16), 0); + s3_accel_start(16, 1, val | (val << 16), 0, s3); } else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16)); + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); } } -void s3_accel_out_l(uint16_t port, uint32_t val, void *priv) +void s3_accel_out_l(uint16_t port, uint32_t val, void *p) { + s3_t *s3 = (s3_t *)p; // pclog("Accel out l %04X %08X\n", port, val); - if (s3_accel.cmd & 0x100) + if (s3->accel.cmd & 0x100) { - if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80) + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { - if (s3_accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - if ((s3_accel.cmd & 0x600) == 0x400) - s3_accel_start(32, 1, val, 0); - else if ((s3_accel.cmd & 0x600) == 0x200) + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + if ((s3->accel.cmd & 0x600) == 0x400) + s3_accel_start(32, 1, val, 0, s3); + else if ((s3->accel.cmd & 0x600) == 0x200) { - s3_accel_start(16, 1, val >> 16, 0); - s3_accel_start(16, 1, val, 0); + s3_accel_start(16, 1, val >> 16, 0, s3); + s3_accel_start(16, 1, val, 0, s3); } - else if (!(s3_accel.cmd & 0x600)) + else if (!(s3->accel.cmd & 0x600)) { - s3_accel_start(8, 1, val >> 24, 0); - s3_accel_start(8, 1, val >> 16, 0); - s3_accel_start(8, 1, val >> 8, 0); - s3_accel_start(8, 1, val, 0); + s3_accel_start(8, 1, val >> 24, 0, s3); + s3_accel_start(8, 1, val >> 16, 0, s3); + s3_accel_start(8, 1, val >> 8, 0, s3); + s3_accel_start(8, 1, val, 0, s3); } } else { - if ((s3_accel.cmd & 0x600) == 0x400) - s3_accel_start(4, 1, 0xffffffff, val); - else if ((s3_accel.cmd & 0x600) == 0x200) + if ((s3->accel.cmd & 0x600) == 0x400) + s3_accel_start(4, 1, 0xffffffff, val, s3); + else if ((s3->accel.cmd & 0x600) == 0x200) { - s3_accel_start(2, 1, 0xffffffff, val >> 16); - s3_accel_start(2, 1, 0xffffffff, val); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + s3_accel_start(2, 1, 0xffffffff, val, s3); } - else if (!(s3_accel.cmd & 0x600)) + else if (!(s3->accel.cmd & 0x600)) { - s3_accel_start(1, 1, 0xffffffff, val >> 24); - s3_accel_start(1, 1, 0xffffffff, val >> 16); - s3_accel_start(1, 1, 0xffffffff, val >> 8); - s3_accel_start(1, 1, 0xffffffff, val); + s3_accel_start(1, 1, 0xffffffff, val >> 24, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 8, s3); + s3_accel_start(1, 1, 0xffffffff, val, s3); } } } } -uint8_t s3_accel_in(uint16_t port, void *priv) +uint8_t s3_accel_in(uint16_t port, void *p) { + s3_t *s3 = (s3_t *)p; int temp; // pclog("Accel in %04X\n", port); switch (port) @@ -595,34 +634,34 @@ uint8_t s3_accel_in(uint16_t port, void *priv) return 0; case 0x82e8: - return s3_accel.cur_y & 0xff; + return s3->accel.cur_y & 0xff; case 0x82e9: - return s3_accel.cur_y >> 8; + return s3->accel.cur_y >> 8; case 0x86e8: - return s3_accel.cur_x & 0xff; + return s3->accel.cur_x & 0xff; case 0x86e9: - return s3_accel.cur_x >> 8; + return s3->accel.cur_x >> 8; case 0x8ae8: - return s3_accel.desty_axstp & 0xff; + return s3->accel.desty_axstp & 0xff; case 0x8ae9: - return s3_accel.desty_axstp >> 8; + return s3->accel.desty_axstp >> 8; case 0x8ee8: - return s3_accel.destx_distp & 0xff; + return s3->accel.destx_distp & 0xff; case 0x8ee9: - return s3_accel.destx_distp >> 8; + return s3->accel.destx_distp >> 8; case 0x92e8: - return s3_accel.err_term & 0xff; + return s3->accel.err_term & 0xff; case 0x92e9: - return s3_accel.err_term >> 8; + return s3->accel.err_term >> 8; case 0x96e8: - return s3_accel.maj_axis_pcnt & 0xff; + return s3->accel.maj_axis_pcnt & 0xff; case 0x96e9: - return s3_accel.maj_axis_pcnt >> 8; + return s3->accel.maj_axis_pcnt >> 8; case 0x9ae8: return 0; @@ -630,69 +669,69 @@ uint8_t s3_accel_in(uint16_t port, void *priv) return 0; case 0xa2e8: - return s3_accel.bkgd_color & 0xff; + return s3->accel.bkgd_color & 0xff; case 0xa2e9: - return s3_accel.bkgd_color >> 8; + return s3->accel.bkgd_color >> 8; case 0xa6e8: - return s3_accel.frgd_color & 0xff; + return s3->accel.frgd_color & 0xff; case 0xa6e9: - return s3_accel.frgd_color >> 8; + return s3->accel.frgd_color >> 8; case 0xaae8: - return s3_accel.wrt_mask & 0xff; + return s3->accel.wrt_mask & 0xff; case 0xaae9: - return s3_accel.wrt_mask >> 8; + return s3->accel.wrt_mask >> 8; case 0xaee8: - return s3_accel.rd_mask & 0xff; + return s3->accel.rd_mask & 0xff; case 0xaee9: - return s3_accel.rd_mask >> 8; + return s3->accel.rd_mask >> 8; case 0xb2e8: - return s3_accel.color_cmp & 0xff; + return s3->accel.color_cmp & 0xff; case 0xb2e9: - return s3_accel.color_cmp >> 8; + return s3->accel.color_cmp >> 8; case 0xb6e8: - return s3_accel.bkgd_mix; + return s3->accel.bkgd_mix; case 0xbae8: - return s3_accel.frgd_mix; + return s3->accel.frgd_mix; case 0xbee8: - temp = s3_accel.multifunc[0xf] & 0xf; + temp = s3->accel.multifunc[0xf] & 0xf; switch (temp) { - case 0x0: return s3_accel.multifunc[0x0] & 0xff; - case 0x1: return s3_accel.multifunc[0x1] & 0xff; - case 0x2: return s3_accel.multifunc[0x2] & 0xff; - case 0x3: return s3_accel.multifunc[0x3] & 0xff; - case 0x4: return s3_accel.multifunc[0x4] & 0xff; - case 0x5: return s3_accel.multifunc[0xa] & 0xff; - case 0x6: return s3_accel.multifunc[0xe] & 0xff; - case 0x7: return s3_accel.cmd & 0xff; - case 0x8: return s3_accel.subsys_cntl & 0xff; - case 0x9: return s3_accel.setup_md & 0xff; - case 0xa: return s3_accel.multifunc[0xd] & 0xff; + case 0x0: return s3->accel.multifunc[0x0] & 0xff; + case 0x1: return s3->accel.multifunc[0x1] & 0xff; + case 0x2: return s3->accel.multifunc[0x2] & 0xff; + case 0x3: return s3->accel.multifunc[0x3] & 0xff; + case 0x4: return s3->accel.multifunc[0x4] & 0xff; + case 0x5: return s3->accel.multifunc[0xa] & 0xff; + case 0x6: return s3->accel.multifunc[0xe] & 0xff; + case 0x7: return s3->accel.cmd & 0xff; + case 0x8: return s3->accel.subsys_cntl & 0xff; + case 0x9: return s3->accel.setup_md & 0xff; + case 0xa: return s3->accel.multifunc[0xd] & 0xff; } return 0xff; case 0xbee9: - temp = s3_accel.multifunc[0xf] & 0xf; - s3_accel.multifunc[0xf]++; + temp = s3->accel.multifunc[0xf] & 0xf; + s3->accel.multifunc[0xf]++; switch (temp) { - case 0x0: return s3_accel.multifunc[0x0] >> 8; - case 0x1: return s3_accel.multifunc[0x1] >> 8; - case 0x2: return s3_accel.multifunc[0x2] >> 8; - case 0x3: return s3_accel.multifunc[0x3] >> 8; - case 0x4: return s3_accel.multifunc[0x4] >> 8; - case 0x5: return s3_accel.multifunc[0xa] >> 8; - case 0x6: return s3_accel.multifunc[0xe] >> 8; - case 0x7: return s3_accel.cmd >> 8; - case 0x8: return (s3_accel.subsys_cntl >> 8) & ~0xe000; - case 0x9: return (s3_accel.setup_md >> 8) & ~0xf000; - case 0xa: return s3_accel.multifunc[0xd] >> 8; + case 0x0: return s3->accel.multifunc[0x0] >> 8; + case 0x1: return s3->accel.multifunc[0x1] >> 8; + case 0x2: return s3->accel.multifunc[0x2] >> 8; + case 0x3: return s3->accel.multifunc[0x3] >> 8; + case 0x4: return s3->accel.multifunc[0x4] >> 8; + case 0x5: return s3->accel.multifunc[0xa] >> 8; + case 0x6: return s3->accel.multifunc[0xe] >> 8; + case 0x7: return s3->accel.cmd >> 8; + case 0x8: return (s3->accel.subsys_cntl >> 8) & ~0xe000; + case 0x9: return (s3->accel.setup_md >> 8) & ~0xf000; + case 0xa: return s3->accel.multifunc[0xd] >> 8; } return 0xff; @@ -702,114 +741,116 @@ uint8_t s3_accel_in(uint16_t port, void *priv) return 0; } -void s3_accel_write(uint32_t addr, uint8_t val, void *priv) +void s3_accel_write(uint32_t addr, uint8_t val, void *p) { + s3_t *s3 = (s3_t *)p; // pclog("Write S3 accel %08X %02X\n", addr, val); if (addr & 0x8000) - s3_accel_out(addr & 0xffff, val, priv); + s3_accel_out(addr & 0xffff, val, p); else { - if (s3_accel.cmd & 0x100) + if (s3->accel.cmd & 0x100) { - if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80) - s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0); + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24)); + s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } } } -void s3_accel_write_w(uint32_t addr, uint16_t val, void *priv) +void s3_accel_write_w(uint32_t addr, uint16_t val, void *p) { + s3_t *s3 = (s3_t *)p; // pclog("Write S3 accel w %08X %04X\n", addr, val); if (addr & 0x8000) { - s3_accel_out( addr & 0xffff, val, priv); - s3_accel_out((addr & 0xffff) + 1, val >> 8, priv); + s3_accel_out( addr & 0xffff, val, p); + s3_accel_out((addr & 0xffff) + 1, val >> 8, p); } else { - if (s3_accel.cmd & 0x100) + if (s3->accel.cmd & 0x100) { - if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80) + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { - if (s3_accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - s3_accel_start(16, 1, val | (val << 16), 0); + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + s3_accel_start(16, 1, val | (val << 16), 0, s3); } else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16)); + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); } } } -void s3_accel_write_l(uint32_t addr, uint32_t val, void *priv) +void s3_accel_write_l(uint32_t addr, uint32_t val, void *p) { + s3_t *s3 = (s3_t *)p; // pclog("Write S3 accel l %08X %08X\n", addr, val); if (addr & 0x8000) { - s3_accel_out( addr & 0xffff, val, priv); - s3_accel_out((addr & 0xffff) + 1, val >> 8, priv); - s3_accel_out((addr & 0xffff) + 2, val >> 16, priv); - s3_accel_out((addr & 0xffff) + 3, val >> 24, priv); + s3_accel_out( addr & 0xffff, val, p); + s3_accel_out((addr & 0xffff) + 1, val >> 8, p); + s3_accel_out((addr & 0xffff) + 2, val >> 16, p); + s3_accel_out((addr & 0xffff) + 3, val >> 24, p); } else { - if (s3_accel.cmd & 0x100) + if (s3->accel.cmd & 0x100) { - if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80) + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { - if (s3_accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - if ((s3_accel.cmd & 0x600) == 0x400) - s3_accel_start(32, 1, val, 0); - else if ((s3_accel.cmd & 0x600) == 0x200) + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + if ((s3->accel.cmd & 0x600) == 0x400) + s3_accel_start(32, 1, val, 0, s3); + else if ((s3->accel.cmd & 0x600) == 0x200) { - s3_accel_start(16, 1, val >> 16, 0); - s3_accel_start(16, 1, val, 0); + s3_accel_start(16, 1, val >> 16, 0, s3); + s3_accel_start(16, 1, val, 0, s3); } - else if (!(s3_accel.cmd & 0x600)) + else if (!(s3->accel.cmd & 0x600)) { - s3_accel_start(8, 1, val >> 24, 0); - s3_accel_start(8, 1, val >> 16, 0); - s3_accel_start(8, 1, val >> 8, 0); - s3_accel_start(8, 1, val, 0); + s3_accel_start(8, 1, val >> 24, 0, s3); + s3_accel_start(8, 1, val >> 16, 0, s3); + s3_accel_start(8, 1, val >> 8, 0, s3); + s3_accel_start(8, 1, val, 0, s3); } } else { - if ((s3_accel.cmd & 0x600) == 0x400) - s3_accel_start(4, 1, 0xffffffff, val); - else if ((s3_accel.cmd & 0x600) == 0x200) + if ((s3->accel.cmd & 0x600) == 0x400) + s3_accel_start(4, 1, 0xffffffff, val, s3); + else if ((s3->accel.cmd & 0x600) == 0x200) { - s3_accel_start(2, 1, 0xffffffff, val >> 16); - s3_accel_start(2, 1, 0xffffffff, val); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + s3_accel_start(2, 1, 0xffffffff, val, s3); } - else if (!(s3_accel.cmd & 0x600)) + else if (!(s3->accel.cmd & 0x600)) { - s3_accel_start(1, 1, 0xffffffff, val >> 24); - s3_accel_start(1, 1, 0xffffffff, val >> 16); - s3_accel_start(1, 1, 0xffffffff, val >> 8); - s3_accel_start(1, 1, 0xffffffff, val); + s3_accel_start(1, 1, 0xffffffff, val >> 24, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 8, s3); + s3_accel_start(1, 1, 0xffffffff, val, s3); } } } } } -uint8_t s3_accel_read(uint32_t addr, void *priv) +uint8_t s3_accel_read(uint32_t addr, void *p) { -// pclog("Read S3 accel %08X\n", addr); if (addr & 0x8000) - return s3_accel_in(addr & 0xffff, priv); + return s3_accel_in(addr & 0xffff, p); return 0; } -#define READ(addr, dat) if (s3_bpp == 0) dat = vram[ (addr) & 0x3fffff]; \ - else if (s3_bpp == 1) dat = vram_w[(addr) & 0x1fffff]; \ - else dat = vram_l[(addr) & 0x0fffff]; +#define READ(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & 0x3fffff]; \ + else if (s3->bpp == 1) dat = vram_w[(addr) & 0x1fffff]; \ + else dat = vram_l[(addr) & 0x0fffff]; -#define MIX switch ((mix_dat & mix_mask) ? (s3_accel.frgd_mix & 0xf) : (s3_accel.bkgd_mix & 0xf)) \ +#define MIX switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) \ { \ case 0x0: dest_dat = ~dest_dat; break; \ case 0x1: dest_dat = 0; break; \ @@ -830,62 +871,63 @@ uint8_t s3_accel_read(uint32_t addr, void *priv) } -#define WRITE(addr) if (s3_bpp == 0) \ +#define WRITE(addr) if (s3->bpp == 0) \ { \ - vram[(addr) & 0x3fffff] = dest_dat; \ - changedvram[((addr) & 0x3fffff) >> 10] = changeframecount; \ + svga->vram[(addr) & 0x3fffff] = dest_dat; \ + svga->changedvram[((addr) & 0x3fffff) >> 10] = changeframecount; \ } \ - else if (s3_bpp == 1) \ + else if (s3->bpp == 1) \ { \ vram_w[(addr) & 0x1fffff] = dest_dat; \ - changedvram[((addr) & 0x1fffff) >> 9] = changeframecount; \ + svga->changedvram[((addr) & 0x1fffff) >> 9] = changeframecount; \ } \ else \ { \ vram_l[(addr) & 0xfffff] = dest_dat; \ - changedvram[((addr) & 0xfffff) >> 8] = changeframecount; \ + svga->changedvram[((addr) & 0xfffff) >> 8] = changeframecount; \ } -void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat) +void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3) { + svga_t *svga = &s3->svga; uint32_t src_dat, dest_dat; int frgd_mix, bkgd_mix; - int clip_t = s3_accel.multifunc[1] & 0xfff; - int clip_l = s3_accel.multifunc[2] & 0xfff; - int clip_b = s3_accel.multifunc[3] & 0xfff; - int clip_r = s3_accel.multifunc[4] & 0xfff; - int vram_mask = (s3_accel.multifunc[0xa] & 0xc0) == 0xc0; + int clip_t = s3->accel.multifunc[1] & 0xfff; + int clip_l = s3->accel.multifunc[2] & 0xfff; + int clip_b = s3->accel.multifunc[3] & 0xfff; + int clip_r = s3->accel.multifunc[4] & 0xfff; + int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; uint32_t mix_mask; - uint16_t *vram_w = (uint16_t *)vram; - uint32_t *vram_l = (uint32_t *)vram; - uint32_t compare = s3_accel.color_cmp; - int compare_mode = (s3_accel.multifunc[0xe] >> 7) & 3; + uint16_t *vram_w = (uint16_t *)svga->vram; + uint32_t *vram_l = (uint32_t *)svga->vram; + uint32_t compare = s3->accel.color_cmp; + int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; //return; -// if (!cpu_input) pclog("Start S3 command %i %i, %i %i, %i (clip %i, %i to %i, %i %i)\n", s3_accel.cmd >> 13, s3_accel.cur_x, s3_accel.cur_y, s3_accel.maj_axis_pcnt & 0xfff, s3_accel.multifunc[0] & 0xfff, clip_l, clip_t, clip_r, clip_b, s3_accel.multifunc[0xe] & 0x20); -// else pclog(" S3 command %i, %i, %08x %08x\n", s3_accel.cmd >> 13, count, mix_dat, cpu_dat); +// if (!cpu_input) pclog("Start S3 command %i %i, %i %i, %i (clip %i, %i to %i, %i %i)\n", s3->accel.cmd >> 13, s3->accel.cur_x, s3->accel.cur_y, s3->accel.maj_axis_pcnt & 0xfff, s3->accel.multifunc[0] & 0xfff, clip_l, clip_t, clip_r, clip_b, s3->accel.multifunc[0xe] & 0x20); +// else pclog(" S3 command %i, %i, %08x %08x\n", s3->accel.cmd >> 13, count, mix_dat, cpu_dat); - if (!cpu_input) s3_accel.dat_count = 0; - if (cpu_input && (s3_accel.multifunc[0xa] & 0xc0) != 0x80) + if (!cpu_input) s3->accel.dat_count = 0; + if (cpu_input && (s3->accel.multifunc[0xa] & 0xc0) != 0x80) { - if (s3_bpp == 3 && count == 2) + if (s3->bpp == 3 && count == 2) { - if (s3_accel.dat_count) + if (s3->accel.dat_count) { - cpu_dat = (cpu_dat & 0xffff) | (s3_accel.dat_buf << 16); + cpu_dat = (cpu_dat & 0xffff) | (s3->accel.dat_buf << 16); count = 4; - s3_accel.dat_count = 0; + s3->accel.dat_count = 0; } else { - s3_accel.dat_buf = cpu_dat & 0xffff; - s3_accel.dat_count = 1; + s3->accel.dat_buf = cpu_dat & 0xffff; + s3->accel.dat_count = 1; } } - if (s3_bpp == 1) count >>= 1; - if (s3_bpp == 3) count >>= 2; + if (s3->bpp == 1) count >>= 1; + if (s3->bpp == 3) count >>= 2; } - switch (s3_accel.cmd & 0x600) + switch (s3->accel.cmd & 0x600) { case 0x000: mix_mask = 0x80; break; case 0x200: mix_mask = 0x8000; break; @@ -893,32 +935,32 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 0x600: mix_mask = 0x80000000; break; } - if (s3_bpp == 0) compare &= 0xff; - if (s3_bpp == 1) compare &= 0xffff; - switch (s3_accel.cmd >> 13) + if (s3->bpp == 0) compare &= 0xff; + if (s3->bpp == 1) compare &= 0xffff; + switch (s3->accel.cmd >> 13) { case 1: /*Draw line*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ { - s3_accel.cx = s3_accel.cur_x; - if (s3_accel.cur_x & 0x1000) s3_accel.cx |= ~0xfff; - s3_accel.cy = s3_accel.cur_y; - if (s3_accel.cur_y & 0x1000) s3_accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x; + if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y; + if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; - s3_accel.sy = s3_accel.maj_axis_pcnt; + s3->accel.sy = s3->accel.maj_axis_pcnt; } - if ((s3_accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - if (s3_accel.cmd & 8) /*Radial*/ + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ + if (s3->accel.cmd & 8) /*Radial*/ { - while (count-- && s3_accel.sy >= 0) + while (count-- && s3->accel.sy >= 0) { - if (s3_accel.cx >= clip_l && s3_accel.cx <= clip_r && - s3_accel.cy >= clip_t && s3_accel.cy <= clip_b) + if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && + s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = s3_accel.bkgd_color; break; - case 1: src_dat = s3_accel.frgd_color; break; + case 0: src_dat = s3->accel.bkgd_color; break; + case 1: src_dat = s3->accel.frgd_color; break; case 2: src_dat = cpu_dat; break; case 3: src_dat = 0; break; } @@ -927,44 +969,44 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ((s3_accel.cy * s3_width) + s3_accel.cx, dest_dat); + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); MIX - WRITE((s3_accel.cy * s3_width) + s3_accel.cx); + WRITE((s3->accel.cy * s3->width) + s3->accel.cx); } } mix_dat <<= 1; mix_dat |= 1; - if (s3_bpp == 0) cpu_dat >>= 8; + if (s3->bpp == 0) cpu_dat >>= 8; else cpu_dat >>= 16; - switch (s3_accel.cmd & 0xe0) + switch (s3->accel.cmd & 0xe0) { - case 0x00: s3_accel.cx++; break; - case 0x20: s3_accel.cx++; s3_accel.cy--; break; - case 0x40: s3_accel.cy--; break; - case 0x60: s3_accel.cx--; s3_accel.cy--; break; - case 0x80: s3_accel.cx--; break; - case 0xa0: s3_accel.cx--; s3_accel.cy++; break; - case 0xc0: s3_accel.cy++; break; - case 0xe0: s3_accel.cx++; s3_accel.cy++; break; + case 0x00: s3->accel.cx++; break; + case 0x20: s3->accel.cx++; s3->accel.cy--; break; + case 0x40: s3->accel.cy--; break; + case 0x60: s3->accel.cx--; s3->accel.cy--; break; + case 0x80: s3->accel.cx--; break; + case 0xa0: s3->accel.cx--; s3->accel.cy++; break; + case 0xc0: s3->accel.cy++; break; + case 0xe0: s3->accel.cx++; s3->accel.cy++; break; } - s3_accel.sy--; + s3->accel.sy--; } } else /*Bresenham*/ { - while (count-- && s3_accel.sy >= 0) + while (count-- && s3->accel.sy >= 0) { - if (s3_accel.cx >= clip_l && s3_accel.cx <= clip_r && - s3_accel.cy >= clip_t && s3_accel.cy <= clip_b) + if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && + s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = s3_accel.bkgd_color; break; - case 1: src_dat = s3_accel.frgd_color; break; + case 0: src_dat = s3->accel.bkgd_color; break; + case 1: src_dat = s3->accel.frgd_color; break; case 2: src_dat = cpu_dat; break; case 3: src_dat = 0; break; } @@ -973,57 +1015,57 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ((s3_accel.cy * s3_width) + s3_accel.cx, dest_dat); + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); -// pclog("Line : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X (%02X %02X) ", s3_accel.cx, s3_accel.cy, s3_accel.dest + s3_accel.cx, src_dat, vram[s3_accel.src + s3_accel.cx], mix_dat & mix_mask, s3_accel.src + s3_accel.cx, dest_dat, s3_accel.frgd_color, s3_accel.bkgd_color); +// pclog("Line : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X (%02X %02X) ", s3->accel.cx, s3->accel.cy, s3->accel.dest + s3->accel.cx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat & mix_mask, s3->accel.src + s3->accel.cx, dest_dat, s3->accel.frgd_color, s3->accel.bkgd_color); MIX // pclog("%02X\n", dest_dat); - WRITE((s3_accel.cy * s3_width) + s3_accel.cx); + WRITE((s3->accel.cy * s3->width) + s3->accel.cx); } } mix_dat <<= 1; mix_dat |= 1; - if (s3_bpp == 0) cpu_dat >>= 8; + if (s3->bpp == 0) cpu_dat >>= 8; else cpu_dat >>= 16; -// pclog("%i, %i - %i %i %i %i\n", s3_accel.cx, s3_accel.cy, s3_accel.err_term, s3_accel.maj_axis_pcnt, s3_accel.desty_axstp, s3_accel.destx_distp); +// pclog("%i, %i - %i %i %i %i\n", s3->accel.cx, s3->accel.cy, s3->accel.err_term, s3->accel.maj_axis_pcnt, s3->accel.desty_axstp, s3->accel.destx_distp); - if (s3_accel.err_term >= s3_accel.maj_axis_pcnt) + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { - s3_accel.err_term += s3_accel.destx_distp; + s3->accel.err_term += s3->accel.destx_distp; /*Step minor axis*/ - switch (s3_accel.cmd & 0xe0) + switch (s3->accel.cmd & 0xe0) { - case 0x00: s3_accel.cy--; break; - case 0x20: s3_accel.cy--; break; - case 0x40: s3_accel.cx--; break; - case 0x60: s3_accel.cx++; break; - case 0x80: s3_accel.cy++; break; - case 0xa0: s3_accel.cy++; break; - case 0xc0: s3_accel.cx--; break; - case 0xe0: s3_accel.cx++; break; + case 0x00: s3->accel.cy--; break; + case 0x20: s3->accel.cy--; break; + case 0x40: s3->accel.cx--; break; + case 0x60: s3->accel.cx++; break; + case 0x80: s3->accel.cy++; break; + case 0xa0: s3->accel.cy++; break; + case 0xc0: s3->accel.cx--; break; + case 0xe0: s3->accel.cx++; break; } } else - s3_accel.err_term += s3_accel.desty_axstp; + s3->accel.err_term += s3->accel.desty_axstp; /*Step major axis*/ - switch (s3_accel.cmd & 0xe0) + switch (s3->accel.cmd & 0xe0) { - case 0x00: s3_accel.cx--; break; - case 0x20: s3_accel.cx++; break; - case 0x40: s3_accel.cy--; break; - case 0x60: s3_accel.cy--; break; - case 0x80: s3_accel.cx--; break; - case 0xa0: s3_accel.cx++; break; - case 0xc0: s3_accel.cy++; break; - case 0xe0: s3_accel.cy++; break; + case 0x00: s3->accel.cx--; break; + case 0x20: s3->accel.cx++; break; + case 0x40: s3->accel.cy--; break; + case 0x60: s3->accel.cy--; break; + case 0x80: s3->accel.cx--; break; + case 0xa0: s3->accel.cx++; break; + case 0xc0: s3->accel.cy++; break; + case 0xe0: s3->accel.cy++; break; } - s3_accel.sy--; + s3->accel.sy--; } } break; @@ -1031,33 +1073,33 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 2: /*Rectangle fill*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ { - s3_accel.sx = s3_accel.maj_axis_pcnt & 0xfff; - s3_accel.sy = s3_accel.multifunc[0] & 0xfff; - s3_accel.cx = s3_accel.cur_x; - if (s3_accel.cur_x & 0x1000) s3_accel.cx |= ~0xfff; - s3_accel.cy = s3_accel.cur_y; - if (s3_accel.cur_y & 0x1000) s3_accel.cy |= ~0xfff; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + s3->accel.cx = s3->accel.cur_x; + if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y; + if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; - s3_accel.dest = s3_accel.cy * s3_width; + s3->accel.dest = s3->accel.cy * s3->width; -// pclog("Dest %08X (%i, %i) %04X %04X\n", s3_accel.dest, s3_accel.cx, s3_accel.cy, s3_accel.cur_x, s3_accel.cur_x & 0x1000); +// pclog("Dest %08X (%i, %i) %04X %04X\n", s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.cur_x, s3->accel.cur_x & 0x1000); } - if ((s3_accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ -// if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ +// if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ // return; - frgd_mix = (s3_accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3_accel.bkgd_mix >> 5) & 3; + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - while (count-- && s3_accel.sy >= 0) + while (count-- && s3->accel.sy >= 0) { - if (s3_accel.cx >= clip_l && s3_accel.cx <= clip_r && - s3_accel.cy >= clip_t && s3_accel.cy <= clip_b) + if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && + s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = s3_accel.bkgd_color; break; - case 1: src_dat = s3_accel.frgd_color; break; + case 0: src_dat = s3->accel.bkgd_color; break; + case 1: src_dat = s3->accel.frgd_color; break; case 2: src_dat = cpu_dat; break; case 3: src_dat = 0; break; } @@ -1066,42 +1108,42 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ(s3_accel.dest + s3_accel.cx, dest_dat); + READ(s3->accel.dest + s3->accel.cx, dest_dat); -// if (CS != 0xc000) pclog("Write %05X %02X %02X %04X (%02X %02X) ", s3_accel.dest + s3_accel.cx, src_dat, dest_dat, mix_dat, s3_accel.frgd_mix, s3_accel.bkgd_mix); +// if (CS != 0xc000) pclog("Write %05X %02X %02X %04X (%02X %02X) ", s3->accel.dest + s3->accel.cx, src_dat, dest_dat, mix_dat, s3->accel.frgd_mix, s3->accel.bkgd_mix); MIX // if (CS != 0xc000) pclog("%02X\n", dest_dat); - WRITE(s3_accel.dest + s3_accel.cx); + WRITE(s3->accel.dest + s3->accel.cx); } } mix_dat <<= 1; mix_dat |= 1; - if (s3_bpp == 0) cpu_dat >>= 8; + if (s3->bpp == 0) cpu_dat >>= 8; else cpu_dat >>= 16; - if (s3_accel.cmd & 0x20) s3_accel.cx++; - else s3_accel.cx--; - s3_accel.sx--; - if (s3_accel.sx < 0) + if (s3->accel.cmd & 0x20) s3->accel.cx++; + else s3->accel.cx--; + s3->accel.sx--; + if (s3->accel.sx < 0) { - if (s3_accel.cmd & 0x20) s3_accel.cx -= (s3_accel.maj_axis_pcnt & 0xfff) + 1; - else s3_accel.cx += (s3_accel.maj_axis_pcnt & 0xfff) + 1; -// s3_accel.dest -= (s3_accel.maj_axis_pcnt & 0xfff) + 1; - s3_accel.sx = s3_accel.maj_axis_pcnt & 0xfff; + if (s3->accel.cmd & 0x20) s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + else s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; +// s3->accel.dest -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; -// s3_accel.dest += s3_width; - if (s3_accel.cmd & 0x80) s3_accel.cy++; - else s3_accel.cy--; +// s3->accel.dest += s3_width; + if (s3->accel.cmd & 0x80) s3->accel.cy++; + else s3->accel.cy--; - s3_accel.dest = s3_accel.cy * s3_width; - s3_accel.sy--; + s3->accel.dest = s3->accel.cy * s3->width; + s3->accel.sy--; - if (cpu_input/* && (s3_accel.multifunc[0xa] & 0xc0) == 0x80*/) return; - if (s3_accel.sy < 0) + if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; + if (s3->accel.sy < 0) { return; } @@ -1112,155 +1154,155 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 6: /*BitBlt*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ { - s3_accel.sx = s3_accel.maj_axis_pcnt & 0xfff; - s3_accel.sy = s3_accel.multifunc[0] & 0xfff; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3_accel.dx = s3_accel.destx_distp & 0xfff; - if (s3_accel.destx_distp & 0x1000) s3_accel.dx |= ~0xfff; - s3_accel.dy = s3_accel.desty_axstp & 0xfff; - if (s3_accel.desty_axstp & 0x1000) s3_accel.dy |= ~0xfff; + s3->accel.dx = s3->accel.destx_distp & 0xfff; + if (s3->accel.destx_distp & 0x1000) s3->accel.dx |= ~0xfff; + s3->accel.dy = s3->accel.desty_axstp & 0xfff; + if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; - s3_accel.cx = s3_accel.cur_x & 0xfff; - if (s3_accel.cur_x & 0x1000) s3_accel.cx |= ~0xfff; - s3_accel.cy = s3_accel.cur_y & 0xfff; - if (s3_accel.cur_y & 0x1000) s3_accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; - s3_accel.src = s3_accel.cy * s3_width; - s3_accel.dest = s3_accel.dy * s3_width; + s3->accel.src = s3->accel.cy * s3->width; + s3->accel.dest = s3->accel.dy * s3->width; -// pclog("Source %08X Dest %08X (%i, %i) - (%i, %i)\n", s3_accel.src, s3_accel.dest, s3_accel.cx, s3_accel.cy, s3_accel.dx, s3_accel.dy); +// pclog("Source %08X Dest %08X (%i, %i) - (%i, %i)\n", s3->accel.src, s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy); } - if ((s3_accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ -// if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ +// if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ // return; - if (s3_accel.sy < 0) + if (s3->accel.sy < 0) return; - frgd_mix = (s3_accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3_accel.bkgd_mix >> 5) & 3; + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && - (s3_accel.cmd & 0xa0) == 0xa0 && (s3_accel.frgd_mix & 0xf) == 7) + (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7) { while (1) { - if (s3_accel.dx >= clip_l && s3_accel.dx <= clip_r && - s3_accel.dy >= clip_t && s3_accel.dy <= clip_b) + if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && + s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) { - READ(s3_accel.src + s3_accel.cx, src_dat); + READ(s3->accel.src + s3->accel.cx, src_dat); dest_dat = src_dat; - WRITE(s3_accel.dest + s3_accel.dx); + WRITE(s3->accel.dest + s3->accel.dx); } - s3_accel.cx++; - s3_accel.dx++; - s3_accel.sx--; - if (s3_accel.sx < 0) + s3->accel.cx++; + s3->accel.dx++; + s3->accel.sx--; + if (s3->accel.sx < 0) { - s3_accel.cx -= (s3_accel.maj_axis_pcnt & 0xfff) + 1; - s3_accel.dx -= (s3_accel.maj_axis_pcnt & 0xfff) + 1; - s3_accel.sx = s3_accel.maj_axis_pcnt & 0xfff; + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3_accel.cy++; - s3_accel.dy++; + s3->accel.cy++; + s3->accel.dy++; - s3_accel.src = s3_accel.cy * s3_width; - s3_accel.dest = s3_accel.dy * s3_width; + s3->accel.src = s3->accel.cy * s3->width; + s3->accel.dest = s3->accel.dy * s3->width; - s3_accel.sy--; + s3->accel.sy--; - if (s3_accel.sy < 0) + if (s3->accel.sy < 0) return; } } } else { - while (count-- && s3_accel.sy >= 0) + while (count-- && s3->accel.sy >= 0) { - if (s3_accel.dx >= clip_l && s3_accel.dx <= clip_r && - s3_accel.dy >= clip_t && s3_accel.dy <= clip_b) + if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && + s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) { if (vram_mask) { - READ(s3_accel.src + s3_accel.cx, mix_dat) + READ(s3->accel.src + s3->accel.cx, mix_dat) mix_dat = mix_dat ? mix_mask : 0; } switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = s3_accel.bkgd_color; break; - case 1: src_dat = s3_accel.frgd_color; break; + case 0: src_dat = s3->accel.bkgd_color; break; + case 1: src_dat = s3->accel.frgd_color; break; case 2: src_dat = cpu_dat; break; - case 3: READ(s3_accel.src + s3_accel.cx, src_dat); break; + case 3: READ(s3->accel.src + s3->accel.cx, src_dat); break; } if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ(s3_accel.dest + s3_accel.dx, dest_dat); + READ(s3->accel.dest + s3->accel.dx, dest_dat); -// pclog("BitBlt : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X ", s3_accel.dx, s3_accel.dy, s3_accel.dest + s3_accel.dx, src_dat, vram[s3_accel.src + s3_accel.cx], mix_dat, s3_accel.src + s3_accel.cx, dest_dat); +// pclog("BitBlt : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X ", s3->accel.dx, s3->accel.dy, s3->accel.dest + s3->accel.dx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat, s3->accel.src + s3->accel.cx, dest_dat); MIX // pclog("%02X\n", dest_dat); - WRITE(s3_accel.dest + s3_accel.dx); + WRITE(s3->accel.dest + s3->accel.dx); } } mix_dat <<= 1; mix_dat |= 1; - if (s3_bpp == 0) cpu_dat >>= 8; + if (s3->bpp == 0) cpu_dat >>= 8; else cpu_dat >>= 16; - if (s3_accel.cmd & 0x20) + if (s3->accel.cmd & 0x20) { - s3_accel.cx++; - s3_accel.dx++; + s3->accel.cx++; + s3->accel.dx++; } else { - s3_accel.cx--; - s3_accel.dx--; + s3->accel.cx--; + s3->accel.dx--; } - s3_accel.sx--; - if (s3_accel.sx < 0) + s3->accel.sx--; + if (s3->accel.sx < 0) { - if (s3_accel.cmd & 0x20) + if (s3->accel.cmd & 0x20) { - s3_accel.cx -= (s3_accel.maj_axis_pcnt & 0xfff) + 1; - s3_accel.dx -= (s3_accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; } else { - s3_accel.cx += (s3_accel.maj_axis_pcnt & 0xfff) + 1; - s3_accel.dx += (s3_accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; } - s3_accel.sx = s3_accel.maj_axis_pcnt & 0xfff; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - if (s3_accel.cmd & 0x80) + if (s3->accel.cmd & 0x80) { - s3_accel.cy++; - s3_accel.dy++; + s3->accel.cy++; + s3->accel.dy++; } else { - s3_accel.cy--; - s3_accel.dy--; + s3->accel.cy--; + s3->accel.dy--; } - s3_accel.src = s3_accel.cy * s3_width; - s3_accel.dest = s3_accel.dy * s3_width; + s3->accel.src = s3->accel.cy * s3->width; + s3->accel.dest = s3->accel.dy * s3->width; - s3_accel.sy--; + s3->accel.sy--; - if (cpu_input/* && (s3_accel.multifunc[0xa] & 0xc0) == 0x80*/) return; - if (s3_accel.sy < 0) + if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; + if (s3->accel.sy < 0) { return; } @@ -1272,124 +1314,124 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ { - s3_accel.sx = s3_accel.maj_axis_pcnt & 0xfff; - s3_accel.sy = s3_accel.multifunc[0] & 0xfff; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3_accel.dx = s3_accel.destx_distp & 0xfff; - if (s3_accel.destx_distp & 0x1000) s3_accel.dx |= ~0xfff; - s3_accel.dy = s3_accel.desty_axstp & 0xfff; - if (s3_accel.desty_axstp & 0x1000) s3_accel.dy |= ~0xfff; + s3->accel.dx = s3->accel.destx_distp & 0xfff; + if (s3->accel.destx_distp & 0x1000) s3->accel.dx |= ~0xfff; + s3->accel.dy = s3->accel.desty_axstp & 0xfff; + if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; - s3_accel.cx = s3_accel.cur_x & 0xfff; - if (s3_accel.cur_x & 0x1000) s3_accel.cx |= ~0xfff; - s3_accel.cy = s3_accel.cur_y & 0xfff; - if (s3_accel.cur_y & 0x1000) s3_accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; /*Align source with destination*/ -// s3_accel.cx = (s3_accel.cx & ~7) | (s3_accel.dx & 7); -// s3_accel.cy = (s3_accel.cy & ~7) | (s3_accel.dy & 7); +// s3->accel.cx = (s3->accel.cx & ~7) | (s3->accel.dx & 7); +// s3->accel.cy = (s3->accel.cy & ~7) | (s3->accel.dy & 7); - s3_accel.pattern = (s3_accel.cy * s3_width) + s3_accel.cx; - s3_accel.dest = s3_accel.dy * s3_width; + s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; + s3->accel.dest = s3->accel.dy * s3->width; - s3_accel.cx = s3_accel.dx & 7; - s3_accel.cy = s3_accel.dy & 7; + s3->accel.cx = s3->accel.dx & 7; + s3->accel.cy = s3->accel.dy & 7; - s3_accel.src = s3_accel.pattern + (s3_accel.cy * s3_width); + s3->accel.src = s3->accel.pattern + (s3->accel.cy * s3->width); -// pclog("Source %08X Dest %08X (%i, %i) - (%i, %i)\n", s3_accel.src, s3_accel.dest, s3_accel.cx, s3_accel.cy, s3_accel.dx, s3_accel.dy); +// pclog("Source %08X Dest %08X (%i, %i) - (%i, %i)\n", s3->accel.src, s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy); // dumpregs(); // exit(-1); } - if ((s3_accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ -// if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ +// if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ // return; - frgd_mix = (s3_accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3_accel.bkgd_mix >> 5) & 3; + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - while (count-- && s3_accel.sy >= 0) + while (count-- && s3->accel.sy >= 0) { - if (s3_accel.dx >= clip_l && s3_accel.dx <= clip_r && - s3_accel.dy >= clip_t && s3_accel.dy <= clip_b) + if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && + s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) { if (vram_mask) { - READ(s3_accel.src + s3_accel.cx, mix_dat) + READ(s3->accel.src + s3->accel.cx, mix_dat) mix_dat = mix_dat ? mix_mask : 0; } switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = s3_accel.bkgd_color; break; - case 1: src_dat = s3_accel.frgd_color; break; + case 0: src_dat = s3->accel.bkgd_color; break; + case 1: src_dat = s3->accel.frgd_color; break; case 2: src_dat = cpu_dat; break; - case 3: READ(s3_accel.src + s3_accel.cx, src_dat); break; + case 3: READ(s3->accel.src + s3->accel.cx, src_dat); break; } if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ(s3_accel.dest + s3_accel.dx, dest_dat); + READ(s3->accel.dest + s3->accel.dx, dest_dat); -// pclog("Pattern fill : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X ", s3_accel.dx, s3_accel.dy, s3_accel.dest + s3_accel.dx, src_dat, vram[s3_accel.src + s3_accel.cx], mix_dat, s3_accel.src + s3_accel.cx, dest_dat); +// pclog("Pattern fill : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X ", s3->accel.dx, s3->accel.dy, s3->accel.dest + s3->accel.dx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat, s3->accel.src + s3->accel.cx, dest_dat); MIX // pclog("%02X\n", dest_dat); - WRITE(s3_accel.dest + s3_accel.dx); + WRITE(s3->accel.dest + s3->accel.dx); } } mix_dat <<= 1; mix_dat |= 1; - if (s3_bpp == 0) cpu_dat >>= 8; + if (s3->bpp == 0) cpu_dat >>= 8; else cpu_dat >>= 16; - if (s3_accel.cmd & 0x20) + if (s3->accel.cmd & 0x20) { - s3_accel.cx = ((s3_accel.cx + 1) & 7) | (s3_accel.cx & ~7); - s3_accel.dx++; + s3->accel.cx = ((s3->accel.cx + 1) & 7) | (s3->accel.cx & ~7); + s3->accel.dx++; } else { - s3_accel.cx = ((s3_accel.cx - 1) & 7) | (s3_accel.cx & ~7); - s3_accel.dx--; + s3->accel.cx = ((s3->accel.cx - 1) & 7) | (s3->accel.cx & ~7); + s3->accel.dx--; } - s3_accel.sx--; - if (s3_accel.sx < 0) + s3->accel.sx--; + if (s3->accel.sx < 0) { - if (s3_accel.cmd & 0x20) + if (s3->accel.cmd & 0x20) { - s3_accel.cx = ((s3_accel.cx - ((s3_accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3_accel.cx & ~7); - s3_accel.dx -= (s3_accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.cx = ((s3->accel.cx - ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; } else { - s3_accel.cx = ((s3_accel.cx + ((s3_accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3_accel.cx & ~7); - s3_accel.dx += (s3_accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.cx = ((s3->accel.cx + ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); + s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; } - s3_accel.sx = s3_accel.maj_axis_pcnt & 0xfff; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - if (s3_accel.cmd & 0x80) + if (s3->accel.cmd & 0x80) { - s3_accel.cy = ((s3_accel.cy + 1) & 7) | (s3_accel.cy & ~7); - s3_accel.dy++; + s3->accel.cy = ((s3->accel.cy + 1) & 7) | (s3->accel.cy & ~7); + s3->accel.dy++; } else { - s3_accel.cy = ((s3_accel.cy - 1) & 7) | (s3_accel.cy & ~7); - s3_accel.dy--; + s3->accel.cy = ((s3->accel.cy - 1) & 7) | (s3->accel.cy & ~7); + s3->accel.dy--; } - s3_accel.src = s3_accel.pattern + (s3_accel.cy * s3_width); - s3_accel.dest = s3_accel.dy * s3_width; + s3->accel.src = s3->accel.pattern + (s3->accel.cy * s3->width); + s3->accel.dest = s3->accel.dy * s3->width; - s3_accel.sy--; + s3->accel.sy--; - if (cpu_input/* && (s3_accel.multifunc[0xa] & 0xc0) == 0x80*/) return; - if (s3_accel.sy < 0) + if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; + if (s3->accel.sy < 0) { return; } @@ -1399,21 +1441,21 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } -void s3_hwcursor_draw(int displine) +void s3_hwcursor_draw(svga_t *svga, int displine) { int x; uint16_t dat[2]; int xx; - int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y); + pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y); for (x = 0; x < 64; x += 16) { - dat[0] = (vram[svga_hwcursor_latch.addr] << 8) | vram[svga_hwcursor_latch.addr + 1]; - dat[1] = (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3]; + dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; + dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; for (xx = 0; xx < 16; xx++) { - if (offset >= svga_hwcursor_latch.x) + if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x8000)) ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? 0xffffff : 0; @@ -1426,20 +1468,22 @@ void s3_hwcursor_draw(int displine) dat[0] <<= 1; dat[1] <<= 1; } - svga_hwcursor_latch.addr += 4; + svga->hwcursor_latch.addr += 4; } } -uint8_t s3_pci_read(int func, int addr, void *priv) +uint8_t s3_pci_read(int func, int addr, void *p) { + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; // pclog("S3 PCI read %08X\n", addr); switch (addr) { case 0x00: return 0x33; /*'S3'*/ case 0x01: return 0x53; - case 0x02: return s3_id_ext; + case 0x02: return s3->id_ext; case 0x03: return 0x88; case 0x04: return 0x03; /*Respond to IO and memory accesses*/ @@ -1454,8 +1498,8 @@ uint8_t s3_pci_read(int func, int addr, void *priv) case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x11: return 0x00; - case 0x12: return crtc[0x5a] & 0x80; - case 0x13: return crtc[0x59]; + case 0x12: return svga->crtc[0x5a] & 0x80; + case 0x13: return svga->crtc[0x59]; case 0x30: return 0x01; /*BIOS ROM address*/ case 0x31: return 0x00; @@ -1465,86 +1509,115 @@ uint8_t s3_pci_read(int func, int addr, void *priv) return 0; } -void s3_pci_write(int func, int addr, uint8_t val, void *priv) +void s3_pci_write(int func, int addr, uint8_t val, void *p) { + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; switch (addr) { - case 0x12: crtc[0x5a] = val & 0x80; s3_updatemapping(); break; - case 0x13: crtc[0x59] = val; s3_updatemapping(); break; + case 0x12: + svga->crtc[0x5a] = val & 0x80; + s3_updatemapping(s3); + break; + case 0x13: + svga->crtc[0x59] = val; + s3_updatemapping(s3); + break; } } -int s3_init() +static void *s3_init() { - if (gfxcard == GFX_BAHAMAS64) - { - s3_id = 0xc1; /*Vision864P*/ - s3_id_ext = 0xc1; /*Trio64*/ - } - if (gfxcard == GFX_N9_9FX) - { - s3_id = 0xe1; - s3_id_ext = 0x11; /*Trio64*/ - } - if (gfxcard == GFX_STEALTH64) - { - s3_id = 0xe1; /*Trio64*/ - s3_id_ext = 0x11; - } - svga_recalctimings_ex = s3_recalctimings; - svga_hwcursor_draw = s3_hwcursor_draw; - - crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5); - crtc[0x37] = 1 | (7 << 5); + s3_t *s3 = malloc(sizeof(s3_t)); + svga_t *svga = &s3->svga; + memset(s3, 0, sizeof(s3_t)); - vrammask = 0x3fffff; + svga_init(&s3->svga, s3, 1 << 22, /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/ + s3_recalctimings, + s3_in, s3_out, + s3_hwcursor_draw); - io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0xa2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0xa6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0xaae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0xaee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); - io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, NULL); + io_sethandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - pci_add(s3_pci_read, s3_pci_write, NULL); + svga->crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5); + svga->crtc[0x37] = 1 | (7 << 5); + + io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xa2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xa6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xaae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xaee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + + pci_add(s3_pci_read, s3_pci_write, s3); - svga_vram_limit = 4 << 20; /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/ - return svga_init(); + return s3; } -GFXCARD vid_s3 = +void *s3_bahamas64_init() { - s3_init, - /*IO at 3Cx/3Dx*/ - s3_out, - s3_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, + s3_t *s3 = s3_init(); - svga_poll, - svga_recalctimings, + s3->id = 0xc1; /*Vision864P*/ + s3->id_ext = 0xc1; /*Trio64*/ + + return s3; +} - svga_write, - video_write_null, - video_write_null, +void *s3_9fx_init() +{ + s3_t *s3 = s3_init(); - svga_read, - video_read_null, - video_read_null + s3->id = 0xe1; + s3->id_ext = 0x11; /*Trio64*/ + + return s3; +} + +void s3_close(void *p) +{ + s3_t *s3 = (s3_t *)p; + + svga_close(&s3->svga); + + free(s3); +} + +void s3_speed_changed(void *p) +{ + s3_t *s3 = (s3_t *)p; + + svga_recalctimings(&s3->svga); +} + +device_t s3_bahamas64_device = +{ + "Paradise Bahamas 64 (S3 Vision864)", + s3_bahamas64_init, + s3_close, + s3_speed_changed, + svga_add_status_info }; +device_t s3_9fx_device = +{ + "Number 9 9FX (S3 Trio64)", + s3_9fx_init, + s3_close, + s3_speed_changed, + svga_add_status_info +}; diff --git a/src/vid_s3.h b/src/vid_s3.h new file mode 100644 index 0000000..161f458 --- /dev/null +++ b/src/vid_s3.h @@ -0,0 +1,2 @@ +device_t s3_bahamas64_device; +device_t s3_9fx_device; diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 43199d1..11c227d 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -1,51 +1,66 @@ /*S3 ViRGE emulation The SVGA core is largely the same as older S3 chips, but the blitter is totally different*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "pci.h" #include "video.h" +#include "vid_s3_virge.h" #include "vid_svga.h" #include "vid_svga_render.h" //#include "vid_sdac_ramdac.h" -void s3_virge_updatemapping(); - -static uint8_t s3_bank; -static uint8_t s3_ma_ext; -static int s3_width = 1024; -static int s3_bpp = 0; - -static uint8_t s3_virge_id, s3_virge_id_high, s3_virge_id_low, s3_virge_rev; - -uint8_t s3_virge_mmio_read(uint32_t addr, void *priv); -uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv); -uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv); -void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv); -void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv); -void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv); - -void s3_virge_out(uint16_t addr, uint8_t val, void *priv) +typedef struct virge_t { + svga_t svga; + + uint8_t bank; + uint8_t ma_ext; + int width; + int bpp; + + uint8_t virge_id, virge_id_high, virge_id_low, virge_rev; + + uint32_t linear_base, linear_size; + + uint8_t pci_regs[256]; +} virge_t; + +void s3_virge_updatemapping(virge_t *virge); + +uint8_t s3_virge_mmio_read(uint32_t addr, void *p); +uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p); +uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p); +void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p); +void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p); +void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p); + +void s3_virge_out(uint16_t addr, uint8_t val, void *p) +{ + virge_t *virge = (virge_t *)p; + svga_t *svga = &virge->svga; uint8_t old; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; pclog("S3 out %04X %02X %04X:%08X %04X %04X %i\n", addr, val, CS, pc, ES, BX, ins); switch (addr) { case 0x3c5: - if (seqaddr >= 0x10) + if (svga->seqaddr >= 0x10) { - seqregs[seqaddr&0x1F]=val; + svga->seqregs[svga->seqaddr & 0x1f]=val; return; } - if (seqaddr == 4) /*Chain-4 - update banking*/ + if (svga->seqaddr == 4) /*Chain-4 - update banking*/ { - if (val & 8) svgawbank = svgarbank = s3_bank << 16; - else svgawbank = svgarbank = s3_bank << 14; + if (val & 8) svga->write_bank = svga->read_bank = virge->bank << 16; + else svga->write_bank = svga->read_bank = virge->bank << 14; } break; @@ -54,107 +69,113 @@ void s3_virge_out(uint16_t addr, uint8_t val, void *priv) //sdac_ramdac_out(addr,val); //return; - case 0x3D4: - crtcreg=val&0x7f; + case 0x3d4: + svga->crtcreg = val & 0x7f; return; - case 0x3D5: + case 0x3d5: // if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val); - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - if (crtcreg >= 0x20 && crtcreg != 0x38 && (crtc[0x38] & 0xcc) != 0x48) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; - switch (crtcreg) + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) + return; + if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) + return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + switch (svga->crtcreg) { case 0x31: - s3_ma_ext = (s3_ma_ext & 0x1c) | ((val & 0x30) >> 4); - vrammask = (val & 8) ? 0x3fffff : 0x3ffff; + virge->ma_ext = (virge->ma_ext & 0x1c) | ((val & 0x30) >> 4); + svga->vrammask = (val & 8) ? 0x3fffff : 0x3ffff; break; case 0x50: - switch (crtc[0x50] & 0xc1) + switch (svga->crtc[0x50] & 0xc1) { - case 0x00: s3_width = (crtc[0x31] & 2) ? 2048 : 1024; break; - case 0x01: s3_width = 1152; break; - case 0x40: s3_width = 640; break; - case 0x80: s3_width = 800; break; - case 0x81: s3_width = 1600; break; - case 0xc0: s3_width = 1280; break; + case 0x00: virge->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; break; + case 0x01: virge->width = 1152; break; + case 0x40: virge->width = 640; break; + case 0x80: virge->width = 800; break; + case 0x81: virge->width = 1600; break; + case 0xc0: virge->width = 1280; break; } - s3_bpp = (crtc[0x50] >> 4) & 3; + virge->bpp = (svga->crtc[0x50] >> 4) & 3; break; case 0x69: - s3_ma_ext = val & 0x1f; + virge->ma_ext = val & 0x1f; break; case 0x35: - s3_bank = (s3_bank & 0x70) | (val & 0xf); + virge->bank = (virge->bank & 0x70) | (val & 0xf); // pclog("CRTC write R35 %02X\n", val); - if (chain4) svgawbank = svgarbank = s3_bank << 16; - else svgawbank = svgarbank = s3_bank << 14; + if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16; + else svga->write_bank = svga->read_bank = virge->bank << 14; break; case 0x51: - s3_bank = (s3_bank & 0x4f) | ((val & 0xc) << 2); - if (chain4) svgawbank = svgarbank = s3_bank << 16; - else svgawbank = svgarbank = s3_bank << 14; - s3_ma_ext = (s3_ma_ext & ~0xc) | ((val & 3) << 2); + virge->bank = (virge->bank & 0x4f) | ((val & 0xc) << 2); + if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16; + else svga->write_bank = svga->read_bank = virge->bank << 14; + virge->ma_ext = (virge->ma_ext & ~0xc) | ((val & 3) << 2); break; case 0x6a: - s3_bank = val; + virge->bank = val; // pclog("CRTC write R6a %02X\n", val); - if (chain4) svgawbank = svgarbank = s3_bank << 16; - else svgawbank = svgarbank = s3_bank << 14; + if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16; + else svga->write_bank = svga->read_bank = virge->bank << 14; break; case 0x3a: - if (val & 0x10) gdcreg[5] |= 0x40; /*Horrible cheat*/ + if (val & 0x10) svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ break; case 0x45: - svga_hwcursor.ena = val & 1; + svga->hwcursor.ena = val & 1; break; case 0x48: - svga_hwcursor.x = ((crtc[0x46] << 8) | crtc[0x47]) & 0x7ff; - if (bpp == 32) svga_hwcursor.x >>= 1; - svga_hwcursor.y = ((crtc[0x48] << 8) | crtc[0x49]) & 0x7ff; - svga_hwcursor.xoff = crtc[0x4e] & 63; - svga_hwcursor.yoff = crtc[0x4f] & 63; - svga_hwcursor.addr = ((((crtc[0x4c] << 8) | crtc[0x4d]) & 0xfff) * 1024) + (svga_hwcursor.yoff * 16); + svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; + if (svga->bpp == 32) svga->hwcursor.x >>= 1; + svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; + svga->hwcursor.xoff = svga->crtc[0x4e] & 63; + svga->hwcursor.yoff = svga->crtc[0x4f] & 63; + svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); break; case 0x53: case 0x58: case 0x59: case 0x5a: - s3_virge_updatemapping(); + s3_virge_updatemapping(virge); break; case 0x67: switch (val >> 4) { - case 3: bpp = 15; break; - case 5: bpp = 16; break; - case 7: bpp = 24; break; - case 13: bpp = 32; break; - default: bpp = 8; break; + case 3: svga->bpp = 15; break; + case 5: svga->bpp = 16; break; + case 7: svga->bpp = 24; break; + case 13: svga->bpp = 32; break; + default: svga->bpp = 8; break; } break; //case 0x55: case 0x43: // pclog("Write CRTC R%02X %02X\n", crtcreg, val); } - if (old!=val) + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(svga); } } break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t s3_virge_in(uint16_t addr, void *priv) +uint8_t s3_virge_in(uint16_t addr, void *p) { - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + virge_t *virge = (virge_t *)p; + svga_t *svga = &virge->svga; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; if (addr != 0x3da) pclog("S3 in %04X %04X:%08X\n", addr, CS, pc); switch (addr) @@ -164,221 +185,221 @@ uint8_t s3_virge_in(uint16_t addr, void *priv) //return sdac_ramdac_in(addr); case 0x3c5: - if (seqaddr >= 0x10) - return seqregs[seqaddr&0x1F]; + if (svga->seqaddr >= 0x10) + return svga->seqregs[svga->seqaddr & 0x1f]; break; case 0x3D4: - return crtcreg; + return svga->crtcreg; case 0x3D5: // pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc); - switch (crtcreg) + switch (svga->crtcreg) { - case 0x2d: return s3_virge_id_high; /*Extended chip ID*/ - case 0x2e: return s3_virge_id_low; /*New chip ID*/ - case 0x2f: return s3_virge_rev; - case 0x30: return s3_virge_id; /*Chip ID*/ - case 0x31: return (crtc[0x31] & 0xcf) | ((s3_ma_ext & 3) << 4); - case 0x35: return (crtc[0x35] & 0xf0) | (s3_bank & 0xf); - case 0x51: return (crtc[0x51] & 0xf0) | ((s3_bank >> 2) & 0xc) | ((s3_ma_ext >> 2) & 3); - case 0x69: return s3_ma_ext; - case 0x6a: return s3_bank; + case 0x2d: return virge->virge_id_high; /*Extended chip ID*/ + case 0x2e: return virge->virge_id_low; /*New chip ID*/ + case 0x2f: return virge->virge_rev; + case 0x30: return virge->virge_id; /*Chip ID*/ + case 0x31: return (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); + case 0x35: return (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf); + case 0x51: return (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3); + case 0x69: return virge->ma_ext; + case 0x6a: return virge->bank; } - return crtc[crtcreg]; + return svga->crtc[svga->crtcreg]; } - return svga_in(addr, NULL); + return svga_in(addr, svga); } -void s3_virge_recalctimings() +void s3_virge_recalctimings(svga_t *svga) { + virge_t *virge = (virge_t *)svga->p; // pclog("recalctimings\n"); - svga_ma |= (s3_ma_ext << 16); + svga->ma_latch |= (virge->ma_ext << 16); // pclog("SVGA_MA %08X\n", svga_ma); // if (gdcreg[5] & 0x40) svga_lowres = !(crtc[0x3a] & 0x10); - if ((gdcreg[5] & 0x40) && (crtc[0x3a] & 0x10)) + if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - switch (bpp) + switch (svga->bpp) { case 8: - svga_render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_highres; break; case 15: - svga_render = svga_render_15bpp_highres; + svga->render = svga_render_15bpp_highres; break; case 16: - svga_render = svga_render_16bpp_highres; + svga->render = svga_render_16bpp_highres; break; case 24: - svga_render = svga_render_24bpp_highres; + svga->render = svga_render_24bpp_highres; break; case 32: - svga_render = svga_render_32bpp_highres; + svga->render = svga_render_32bpp_highres; break; } } - if (crtc[0x5d] & 0x01) svga_htotal += 0x100; - if (crtc[0x5d] & 0x02) svga_hdisp += 0x100; - if (crtc[0x5e] & 0x01) svga_vtotal += 0x400; - if (crtc[0x5e] & 0x02) svga_dispend += 0x400; - if (crtc[0x5e] & 0x10) svga_vsyncstart += 0x400; - if (crtc[0x5e] & 0x40) svga_split += 0x400; - if (crtc[0x51] & 0x30) svga_rowoffset += (crtc[0x51] & 0x30) << 4; - else if (crtc[0x43] & 0x04) svga_rowoffset += 0x100; - if (!svga_rowoffset) svga_rowoffset = 256; - svga_interlace = crtc[0x42] & 0x20; - if (bpp == 32) + if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; + if (svga->crtc[0x5d] & 0x02) svga->hdisp += 0x100; + if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400; + if (svga->crtc[0x5e] & 0x02) svga->dispend += 0x400; + if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400; + if (svga->crtc[0x5e] & 0x40) svga->split += 0x400; + if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; + else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; + if (!svga->rowoffset) svga->rowoffset = 256; + svga->interlace = svga->crtc[0x42] & 0x20; + if (svga->bpp == 32) { - svga_htotal <<= 2; - svga_hdisp <<= 2; + svga->htotal <<= 2; + svga->hdisp <<= 2; } //svga_clock = cpuclock / sdac_getclock((svga_miscout >> 2) & 3); // pclog("SVGA_CLOCK = %f %02X %f\n", svga_clock, svga_miscout, cpuclock); //if (bpp > 8) svga_clock /= 2; } -static uint32_t s3_linear_base = 0, s3_linear_size = 0; -void s3_virge_updatemapping() +void s3_virge_updatemapping(virge_t *virge) { - mem_removehandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); + svga_t *svga = &virge->svga; + + mem_removehandler(virge->linear_base, virge->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, svga); // video_write_a000_w = video_write_a000_l = NULL; - mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); - mem_removehandler(0xa0000, 0x20000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL); - pclog("Update mapping - bank %02X ", gdcreg[6] & 0xc); - switch (gdcreg[6] & 0xc) /*Banked framebuffer*/ + mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); + mem_removehandler(0xa0000, 0x20000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, virge); + pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); + switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ { case 0x0: /*128k at A0000*/ - mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0x4: /*64k at A0000*/ - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0x8: /*32k at B0000*/ - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0xC: /*32k at B8000*/ - mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; } - pclog("Linear framebuffer %02X ", crtc[0x58] & 0x10); - if (crtc[0x58] & 0x10) /*Linear framebuffer*/ + pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); + if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ { - s3_linear_base = (crtc[0x5a] << 16) | (crtc[0x59] << 24); - switch (crtc[0x58] & 3) + virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); + switch (svga->crtc[0x58] & 3) { case 0: /*64k*/ - s3_linear_size = 0x10000; + virge->linear_size = 0x10000; break; case 1: /*1mb*/ - s3_linear_size = 0x100000; + virge->linear_size = 0x100000; break; case 2: /*2mb*/ - s3_linear_size = 0x200000; + virge->linear_size = 0x200000; break; case 3: /*8mb*/ - s3_linear_size = 0x400000; + virge->linear_size = 0x400000; break; } - s3_linear_base &= ~(s3_linear_size - 1); + virge->linear_base &= ~(virge->linear_size - 1); // pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]); - pclog("Linear framebuffer at %08X size %08X\n", s3_linear_base, s3_linear_size); - if (s3_linear_base == 0xa0000) - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + pclog("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size); + if (virge->linear_base == 0xa0000) + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); else - mem_sethandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); + mem_sethandler(virge->linear_base, virge->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, svga); } - pclog("Memory mapped IO %02X\n", crtc[0x53] & 0x18); - output = 0; - if ((crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/ + pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18); + if ((svga->crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/ { - output = 3; - if (crtc[0x53] & 0x20) - mem_sethandler(0xb8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL); + if (svga->crtc[0x53] & 0x20) + mem_sethandler(0xb8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, virge); else - mem_sethandler(0xa8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL); + mem_sethandler(0xa8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, virge); } } -uint8_t s3_virge_mmio_read(uint32_t addr, void *priv) +uint8_t s3_virge_mmio_read(uint32_t addr, void *p) { pclog("MMIO readb %08X\n", addr); return 0xff; } -uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv) +uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p) { pclog("MMIO readw %08X\n", addr); return 0xffff; } -uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv) +uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) { pclog("MMIO readl %08X\n", addr); return 0xffffffff; } -void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv) +void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) { pclog("MMIO writeb %08X %02X\n", addr, val); } -void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv) +void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) { pclog("MMIO writew %08X %04X\n", addr, val); } -void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) +void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) { pclog("MMIO writel %08X %08X\n", addr, val); } -void s3_virge_hwcursor_draw(int displine) +void s3_virge_hwcursor_draw(svga_t *svga, int displine) { int x; uint16_t dat[2]; int xx; - int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y); + pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y); for (x = 0; x < 64; x += 16) { - dat[0] = (vram[svga_hwcursor_latch.addr] << 8) | vram[svga_hwcursor_latch.addr + 1]; - dat[1] = (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3]; + dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; + dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; for (xx = 0; xx < 16; xx++) { - if (offset >= svga_hwcursor_latch.x) + if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x8000)) ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? 0xffffff : 0; else if (dat[1] & 0x8000) ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; -// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]); +// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga->hwcursor_on, dat[0], dat[1]); } offset++; dat[0] <<= 1; dat[1] <<= 1; } - svga_hwcursor_latch.addr += 4; + svga->hwcursor_latch.addr += 4; } } -static uint8_t s3_virge_pci_regs[256]; - -uint8_t s3_virge_pci_read(int func, int addr, void *priv) +uint8_t s3_virge_pci_read(int func, int addr, void *p) { + virge_t *virge = (virge_t *)p; + svga_t *svga = &virge->svga; // pclog("S3 PCI read %08X\n", addr); switch (addr) { case 0x00: return 0x33; /*'S3'*/ case 0x01: return 0x53; - case 0x02: return s3_virge_id_low; - case 0x03: return s3_virge_id_high; + case 0x02: return virge->virge_id_low; + case 0x03: return virge->virge_id_high; case 0x08: return 0; /*Revision ID*/ case 0x09: return 0; /*Programming interface*/ @@ -389,7 +410,7 @@ uint8_t s3_virge_pci_read(int func, int addr, void *priv) case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x11: return 0x00; case 0x12: return 0x00; - case 0x13: return crtc[0x59] & 0xfc; + case 0x13: return svga->crtc[0x59] & 0xfc; case 0x30: return 0x01; /*BIOS ROM address*/ case 0x31: return 0x00; @@ -397,11 +418,14 @@ uint8_t s3_virge_pci_read(int func, int addr, void *priv) case 0x33: return 0x00; } - return s3_virge_pci_regs[addr]; + return virge->pci_regs[addr]; } -void s3_virge_pci_write(int func, int addr, uint8_t val, void *priv) +void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) { + virge_t *virge = (virge_t *)p; + svga_t *svga = &virge->svga; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: @@ -409,59 +433,68 @@ void s3_virge_pci_write(int func, int addr, uint8_t val, void *priv) case 0x3d: case 0x3e: case 0x3f: break; - case 0x13: crtc[0x59] = val & 0xfc; s3_virge_updatemapping(); break; + case 0x13: + svga->crtc[0x59] = val & 0xfc; + s3_virge_updatemapping(virge); + break; } - s3_virge_pci_regs[addr] = val; + virge->pci_regs[addr] = val; } -int s3_virge_init() +void *s3_virge_init() { - s3_virge_pci_regs[4] = 3; - s3_virge_pci_regs[5] = 0; - s3_virge_pci_regs[6] = 0; - s3_virge_pci_regs[7] = 2; - s3_virge_pci_regs[0x3d] = 1; - s3_virge_pci_regs[0x3e] = 4; - s3_virge_pci_regs[0x3f] = 0xff; + virge_t *virge = malloc(sizeof(virge_t)); + memset(virge, 0, sizeof(virge_t)); + + svga_init(&virge->svga, virge, 1 << 22, /*4mb*/ + s3_virge_recalctimings, + s3_virge_in, s3_virge_out, + s3_virge_hwcursor_draw); + + io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + + virge->pci_regs[4] = 3; + virge->pci_regs[5] = 0; + virge->pci_regs[6] = 0; + virge->pci_regs[7] = 2; + virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3e] = 4; + virge->pci_regs[0x3f] = 0xff; - s3_virge_id_high = 0x56; - s3_virge_id_low = 0x31; - s3_virge_rev = 0; - s3_virge_id = 0xe1; + virge->virge_id_high = 0x56; + virge->virge_id_low = 0x31; + virge->virge_rev = 0; + virge->virge_id = 0xe1; - svga_recalctimings_ex = s3_virge_recalctimings; - svga_hwcursor_draw = s3_virge_hwcursor_draw; - - crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5); - crtc[0x37] = 1 | (7 << 5); + virge->svga.crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5); + virge->svga.crtc[0x37] = 1 | (7 << 5); - vrammask = 0x3fffff; - - pci_add(s3_virge_pci_read, s3_virge_pci_write, NULL); + pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); - svga_vram_limit = 4 << 20; /*4mb*/ - return svga_init(); + return virge; } -GFXCARD vid_s3_virge = +void s3_virge_close(void *p) { + virge_t *virge = (virge_t *)p; + + svga_close(&virge->svga); + + free(virge); +} + +void s3_virge_speed_changed(void *p) +{ + virge_t *virge = (virge_t *)p; + + svga_recalctimings(&virge->svga); +} + +device_t s3_virge_device = +{ + "Diamond Stealth 3D 2000 (S3 VIRGE)", s3_virge_init, - /*IO at 3Cx/3Dx*/ - s3_virge_out, - s3_virge_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - svga_poll, - svga_recalctimings, - - svga_write, - video_write_null, - video_write_null, - - svga_read, - video_read_null, - video_read_null + s3_virge_close, + s3_virge_speed_changed, + svga_add_status_info }; - diff --git a/src/vid_s3_virge.h b/src/vid_s3_virge.h new file mode 100644 index 0000000..7b5425a --- /dev/null +++ b/src/vid_s3_virge.h @@ -0,0 +1 @@ +extern device_t s3_virge_device; diff --git a/src/vid_sdac_ramdac.c b/src/vid_sdac_ramdac.c index 156f0f7..2ccbb36 100644 --- a/src/vid_sdac_ramdac.c +++ b/src/vid_sdac_ramdac.c @@ -5,17 +5,7 @@ #include "vid_svga.h" #include "vid_sdac_ramdac.h" -struct -{ - int magic_count; - uint8_t command; - int windex, rindex; - uint16_t regs[256]; - int reg_ff; - int rs2; -} sdac_ramdac; - -void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv) +void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga) { // /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i\n",addr,val,sdac_ramdac.magic_count,CS,pc, sdac_ramdac.rs2); switch (addr) @@ -23,125 +13,125 @@ void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv) case 0x3C6: if (val == 0xff) { - sdac_ramdac.rs2 = 0; - sdac_ramdac.magic_count = 0; + ramdac->rs2 = 0; + ramdac->magic_count = 0; break; } - if (sdac_ramdac.magic_count < 4) break; - if (sdac_ramdac.magic_count == 4) + if (ramdac->magic_count < 4) break; + if (ramdac->magic_count == 4) { - sdac_ramdac.command = val; + ramdac->command = val; // pclog("RAMDAC command reg now %02X\n", val); switch (val >> 4) { - case 2: case 3: case 0xa: bpp = 15; break; - case 4: case 0xe: bpp = 24; break; - case 5: case 6: case 0xc: bpp = 16; break; - case 7: bpp = 32; break; + case 0x2: case 0x3: case 0xa: svga->bpp = 15; break; + case 0x4: case 0xe: svga->bpp = 24; break; + case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; + case 0x7: svga->bpp = 32; break; - case 0: case 1: default: bpp = 8; break; + case 0: case 1: default: svga->bpp = 8; break; } } - //sdac_ramdac.magic_count = 0; + //ramdac->magic_count = 0; break; case 0x3C7: - sdac_ramdac.magic_count = 0; - if (sdac_ramdac.rs2) - sdac_ramdac.rindex = val; + ramdac->magic_count = 0; + if (ramdac->rs2) + ramdac->rindex = val; break; case 0x3C8: - sdac_ramdac.magic_count = 0; - if (sdac_ramdac.rs2) - sdac_ramdac.windex = val; + ramdac->magic_count = 0; + if (ramdac->rs2) + ramdac->windex = val; break; case 0x3C9: - sdac_ramdac.magic_count = 0; - if (sdac_ramdac.rs2) + ramdac->magic_count = 0; + if (ramdac->rs2) { - if (!sdac_ramdac.reg_ff) sdac_ramdac.regs[sdac_ramdac.windex] = (sdac_ramdac.regs[sdac_ramdac.windex] & 0xff00) | val; - else sdac_ramdac.regs[sdac_ramdac.windex] = (sdac_ramdac.regs[sdac_ramdac.windex] & 0x00ff) | (val << 8); - sdac_ramdac.reg_ff = !sdac_ramdac.reg_ff; -// pclog("RAMDAC reg %02X now %04X\n", sdac_ramdac.windex, sdac_ramdac.regs[sdac_ramdac.windex]); - if (!sdac_ramdac.reg_ff) sdac_ramdac.windex++; + if (!ramdac->reg_ff) ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0xff00) | val; + else ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0x00ff) | (val << 8); + ramdac->reg_ff = !ramdac->reg_ff; +// pclog("RAMDAC reg %02X now %04X\n", ramdac->windex, ramdac->regs[ramdac->windex]); + if (!ramdac->reg_ff) ramdac->windex++; } break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t sdac_ramdac_in(uint16_t addr, void *priv) +uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) { uint8_t temp; -// /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i\n",addr,CS,pc, sdac_ramdac.rs2); +// /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i\n",addr,CS,pc, ramdac->rs2); switch (addr) { case 0x3C6: - sdac_ramdac.reg_ff = 0; - if (sdac_ramdac.magic_count < 5) - sdac_ramdac.magic_count++; - if (sdac_ramdac.magic_count == 4) + ramdac->reg_ff = 0; + if (ramdac->magic_count < 5) + ramdac->magic_count++; + if (ramdac->magic_count == 4) { temp = 0x70; /*SDAC ID*/ - sdac_ramdac.rs2 = 1; + ramdac->rs2 = 1; } - if (sdac_ramdac.magic_count == 5) + if (ramdac->magic_count == 5) { - temp = sdac_ramdac.command; - sdac_ramdac.magic_count = 0; + temp = ramdac->command; + ramdac->magic_count = 0; } return temp; case 0x3C7: -// if (sdac_ramdac.magic_count < 4) +// if (ramdac->magic_count < 4) // { - sdac_ramdac.magic_count=0; + ramdac->magic_count=0; // break; // } - if (sdac_ramdac.rs2) return sdac_ramdac.rindex; + if (ramdac->rs2) return ramdac->rindex; break; case 0x3C8: -// if (sdac_ramdac.magic_count < 4) +// if (ramdac->magic_count < 4) // { - sdac_ramdac.magic_count=0; + ramdac->magic_count=0; // break; // } - if (sdac_ramdac.rs2) return sdac_ramdac.windex; + if (ramdac->rs2) return ramdac->windex; break; case 0x3C9: -// if (sdac_ramdac.magic_count < 4) +// if (ramdac->magic_count < 4) // { - sdac_ramdac.magic_count=0; + ramdac->magic_count=0; // break; // } - if (sdac_ramdac.rs2) + if (ramdac->rs2) { - if (!sdac_ramdac.reg_ff) temp = sdac_ramdac.regs[sdac_ramdac.rindex] & 0xff; - else temp = sdac_ramdac.regs[sdac_ramdac.rindex] >> 8; - sdac_ramdac.reg_ff = !sdac_ramdac.reg_ff; - if (!sdac_ramdac.reg_ff) + if (!ramdac->reg_ff) temp = ramdac->regs[ramdac->rindex] & 0xff; + else temp = ramdac->regs[ramdac->rindex] >> 8; + ramdac->reg_ff = !ramdac->reg_ff; + if (!ramdac->reg_ff) { - sdac_ramdac.rindex++; - sdac_ramdac.magic_count = 0; + ramdac->rindex++; + ramdac->magic_count = 0; } return temp; } break; } - return svga_in(addr, NULL); + return svga_in(addr, svga); } -float sdac_getclock(int clock) +float sdac_getclock(int clock, sdac_ramdac_t *ramdac) { float t; int m, n1, n2; -// pclog("SDAC_Getclock %i %04X\n", clock, sdac_ramdac.regs[clock]); +// pclog("SDAC_Getclock %i %04X\n", clock, ramdac->regs[clock]); if (clock == 0) return 25175000.0; if (clock == 1) return 28322000.0; clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ - m = (sdac_ramdac.regs[clock] & 0x7f) + 2; - n1 = ((sdac_ramdac.regs[clock] >> 8) & 0x1f) + 2; - n2 = ((sdac_ramdac.regs[clock] >> 13) & 0x07); + m = (ramdac->regs[clock] & 0x7f) + 2; + n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; + n2 = ((ramdac->regs[clock] >> 13) & 0x07); t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); -// pclog("SDAC clock %i %i %i %f %04X %f %i\n", m, n1, n2, t, sdac_ramdac.regs[2], 14318184.0 * ((float)m / (float)n1), 1 << n2); +// pclog("SDAC clock %i %i %i %f %04X %f %i\n", m, n1, n2, t, ramdac->regs[2], 14318184.0 * ((float)m / (float)n1), 1 << n2); return t; } diff --git a/src/vid_sdac_ramdac.h b/src/vid_sdac_ramdac.h index e5f2756..35c95db 100644 --- a/src/vid_sdac_ramdac.h +++ b/src/vid_sdac_ramdac.h @@ -1,4 +1,14 @@ -void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv); -uint8_t sdac_ramdac_in(uint16_t addr, void *priv); +typedef struct sdac_ramdac_t +{ + int magic_count; + uint8_t command; + int windex, rindex; + uint16_t regs[256]; + int reg_ff; + int rs2; +} sdac_ramdac_t; -float sdac_getclock(int clock); +void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga); +uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga); + +float sdac_getclock(int clock, sdac_ramdac_t *ramdac); diff --git a/src/vid_stg_ramdac.c b/src/vid_stg_ramdac.c index 7ec7b41..82bbf07 100644 --- a/src/vid_stg_ramdac.c +++ b/src/vid_stg_ramdac.c @@ -4,101 +4,114 @@ #include "vid_svga.h" #include "vid_stg_ramdac.h" -struct -{ - int magic_count; - uint8_t command; - int index; - uint8_t regs[256]; -} stg_ramdac; +static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}}; +static int stg_state_write[8] = {0,0,0,0,0,6,7,7}; -int stg_state_read[2][8]={{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}}; -int stg_state_write[8]={0,0,0,0,0,6,7,7}; - -void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv) +void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga) { int didwrite; //if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc); switch (addr) { - case 0x3C6: - switch (stg_ramdac.magic_count) + case 0x3c6: + switch (ramdac->magic_count) { - case 0: case 1: case 2: case 3: break; - case 4: stg_ramdac.command=val; /*pclog("Write RAMDAC command %02X\n",val);*/ break; - case 5: stg_ramdac.index=(stg_ramdac.index&0xFF00)|val; break; - case 6: stg_ramdac.index=(stg_ramdac.index&0xFF)|(val<<8); break; + case 0: case 1: case 2: case 3: + break; + case 4: + ramdac->command = val; + /*pclog("Write RAMDAC command %02X\n",val);*/ + break; + case 5: + ramdac->index = (ramdac->index & 0xff00) | val; + break; + case 6: + ramdac->index = (ramdac->index & 0xff) | (val << 8); + break; case 7: - pclog("Write RAMDAC reg %02X %02X\n", stg_ramdac.index, val); - if (stg_ramdac.index<0x100) stg_ramdac.regs[stg_ramdac.index]=val; - stg_ramdac.index++; + pclog("Write RAMDAC reg %02X %02X\n", ramdac->index, val); + if (ramdac->index < 0x100) + ramdac->regs[ramdac->index] = val; + ramdac->index++; break; } - didwrite = (stg_ramdac.magic_count>=4); - stg_ramdac.magic_count=stg_state_write[stg_ramdac.magic_count&7]; - if (stg_ramdac.command&8) + didwrite = (ramdac->magic_count >= 4); + ramdac->magic_count = stg_state_write[ramdac->magic_count & 7]; + if (ramdac->command & 8) { - switch (stg_ramdac.regs[3]) + switch (ramdac->regs[3]) { - case 0: case 5: case 7: bpp=8; break; - case 1: case 2: case 8: bpp=15; break; - case 3: case 6: bpp=16; break; - case 4: case 9: bpp=24; break; - default: bpp=8; break; + case 0: case 5: case 7: svga->bpp = 8; break; + case 1: case 2: case 8: svga->bpp = 15; break; + case 3: case 6: svga->bpp = 16; break; + case 4: case 9: svga->bpp = 24; break; + default: svga->bpp = 8; break; } } else { - switch (stg_ramdac.command>>5) + switch (ramdac->command >> 5) { - case 0: bpp=8; break; - case 5: bpp=15; break; - case 6: bpp=16; break; - case 7: bpp=24; break; - default: bpp=8; break; + case 0: svga->bpp = 8; break; + case 5: svga->bpp = 15; break; + case 6: svga->bpp = 16; break; + case 7: svga->bpp = 24; break; + default: svga->bpp = 8; break; } } if (didwrite) return; break; - case 0x3C7: case 0x3C8: case 0x3C9: - stg_ramdac.magic_count=0; + case 0x3c7: case 0x3c8: case 0x3c9: + ramdac->magic_count=0; break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t stg_ramdac_in(uint16_t addr, void *priv) +uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga) { uint8_t temp; //if (CS!=0xC000) pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc); switch (addr) { - case 0x3C6: - switch (stg_ramdac.magic_count) + case 0x3c6: + switch (ramdac->magic_count) { - case 0: case 1: case 2: case 3: temp=0xFF; break; - case 4: temp=stg_ramdac.command; break; - case 5: temp=stg_ramdac.index&0xFF; break; - case 6: temp=stg_ramdac.index>>8; break; + case 0: case 1: case 2: case 3: + temp = 0xff; + break; + case 4: + temp = ramdac->command; + break; + case 5: + temp = ramdac->index & 0xff; + break; + case 6: + temp = ramdac->index >> 8; + break; case 7: // pclog("Read RAMDAC index %04X\n",stg_ramdac.index); - switch (stg_ramdac.index) + switch (ramdac->index) { - case 0: temp=0x44; break; - case 1: temp=0x02; break; + case 0: + temp = 0x44; + break; + case 1: + temp = 0x02; + break; default: - if (stg_ramdac.index<0x100) temp=stg_ramdac.regs[stg_ramdac.index]; - else temp=0xFF; + if (ramdac->index < 0x100) temp = ramdac->regs[ramdac->index]; + else temp = 0xff; break; } - stg_ramdac.index++; + ramdac->index++; break; } - stg_ramdac.magic_count=stg_state_read[(stg_ramdac.command&0x10)?1:0][stg_ramdac.magic_count&7]; + ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7]; return temp; - case 0x3C8: case 0x3C9: - stg_ramdac.magic_count=0; + case 0x3c8: case 0x3c9: + ramdac->magic_count=0; break; } - return svga_in(addr, NULL); + return svga_in(addr, svga); } diff --git a/src/vid_stg_ramdac.h b/src/vid_stg_ramdac.h index 64394af..ec11930 100644 --- a/src/vid_stg_ramdac.h +++ b/src/vid_stg_ramdac.h @@ -1,2 +1,10 @@ -void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv); -uint8_t stg_ramdac_in(uint16_t addr, void *priv); +typedef struct stg_ramdac_t +{ + int magic_count; + uint8_t command; + int index; + uint8_t regs[256]; +} stg_ramdac_t; + +void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga); +uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga); diff --git a/src/vid_svga.c b/src/vid_svga.c index df0e1d5..0fafe10 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -1,5 +1,6 @@ /*Generic SVGA handling*/ /*This is intended to be used by another SVGA driver, and not as a card in it's own right*/ +#include #include "ibm.h" #include "mem.h" #include "video.h" @@ -10,322 +11,344 @@ #define svga_output 0 -uint32_t svga_vram_limit; +void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga); extern uint8_t edatlookup[4][4]; -uint8_t svga_miscout; -static uint8_t la, lb, lc, ld; uint8_t svga_rotate[8][256]; -static int svga_fast; -void (*svga_render)(); - -static uint8_t dacmask, dacstatus; - -void svga_out(uint16_t addr, uint8_t val, void *priv) +void svga_out(uint16_t addr, uint8_t val, void *p) { + svga_t *svga = (svga_t *)p; int c; uint8_t o; // printf("OUT SVGA %03X %02X %04X:%04X %i %08X\n",addr,val,CS,pc,TRIDENT,svgawbank); switch (addr) { case 0x3C0: - if (!attrff) - attraddr=val&31; + if (!svga->attrff) + svga->attraddr = val & 31; else { - attrregs[attraddr&31]=val; - if (attraddr<16) fullchange=changeframecount; - if (attraddr==0x10 || attraddr==0x14 || attraddr<0x10) + svga->attrregs[svga->attraddr & 31] = val; + if (svga->attraddr < 16) + svga->fullchange = changeframecount; + if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (c=0;c<16;c++) + for (c = 0; c < 16; c++) { - if (attrregs[0x10]&0x80) egapal[c]=(attrregs[c]&0xF)|((attrregs[0x14]&0xF)<<4); - else egapal[c]=(attrregs[c]&0x3F)|((attrregs[0x14]&0xC)<<4); + if (svga->attrregs[0x10] & 0x80) svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); + else svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); } } - if (attraddr == 0x10) svga_recalctimings(); + if (svga->attraddr == 0x10) + svga_recalctimings(svga); } - attrff^=1; + svga->attrff ^= 1; break; case 0x3C2: - svga_miscout = val; - vres = 0; pallook = pallook256; - vidclock = val & 4; printf("3C2 write %02X\n",val); + svga->miscout = val; + svga->vidclock = val & 4; printf("3C2 write %02X\n",val); if (val & 1) { pclog("Remove mono handler\n"); - io_removehandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL, NULL); + io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); } else { pclog("Set mono handler\n"); - io_sethandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL, NULL); + io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); } break; - case 0x3C4: seqaddr=val; break; + case 0x3C4: + svga->seqaddr = val; + break; case 0x3C5: - if (seqaddr > 0xf) return; - o=seqregs[seqaddr&0xF]; - seqregs[seqaddr&0xF]=val; - if (o!=val && (seqaddr&0xF)==1) svga_recalctimings(); - switch (seqaddr&0xF) + if (svga->seqaddr > 0xf) return; + o = svga->seqregs[svga->seqaddr & 0xf]; + svga->seqregs[svga->seqaddr & 0xf] = val; + if (o != val && (svga->seqaddr & 0xf) == 1) + svga_recalctimings(svga); + switch (svga->seqaddr & 0xf) { case 1: - if (scrblank && !(val&0x20)) - fullchange=3; - scrblank=(scrblank&~0x20)|(val&0x20); - svga_recalctimings(); + if (svga->scrblank && !(val & 0x20)) + svga->fullchange = 3; + svga->scrblank = (svga->scrblank & ~0x20) | (val & 0x20); + svga_recalctimings(svga); + break; + case 2: + svga->writemask = val & 0xf; break; - case 2: writemask=val&0xF; break; case 3: - charset=val&0xF; - charseta=((charset>>2)*0x10000)+2; - charsetb=((charset&3) *0x10000)+2; + svga->charseta = (((val >> 2) & 3) * 0x10000) + 2; + svga->charsetb = ((val & 3) * 0x10000) + 2; break; case 4: - chain4=val&8; /*printf("Chain4 %i %02X\n",val&8,gdcreg[5]&0x60); */ - svga_fast = (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) && chain4; + svga->chain4 = val & 8; + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4; break; } break; - case 0x3c6: dacmask=val; break; - case 0x3C7: dacread=val; dacpos=0; break; - case 0x3C8: dacwrite=val; dacpos=0; break; + case 0x3c6: + svga->dac_mask = val; + break; + case 0x3C7: + svga->dac_read = val; + svga->dac_pos = 0; + break; + case 0x3C8: + svga->dac_write = val; + svga->dac_pos = 0; + break; case 0x3C9: - dacstatus = 0; -/* if (pc == 0x68AD) + svga->dac_status = 0; + svga->fullchange = changeframecount; + switch (svga->dac_pos) { - dumpregs(); - exit(-1); - }*/ - palchange=1; - fullchange=changeframecount; - switch (dacpos) - { - case 0: vgapal[dacwrite].r=val&63; pallook256[dacwrite]=makecol32(vgapal[dacwrite].r*4,vgapal[dacwrite].g*4,vgapal[dacwrite].b*4); dacpos++; break; - case 1: vgapal[dacwrite].g=val&63; pallook256[dacwrite]=makecol32(vgapal[dacwrite].r*4,vgapal[dacwrite].g*4,vgapal[dacwrite].b*4); dacpos++; break; - case 2: vgapal[dacwrite].b=val&63; pallook256[dacwrite]=makecol32(vgapal[dacwrite].r*4,vgapal[dacwrite].g*4,vgapal[dacwrite].b*4); dacpos=0; dacwrite=(dacwrite+1)&255; break; + case 0: + svga->vgapal[svga->dac_write].r = val & 63; + svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r * 4, svga->vgapal[svga->dac_write].g * 4, svga->vgapal[svga->dac_write].b * 4); + svga->dac_pos++; + break; + case 1: + svga->vgapal[svga->dac_write].g = val & 63; + svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r * 4, svga->vgapal[svga->dac_write].g * 4, svga->vgapal[svga->dac_write].b * 4); + svga->dac_pos++; + break; + case 2: + svga->vgapal[svga->dac_write].b = val & 63; + svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r * 4, svga->vgapal[svga->dac_write].g * 4, svga->vgapal[svga->dac_write].b * 4); + svga->dac_pos = 0; + svga->dac_write = (svga->dac_write + 1) & 255; + break; } break; - case 0x3CE: gdcaddr=val; break; + case 0x3CE: + svga->gdcaddr = val; + break; case 0x3CF: - o = gdcreg[gdcaddr & 15]; - switch (gdcaddr&15) + o = svga->gdcreg[svga->gdcaddr & 15]; + switch (svga->gdcaddr & 15) { - case 2: colourcompare=val; break; - case 4: readplane=val&3; break; - case 5: writemode=val&3; readmode=val&8; break; + case 2: svga->colourcompare=val; break; + case 4: svga->readplane=val&3; break; + case 5: svga->writemode=val&3; svga->readmode=val&8; break; case 6: - if ((gdcreg[6] & 0xc) != (val & 0xc)) + pclog("svga_out recalcmapping %p\n", svga); + if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - 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, p); pclog("Write mapping %02X\n", val); switch (val&0xC) { 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, p); break; case 0x4: /*64k at A0000*/ - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, p); break; case 0x8: /*32k at B0000*/ - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, p); break; case 0xC: /*32k at B8000*/ - mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, p); break; } } break; - case 7: colournocare=val; break; + case 7: svga->colournocare=val; break; } - gdcreg[gdcaddr&15]=val; - svga_fast = (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) && chain4; - if (((gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((gdcaddr & 15) == 6 && (val ^ o) & 1)) - svga_recalctimings(); + svga->gdcreg[svga->gdcaddr & 15] = val; + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4; + if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) + svga_recalctimings(svga); break; } } -uint8_t svga_in(uint16_t addr, void *priv) +uint8_t svga_in(uint16_t addr, void *p) { + svga_t *svga = (svga_t *)p; uint8_t temp; // if (addr!=0x3da) pclog("Read port %04X\n",addr); switch (addr) { - case 0x3C0: return attraddr; - case 0x3C1: return attrregs[attraddr]; + case 0x3C0: + return svga->attraddr; + case 0x3C1: + return svga->attrregs[svga->attraddr]; case 0x3c2: - if ((vgapal[0].r + vgapal[0].g + vgapal[0].b) >= 0x50) + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) temp = 0; else temp = 0x10; return temp; - case 0x3C4: return seqaddr; + case 0x3C4: + return svga->seqaddr; case 0x3C5: - return seqregs[seqaddr&0xF]; - case 0x3c6: return dacmask; - case 0x3c7: return dacstatus; - case 0x3C8: return dacwrite; - case 0x3C9: - dacstatus=3; - palchange=1; - switch (dacpos) + return svga->seqregs[svga->seqaddr & 0xF]; + case 0x3c6: return svga->dac_mask; + case 0x3c7: return svga->dac_status; + case 0x3c8: return svga->dac_write; + case 0x3c9: + svga->dac_status = 3; + switch (svga->dac_pos) { - case 0: dacpos++; return vgapal[dacread].r; - case 1: dacpos++; return vgapal[dacread].g; - case 2: dacpos=0; dacread=(dacread+1)&255; return vgapal[(dacread-1)&255].b; + case 0: + svga->dac_pos++; + return svga->vgapal[svga->dac_read].r; + case 1: + svga->dac_pos++; + return svga->vgapal[svga->dac_read].g; + case 2: + svga->dac_pos=0; + svga->dac_read = (svga->dac_read + 1) & 255; + return svga->vgapal[(svga->dac_read - 1) & 255].b; } break; - case 0x3CC: return svga_miscout; - case 0x3CE: return gdcaddr; + case 0x3CC: + return svga->miscout; + case 0x3CE: + return svga->gdcaddr; case 0x3CF: - return gdcreg[gdcaddr&0xF]; + return svga->gdcreg[svga->gdcaddr & 0xf]; case 0x3DA: - attrff=0; - cgastat^=0x30; - return cgastat; + svga->attrff = 0; + svga->cgastat ^= 0x30; + return svga->cgastat; } // printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc); return 0xFF; } -int svga_vtotal, svga_dispend, svga_vsyncstart, svga_split; -int svga_hdisp, svga_htotal, svga_hdisp_time, svga_rowoffset; -int svga_lowres, svga_interlace; -int svga_linedbl, svga_rowcount; -double svga_clock; -uint32_t svga_ma; -void (*svga_recalctimings_ex)() = NULL; -void (*svga_hwcursor_draw)(int displine) = NULL; - -void svga_recalctimings() +void svga_recalctimings(svga_t *svga) { double crtcconst; - double _dispontime, _dispofftime; + double _dispontime, _dispofftime, disptime; + int hdisp_old; - svga_vtotal=crtc[6]; - svga_dispend=crtc[0x12]; - svga_vsyncstart=crtc[0x10]; - svga_split=crtc[0x18]; + svga->vtotal = svga->crtc[6]; + svga->dispend = svga->crtc[0x12]; + svga->vsyncstart = svga->crtc[0x10]; + svga->split = svga->crtc[0x18]; - if (crtc[7]&1) svga_vtotal|=0x100; - if (crtc[7]&32) svga_vtotal|=0x200; - svga_vtotal+=2; + if (svga->crtc[7] & 1) svga->vtotal |= 0x100; + if (svga->crtc[7] & 32) svga->vtotal |= 0x200; + svga->vtotal += 2; + if (svga->crtc[7] & 2) svga->dispend |= 0x100; + if (svga->crtc[7] & 64) svga->dispend |= 0x200; + svga->dispend++; - if (crtc[7]&2) svga_dispend|=0x100; - if (crtc[7]&64) svga_dispend|=0x200; - svga_dispend++; + if (svga->crtc[7] & 4) svga->vsyncstart |= 0x100; + if (svga->crtc[7] & 128) svga->vsyncstart |= 0x200; + svga->vsyncstart++; - if (crtc[7]&4) svga_vsyncstart|=0x100; - if (crtc[7]&128) svga_vsyncstart|=0x200; - svga_vsyncstart++; + if (svga->crtc[7] & 0x10) svga->split|=0x100; + if (svga->crtc[9] & 0x40) svga->split|=0x200; + svga->split++; - if (crtc[7]&0x10) svga_split|=0x100; - if (crtc[9]&0x40) svga_split|=0x200; - svga_split++; + svga->hdisp = svga->crtc[1]; + svga->hdisp++; - svga_hdisp=crtc[1]; - svga_hdisp++; + svga->htotal = svga->crtc[0]; + svga->htotal += 6; /*+6 is required for Tyrian*/ - svga_htotal=crtc[0]; - svga_htotal+=6; /*+6 is required for Tyrian*/ + svga->rowoffset = svga->crtc[0x13]; - svga_rowoffset=crtc[0x13]; - - svga_clock = (vidclock) ? VGACONST2 : VGACONST1; + svga->clock = (svga->vidclock) ? VGACONST2 : VGACONST1; - svga_lowres = attrregs[0x10]&0x40; + svga->lowres = svga->attrregs[0x10] & 0x40; - svga_interlace = 0; + svga->interlace = 0; - svga_ma = (crtc[0xC]<<8)|crtc[0xD]; + svga->ma_latch = (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - svga_hdisp_time = svga_hdisp; - svga_render = svga_render_blank; - if (!scrblank) + svga->hdisp_time = svga->hdisp; + svga->render = svga_render_blank; + if (!svga->scrblank) { - if (!(gdcreg[6]&1)) /*Text mode*/ + if (!(svga->gdcreg[6] & 1)) /*Text mode*/ { - if (seqregs[1]&8) /*40 column*/ + if (svga->seqregs[1] & 8) /*40 column*/ { - svga_render = svga_render_text_40; - svga_hdisp *= (seqregs[1] & 1) ? 16 : 18; + svga->render = svga_render_text_40; + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; } else { - svga_render = svga_render_text_80; - svga_hdisp *= (seqregs[1] & 1) ? 8 : 9; + svga->render = svga_render_text_80; + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; } + svga->hdisp_old = svga->hdisp; } else { - svga_hdisp *= (seqregs[1] & 8) ? 16 : 8; + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->hdisp_old = svga->hdisp; - switch (gdcreg[5]&0x60) + switch (svga->gdcreg[5] & 0x60) { case 0x00: /*16 colours*/ - if (seqregs[1]&8) /*Low res (320)*/ - svga_render = svga_render_4bpp_lowres; + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; else - svga_render = svga_render_4bpp_highres; + svga->render = svga_render_4bpp_highres; break; case 0x20: /*4 colours*/ - svga_render = svga_render_2bpp_lowres; + svga->render = svga_render_2bpp_lowres; break; case 0x40: case 0x60: /*256+ colours*/ - switch (bpp) + switch (svga->bpp) { case 8: - if (svga_lowres) - svga_render = svga_render_8bpp_lowres; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; else { - svga_render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_highres; // svga_hdisp <<= 1; } break; case 15: - if (svga_lowres) - svga_render = svga_render_15bpp_lowres; + if (svga->lowres) + svga->render = svga_render_15bpp_lowres; else { - svga_render = svga_render_15bpp_highres; - svga_hdisp <<= 1; + svga->render = svga_render_15bpp_highres; + svga->hdisp <<= 1; } break; case 16: - if (svga_lowres) - svga_render = svga_render_16bpp_lowres; + if (svga->lowres) + svga->render = svga_render_16bpp_lowres; else { - svga_render = svga_render_16bpp_highres; - svga_hdisp <<= 1; + svga->render = svga_render_16bpp_highres; + svga->hdisp <<= 1; } break; case 24: - if (svga_lowres) + if (svga->lowres) { - svga_render = svga_render_24bpp_lowres; - svga_hdisp = ((svga_hdisp<<3)/3); + svga->render = svga_render_24bpp_lowres; + svga->hdisp = ((svga->hdisp << 3) / 3); } else { - svga_render = svga_render_24bpp_highres; - svga_hdisp = ((svga_hdisp<<3)/3); + svga->render = svga_render_24bpp_highres; + svga->hdisp = ((svga->hdisp << 3) / 3); } break; case 32: - if (svga_lowres) - svga_render = svga_render_32bpp_lowres; + if (svga->lowres) + svga->render = svga_render_32bpp_lowres; else { - svga_render = svga_render_32bpp_highres; - svga_hdisp <<= 1; + svga->render = svga_render_32bpp_highres; + svga->hdisp <<= 1; } break; } @@ -336,253 +359,260 @@ void svga_recalctimings() // pclog("svga_render %08X : %08X %08X %08X %08X %08X %i %i %02X %i %i\n", svga_render, svga_render_text_40, svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8); - svga_linedbl = crtc[9] & 0x80; - svga_rowcount = crtc[9] & 31; - if (svga_recalctimings_ex) svga_recalctimings_ex(); + svga->linedbl = svga->crtc[9] & 0x80; + svga->rowcount = svga->crtc[9] & 31; + if (svga->recalctimings_ex) + svga->recalctimings_ex(svga); - crtcconst=(seqregs[1]&1)?(svga_clock*8.0):(svga_clock*9.0); + crtcconst = (svga->seqregs[1] & 1) ? (svga->clock * 8.0) : (svga->clock * 9.0); - disptime =svga_htotal; - _dispontime = svga_hdisp_time; + disptime = svga->htotal; + _dispontime = svga->hdisp_time; // printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8); - if (seqregs[1]&8) { disptime*=2; _dispontime*=2; } - _dispofftime=disptime-_dispontime; - _dispontime*=crtcconst; - _dispofftime*=crtcconst; + if (svga->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; } + _dispofftime = disptime - _dispontime; + _dispontime *= crtcconst; + _dispofftime *= crtcconst; - dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); -// printf("SVGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4)); -// printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga_vtotal,svga_dispend,(crtc[9]&31)+1,svga_vsyncstart); -// printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*svga_vtotal,(dispontime+dispofftime)*svga_vtotal*70,seqregs[1]); + svga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + svga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); +/* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock); + printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart); + printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]); -// pclog("svga_render %08X\n", svga_render); + pclog("svga->render %08X\n", svga->render);*/ } -void (*svga_render)(); - -uint32_t ma, maback, ca; -static int vc; -int sc; -static int linepos, vslines, linecountff, oddeven; -static int svga_dispon; -int con, coff, cursoron, cgablink; -int scrollcache; - -int svga_hwcursor_on; - -SVGA_HWCURSOR svga_hwcursor, svga_hwcursor_latch; - -int svga_hdisp_on; - -int firstline_draw = 2000, lastline_draw = 0; -int displine; - -void svga_poll() +extern int cyc_total; +void svga_poll(void *p) { + svga_t *svga = (svga_t *)p; int x; - if (!linepos) + if (!svga->linepos) { // if (!(vc & 15)) pclog("VC %i %i\n", vc, GetTickCount()); - if (displine == svga_hwcursor_latch.y && svga_hwcursor_latch.ena) - svga_hwcursor_on = 64 - svga_hwcursor_latch.yoff; - vidtime+=dispofftime; + if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) + svga->hwcursor_on = 64 - svga->hwcursor_latch.yoff; + svga->vidtime += svga->dispofftime; // if (output) printf("Display off %f\n",vidtime); - cgastat|=1; - linepos=1; + svga->cgastat |= 1; + svga->linepos = 1; - if (svga_dispon) + if (svga->dispon) { - svga_hdisp_on=1; + svga->hdisp_on=1; - ma&=vrammask; - if (firstline==2000) firstline=displine; + svga->ma &= svga->vrammask; + if (svga->firstline == 2000) + svga->firstline = svga->displine; - if (svga_hwcursor_on) changedvram[ma >> 10] = changedvram[(ma >> 10) + 1] = 2; + if (svga->hwcursor_on) + svga->changedvram[svga->ma >> 10] = svga->changedvram[(svga->ma >> 10) + 1] = 2; - svga_render(); + svga->render(svga); - if (svga_hwcursor_on) - { - svga_hwcursor_draw(displine); - svga_hwcursor_on--; - } + if (svga->hwcursor_on) + { + svga->hwcursor_draw(svga, svga->displine); + svga->hwcursor_on--; + } - if (lastlinelastline < svga->displine) + svga->lastline = svga->displine; } // pclog("%03i %06X %06X\n",displine,ma,vrammask); - displine++; - if (svga_interlace) displine++; - if ((cgastat&8) && ((displine&15)==(crtc[0x11]&15)) && vslines) + svga->displine++; + if (svga->interlace) + svga->displine++; + if ((svga->cgastat & 8) && ((svga->displine & 15) == (svga->crtc[0x11] & 15)) && svga->vslines) { // printf("Vsync off at line %i\n",displine); - cgastat&=~8; + svga->cgastat &= ~8; } - vslines++; - if (displine>1500) displine=0; + svga->vslines++; + if (svga->displine > 1500) + svga->displine = 0; // pclog("Col is %08X %08X %08X %i %i %08X\n",((uint32_t *)buffer32->line[displine])[320],((uint32_t *)buffer32->line[displine])[321],((uint32_t *)buffer32->line[displine])[322], // displine, vc, ma); } else { // pclog("VC %i ma %05X\n", vc, ma); - vidtime+=dispontime; - -// if (output) printf("Display on %f\n",vidtime); - if (svga_dispon) cgastat&=~1; - svga_hdisp_on=0; - - linepos=0; - if (sc==(crtc[11]&31)) con = 0; - if (svga_dispon) - { - if (svga_linedbl && !linecountff) - { - linecountff=1; - ma=maback; - } - else if (sc == svga_rowcount) - { - linecountff=0; - sc=0; + svga->vidtime += svga->dispontime; - maback += (svga_rowoffset<<3); - if (svga_interlace) maback += (svga_rowoffset<<3); - maback&=vrammask; - ma=maback; +// if (output) printf("Display on %f\n",vidtime); + if (svga->dispon) + svga->cgastat &= ~1; + svga->hdisp_on = 0; + + svga->linepos = 0; + if (svga->sc == (svga->crtc[11] & 31)) + svga->con = 0; + if (svga->dispon) + { + if (svga->linedbl && !svga->linecountff) + { + svga->linecountff = 1; + svga->ma = svga->maback; + } + else if (svga->sc == svga->rowcount) + { + svga->linecountff = 0; + svga->sc = 0; + + svga->maback += (svga->rowoffset << 3); + if (svga->interlace) + svga->maback += (svga->rowoffset << 3); + svga->maback &= svga->vrammask; + svga->ma = svga->maback; } else { - linecountff=0; - sc++; - sc&=31; - ma=maback; + svga->linecountff = 0; + svga->sc++; + svga->sc &= 31; + svga->ma = svga->maback; } } - vc++; - vc&=2047; + svga->vc++; + svga->vc &= 2047; - if (vc==svga_split) + if (svga->vc == svga->split) { // pclog("VC split\n"); - ma=maback=0; - if (attrregs[0x10]&0x20) scrollcache=0; + svga->ma = svga->maback = 0; + if (svga->attrregs[0x10] & 0x20) + svga->scrollcache = 0; } - if (vc==svga_dispend) + if (svga->vc == svga->dispend) { // pclog("VC dispend\n"); - svga_dispon=0; - if (crtc[10] & 0x20) cursoron=0; - else cursoron=cgablink&16; - if (!(gdcreg[6]&1) && !(cgablink&15)) fullchange=2; - cgablink++; + svga->dispon=0; + if (svga->crtc[10] & 0x20) svga->cursoron = 0; + else svga->cursoron = svga->blink & 16; + if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15)) + svga->fullchange = 2; + svga->blink++; - for (x=0;x<2048;x++) if (changedvram[x]) changedvram[x]--; -// memset(changedvram,0,2048); - if (fullchange) fullchange--; - } - if (vc==svga_vsyncstart) - { -// pclog("VC vsync %i %i\n", firstline_draw, lastline_draw); - svga_dispon=0; - cgastat|=8; - /*if (seqregs[1]&8) x=(svga_hdisp*((seqregs[1]&1)?8:9))*2; - else */x = svga_hdisp;//*((seqregs[1]&1)?8:9); - - if (bpp == 16 || bpp == 15) x /= 2; -// if (bpp == 24) x /= 3; - if (bpp == 32) x /= 4; - if (svga_interlace && !oddeven) lastline++; - if (svga_interlace && oddeven) firstline--; - - wx=x; - wy=lastline-firstline; - - - svga_doblit(firstline_draw, lastline_draw + 1); - - readflash=0; - - firstline=2000; - lastline=0; - - firstline_draw = 2000; - lastline_draw = 0; - - oddeven^=1; - - changeframecount=(svga_interlace)?3:2; - vslines=0; - - if (svga_interlace && oddeven) ma = maback = svga_ma + (svga_rowoffset << 1); - else ma = maback = svga_ma; - ca=(crtc[0xE]<<8)|crtc[0xF]; - - ma <<= 2; - maback <<= 2; - ca <<= 2; - - - video_res_x = wx; - video_res_y = wy + 1; - - if (!(gdcreg[6]&1)) /*Text mode*/ + for (x = 0; x < 2048; x++) { - video_res_x /= (seqregs[1] & 1) ? 8 : 9; - video_res_y /= (crtc[9] & 31) + 1; - video_bpp = 0; + if (svga->changedvram[x]) + svga->changedvram[x]--; + } +// memset(changedvram,0,2048); + if (svga->fullchange) + svga->fullchange--; + } + if (svga->vc == svga->vsyncstart) + { + int wx, wy; +// pclog("VC vsync %i %i\n", firstline_draw, lastline_draw); + svga->dispon=0; + svga->cgastat |= 8; + x = svga->hdisp; + + if (svga->bpp == 16 || svga->bpp == 15) x /= 2; + if (svga->bpp == 32) x /= 4; + if (svga->interlace && !svga->oddeven) svga->lastline++; + if (svga->interlace && svga->oddeven) svga->firstline--; + + wx = x; + wy = svga->lastline - svga->firstline; + + + svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga); + + readflash = 0; + + svga->firstline = 2000; + svga->lastline = 0; + + svga->firstline_draw = 2000; + svga->lastline_draw = 0; + + svga->oddeven ^= 1; + + changeframecount = svga->interlace ? 3 : 2; + svga->vslines = 0; + + if (svga->interlace && svga->oddeven) svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1); + else svga->ma = svga->maback = svga->ma_latch; + svga->ca = (svga->crtc[0xe] << 8) | svga->crtc[0xf]; + + svga->ma <<= 2; + svga->maback <<= 2; + svga->ca <<= 2; + + + svga->video_res_x = wx; + svga->video_res_y = wy + 1; + pclog("%i %i %i\n", svga->video_res_x, svga->video_res_y, svga->lowres); + if (!(svga->gdcreg[6] & 1)) /*Text mode*/ + { + svga->video_res_x /= (svga->seqregs[1] & 1) ? 8 : 9; + svga->video_res_y /= (svga->crtc[9] & 31) + 1; + svga->video_bpp = 0; } else { - if (crtc[9] & 0x80) - video_res_y /= 2; - if (!(crtc[0x17] & 1)) - video_res_y *= 2; - video_res_y /= (crtc[9] & 31) + 1; - if ((seqregs[1] & 8) || svga_lowres) - video_res_x /= 2; - switch (gdcreg[5]&0x60) + if (svga->crtc[9] & 0x80) + svga->video_res_y /= 2; + if (!(svga->crtc[0x17] & 1)) + svga->video_res_y *= 2; + svga->video_res_y /= (svga->crtc[9] & 31) + 1; + if (svga->lowres) + svga->video_res_x /= 2; + + switch (svga->gdcreg[5] & 0x60) { - case 0x00: video_bpp = 4; break; - case 0x20: video_bpp = 2; break; - case 0x40: case 0x60: video_bpp = bpp; break; + case 0x00: svga->video_bpp = 4; break; + case 0x20: svga->video_bpp = 2; break; + case 0x40: case 0x60: svga->video_bpp = svga->bpp; break; } } - video_bpp = bpp; // if (svga_interlace && oddeven) ma=maback=ma+(svga_rowoffset<<2); // pclog("Addr %08X vson %03X vsoff %01X %02X %02X %02X %i %i\n",ma,svga_vsyncstart,crtc[0x11]&0xF,crtc[0xD],crtc[0xC],crtc[0x33], svga_interlace, oddeven); } - if (vc==svga_vtotal) + if (svga->vc == svga->vtotal) { // pclog("VC vtotal\n"); // printf("Frame over at line %i %i %i %i\n",displine,vc,svga_vsyncstart,svga_dispend); - vc=0; - sc=0; - svga_dispon=1; - displine=(svga_interlace && oddeven) ? 1 : 0; //(TRIDENT && (crtc[0x1E]&4) && oddeven)?1:0; - scrollcache=attrregs[0x13]&7; - linecountff=0; + svga->vc = 0; + svga->sc = 0; + svga->dispon = 1; + svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; + svga->scrollcache = svga->attrregs[0x13] & 7; + svga->linecountff = 0; - svga_hwcursor_on=0; - svga_hwcursor_latch = svga_hwcursor; + svga->hwcursor_on = 0; + svga->hwcursor_latch = svga->hwcursor; // pclog("Latch HWcursor addr %08X\n", svga_hwcursor_latch.addr); // pclog("ADDR %08X\n",hwcursor_addr); } - if (sc==(crtc[10]&31)) con=1; + if (svga->sc == (svga->crtc[10] & 31)) + svga->con = 1; } // printf("2 %i\n",svga_vsyncstart); +//pclog("svga_poll %i %i %i %i %i %i %i\n", ins, svga->dispofftime, svga->dispontime, svga->vidtime, cyc_total, svga->linepos, svga->vc); } -int svga_init() +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)) { int c, d, e; + + svga->p = p; + for (c = 0; c < 256; c++) { e = c; @@ -592,16 +622,41 @@ int svga_init() e = (e >> 1) | ((e & 1) ? 0x80 : 0); } } - readmode = 0; + svga->readmode = 0; + + svga->crtc[0] = 63; + svga->crtc[6] = 255; + svga->dispontime = 1000 * (1 << TIMER_SHIFT); + svga->dispofftime = 1000 * (1 << TIMER_SHIFT); + svga->bpp = 8; + svga->vram = malloc(memsize); + svga->vram_limit = memsize; + svga->vrammask = memsize - 1; + svga->changedvram = malloc(/*(memsize >> 10) << 1*/0x800000 >> 10); + svga->recalctimings_ex = recalctimings_ex; + svga->video_in = video_in; + svga->video_out = video_out; + svga->hwcursor_draw = hwcursor_draw; +// _svga_recalctimings(svga); + + timer_add(svga_poll, &svga->vidtime, TIMER_ALWAYS_ENABLED, svga); + vramp = svga->vram; return 0; } +void svga_close(svga_t *svga) +{ + free(svga->changedvram); + free(svga->vram); +} + #define egacycles 1 #define egacycles2 1 -void svga_write(uint32_t addr, uint8_t val, void *priv) +void svga_write(uint32_t addr, uint8_t val, void *p) { - uint8_t vala,valb,valc,vald,wm=writemask; - int writemask2 = writemask; + svga_t *svga = (svga_t *)p; + uint8_t vala, valb, valc, vald, wm = svga->writemask; + int writemask2 = svga->writemask; egawrites++; @@ -614,11 +669,11 @@ void svga_write(uint32_t addr, uint8_t val, void *priv) { //if (gdcreg[6]&8) return; addr &= 0xFFFF; - addr += svgawbank; + addr += svga->write_bank; } - if (!(gdcreg[6]&1)) fullchange=2; - if (chain4) + if (!(svga->gdcreg[6] & 1)) svga->fullchange=2; + if (svga->chain4) { writemask2=1<<(addr&3); addr&=~3; @@ -627,155 +682,162 @@ void svga_write(uint32_t addr, uint8_t val, void *priv) { addr<<=2; } - addr&=0x7FFFFF; - if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i\n", addr, addr & 1023, addr >> 10, val, writemask2, writemode, chain4); - changedvram[addr>>10]=changeframecount; + addr &= 0x7fffff; - switch (writemode) + if (addr >= svga->vram_limit) + return; + + if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i %02X\n", addr, addr & 1023, addr >> 10, val, writemask2, svga->writemode, svga->chain4, svga->gdcreg[8]); + svga->changedvram[addr >> 10] = changeframecount; + + switch (svga->writemode) { case 1: - if (writemask2&1) vram[addr]=la; - if (writemask2&2) vram[addr|0x1]=lb; - if (writemask2&4) vram[addr|0x2]=lc; - if (writemask2&8) vram[addr|0x3]=ld; + if (writemask2 & 1) svga->vram[addr] = svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld; break; case 0: - if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val]; - if (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) { - if (writemask2&1) vram[addr]=val; - if (writemask2&2) vram[addr|0x1]=val; - if (writemask2&4) vram[addr|0x2]=val; - if (writemask2&8) vram[addr|0x3]=val; + if (writemask2 & 1) svga->vram[addr] = val; + if (writemask2 & 2) svga->vram[addr | 0x1] = val; + if (writemask2 & 4) svga->vram[addr | 0x2] = val; + if (writemask2 & 8) svga->vram[addr | 0x3] = val; } else { - if (gdcreg[1]&1) vala=(gdcreg[0]&1)?0xFF:0; - else vala=val; - if (gdcreg[1]&2) valb=(gdcreg[0]&2)?0xFF:0; - else valb=val; - if (gdcreg[1]&4) valc=(gdcreg[0]&4)?0xFF:0; - else valc=val; - if (gdcreg[1]&8) vald=(gdcreg[0]&8)?0xFF:0; - else vald=val; + if (svga->gdcreg[1] & 1) vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + else vala = val; + if (svga->gdcreg[1] & 2) valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + else valb = val; + if (svga->gdcreg[1] & 4) valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + else valc = val; + if (svga->gdcreg[1] & 8) vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + else vald = val; - switch (gdcreg[3]&0x18) + switch (svga->gdcreg[3] & 0x18) { case 0: /*Set*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); break; case 8: /*AND*/ - if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; - if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; - if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; - if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; break; case 0x10: /*OR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; break; case 0x18: /*XOR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; break; } // pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); } break; case 2: - if (!(gdcreg[3]&0x18) && !gdcreg[1]) + if (!(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) { - if (writemask2&1) vram[addr]=(((val&1)?0xFF:0)&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(((val&2)?0xFF:0)&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(((val&4)?0xFF:0)&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(((val&8)?0xFF:0)&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); } else { - vala=((val&1)?0xFF:0); - valb=((val&2)?0xFF:0); - valc=((val&4)?0xFF:0); - vald=((val&8)?0xFF:0); - switch (gdcreg[3]&0x18) + vala = ((val & 1) ? 0xff : 0); + valb = ((val & 2) ? 0xff : 0); + valc = ((val & 4) ? 0xff : 0); + vald = ((val & 8) ? 0xff : 0); + switch (svga->gdcreg[3] & 0x18) { case 0: /*Set*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); break; case 8: /*AND*/ - if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; - if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; - if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; - if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; break; case 0x10: /*OR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; break; case 0x18: /*XOR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; break; } } break; case 3: - if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val]; - wm=gdcreg[8]; - gdcreg[8]&=val; + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= val; - vala=(gdcreg[0]&1)?0xFF:0; - valb=(gdcreg[0]&2)?0xFF:0; - valc=(gdcreg[0]&4)?0xFF:0; - vald=(gdcreg[0]&8)?0xFF:0; - switch (gdcreg[3]&0x18) + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + switch (svga->gdcreg[3] & 0x18) { case 0: /*Set*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); break; case 8: /*AND*/ - if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; - if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; - if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; - if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; break; case 0x10: /*OR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; break; case 0x18: /*XOR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; break; } - gdcreg[8]=wm; + svga->gdcreg[8] = wm; break; } } -uint8_t svga_read(uint32_t addr, void *priv) +uint8_t svga_read(uint32_t addr, void *p) { - uint8_t temp,temp2,temp3,temp4; + svga_t *svga = (svga_t *)p; + uint8_t temp, temp2, temp3, temp4; cycles -= video_timing_b; cycles_lost += video_timing_b; @@ -786,52 +848,53 @@ uint8_t svga_read(uint32_t addr, void *priv) else { addr &= 0xFFFF; - addr += svgarbank; + addr += svga->read_bank; } -// pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], readmode); -// pclog("%i\n", readmode); - if (chain4) +// pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode); +// pclog("%i\n", svga->readmode); + if (svga->chain4) { addr &= 0x7fffff; - if (addr >= svga_vram_limit) + if (addr >= svga->vram_limit) return 0xff; - return vram[addr]; + return svga->vram[addr]; } else addr<<=2; addr &= 0x7fffff; - if (addr >= svga_vram_limit) + if (addr >= svga->vram_limit) return 0xff; - la=vram[addr]; - lb=vram[addr|0x1]; - lc=vram[addr|0x2]; - ld=vram[addr|0x3]; - if (readmode) + svga->la = svga->vram[addr]; + svga->lb = svga->vram[addr | 0x1]; + svga->lc = svga->vram[addr | 0x2]; + svga->ld = svga->vram[addr | 0x3]; + if (svga->readmode) { - temp= (colournocare&1) ?0xFF:0; - temp&=la; - temp^=(colourcompare&1)?0xFF:0; - temp2= (colournocare&2) ?0xFF:0; - temp2&=lb; - temp2^=(colourcompare&2)?0xFF:0; - temp3= (colournocare&4) ?0xFF:0; - temp3&=lc; - temp3^=(colourcompare&4)?0xFF:0; - temp4= (colournocare&8) ?0xFF:0; - temp4&=ld; - temp4^=(colourcompare&8)?0xFF:0; - return ~(temp|temp2|temp3|temp4); + temp = (svga->colournocare & 1) ? 0xff : 0; + temp &= svga->la; + temp ^= (svga->colourcompare & 1) ? 0xff : 0; + temp2 = (svga->colournocare & 2) ? 0xff : 0; + temp2 &= svga->lb; + temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; + temp3 = (svga->colournocare & 4) ? 0xff : 0; + temp3 &= svga->lc; + temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; + temp4 = (svga->colournocare & 8) ? 0xff : 0; + temp4 &= svga->ld; + temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; + return ~(temp | temp2 | temp3 | temp4); } -//pclog("Read %02X %04X %04X\n",vram[addr|readplane],addr,readplane); - return vram[addr|readplane]; +//pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); + return svga->vram[addr | svga->readplane]; } -void svga_write_linear(uint32_t addr, uint8_t val, void *priv) +void svga_write_linear(uint32_t addr, uint8_t val, void *p) { - uint8_t vala,valb,valc,vald,wm=writemask; - int writemask2 = writemask; + svga_t *svga = (svga_t *)p; + uint8_t vala, valb, valc, vald, wm = svga->writemask; + int writemask2 = svga->writemask; cycles -= video_timing_b; cycles_lost += video_timing_b; @@ -839,8 +902,9 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *priv) egawrites++; if (svga_output) pclog("Write LFB %08X %02X ", addr, val); - if (!(gdcreg[6]&1)) fullchange=2; - if (chain4) + if (!(svga->gdcreg[6] & 1)) + svga->fullchange = 2; + if (svga->chain4) { writemask2=1<<(addr&3); addr&=~3; @@ -850,201 +914,206 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *priv) addr<<=2; } addr &= 0x7fffff; + if (addr >= svga->vram_limit) + return; if (svga_output) pclog("%08X\n", addr); - changedvram[addr>>10]=changeframecount; + svga->changedvram[addr>>10]=changeframecount; - switch (writemode) + switch (svga->writemode) { case 1: - if (writemask2&1) vram[addr]=la; - if (writemask2&2) vram[addr|0x1]=lb; - if (writemask2&4) vram[addr|0x2]=lc; - if (writemask2&8) vram[addr|0x3]=ld; + if (writemask2 & 1) svga->vram[addr] = svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld; break; case 0: - if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val]; - if (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) { - if (writemask2&1) vram[addr]=val; - if (writemask2&2) vram[addr|0x1]=val; - if (writemask2&4) vram[addr|0x2]=val; - if (writemask2&8) vram[addr|0x3]=val; + if (writemask2 & 1) svga->vram[addr] = val; + if (writemask2 & 2) svga->vram[addr | 0x1] = val; + if (writemask2 & 4) svga->vram[addr | 0x2] = val; + if (writemask2 & 8) svga->vram[addr | 0x3] = val; } else { - if (gdcreg[1]&1) vala=(gdcreg[0]&1)?0xFF:0; - else vala=val; - if (gdcreg[1]&2) valb=(gdcreg[0]&2)?0xFF:0; - else valb=val; - if (gdcreg[1]&4) valc=(gdcreg[0]&4)?0xFF:0; - else valc=val; - if (gdcreg[1]&8) vald=(gdcreg[0]&8)?0xFF:0; - else vald=val; + if (svga->gdcreg[1] & 1) vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + else vala = val; + if (svga->gdcreg[1] & 2) valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + else valb = val; + if (svga->gdcreg[1] & 4) valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + else valc = val; + if (svga->gdcreg[1] & 8) vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + else vald = val; - switch (gdcreg[3]&0x18) + switch (svga->gdcreg[3] & 0x18) { case 0: /*Set*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); break; case 8: /*AND*/ - if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; - if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; - if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; - if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; break; case 0x10: /*OR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; break; case 0x18: /*XOR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; break; } // pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); } break; case 2: - if (!(gdcreg[3]&0x18) && !gdcreg[1]) + if (!(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) { - if (writemask2&1) vram[addr]=(((val&1)?0xFF:0)&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(((val&2)?0xFF:0)&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(((val&4)?0xFF:0)&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(((val&8)?0xFF:0)&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); } else { - vala=((val&1)?0xFF:0); - valb=((val&2)?0xFF:0); - valc=((val&4)?0xFF:0); - vald=((val&8)?0xFF:0); - switch (gdcreg[3]&0x18) + vala = ((val & 1) ? 0xff : 0); + valb = ((val & 2) ? 0xff : 0); + valc = ((val & 4) ? 0xff : 0); + vald = ((val & 8) ? 0xff : 0); + switch (svga->gdcreg[3] & 0x18) { case 0: /*Set*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); break; case 8: /*AND*/ - if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; - if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; - if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; - if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; break; case 0x10: /*OR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; break; case 0x18: /*XOR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; break; } } break; case 3: - if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val]; - wm=gdcreg[8]; - gdcreg[8]&=val; + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= val; - vala=(gdcreg[0]&1)?0xFF:0; - valb=(gdcreg[0]&2)?0xFF:0; - valc=(gdcreg[0]&4)?0xFF:0; - vald=(gdcreg[0]&8)?0xFF:0; - switch (gdcreg[3]&0x18) + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + switch (svga->gdcreg[3] & 0x18) { case 0: /*Set*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); break; case 8: /*AND*/ - if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; - if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; - if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; - if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; break; case 0x10: /*OR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; break; case 0x18: /*XOR*/ - if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; - if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; - if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; - if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; break; } - gdcreg[8]=wm; + svga->gdcreg[8] = wm; break; } } -uint8_t svga_read_linear(uint32_t addr, void *priv) +uint8_t svga_read_linear(uint32_t addr, void *p) { - uint8_t temp,temp2,temp3,temp4; + svga_t *svga = (svga_t *)p; + uint8_t temp, temp2, temp3, temp4; cycles -= video_timing_b; cycles_lost += video_timing_b; egareads++; - if (chain4) + if (svga->chain4) { addr &= 0x7fffff; - if (addr >= svga_vram_limit) + if (addr >= svga->vram_limit) return 0xff; - return vram[addr & 0x7fffff]; + return svga->vram[addr & 0x7fffff]; } else addr<<=2; addr &= 0x7fffff; - if (addr >= svga_vram_limit) + if (addr >= svga->vram_limit) return 0xff; - la=vram[addr]; - lb=vram[addr|0x1]; - lc=vram[addr|0x2]; - ld=vram[addr|0x3]; - if (readmode) + svga->la = svga->vram[addr]; + svga->lb = svga->vram[addr | 0x1]; + svga->lc = svga->vram[addr | 0x2]; + svga->ld = svga->vram[addr | 0x3]; + if (svga->readmode) { - temp= (colournocare&1) ?0xFF:0; - temp&=la; - temp^=(colourcompare&1)?0xFF:0; - temp2= (colournocare&2) ?0xFF:0; - temp2&=lb; - temp2^=(colourcompare&2)?0xFF:0; - temp3= (colournocare&4) ?0xFF:0; - temp3&=lc; - temp3^=(colourcompare&4)?0xFF:0; - temp4= (colournocare&8) ?0xFF:0; - temp4&=ld; - temp4^=(colourcompare&8)?0xFF:0; - return ~(temp|temp2|temp3|temp4); + temp = (svga->colournocare & 1) ? 0xff : 0; + temp &= svga->la; + temp ^= (svga->colourcompare & 1) ? 0xff : 0; + temp2 = (svga->colournocare & 2) ? 0xff : 0; + temp2 &= svga->lb; + temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; + temp3 = (svga->colournocare & 4) ? 0xff : 0; + temp3 &= svga->lc; + temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; + temp4 = (svga->colournocare & 8) ? 0xff : 0; + temp4 &= svga->ld; + temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; + return ~(temp | temp2 | temp3 | temp4); } -//printf("Read %02X %04X %04X\n",vram[addr|readplane],addr,readplane); - return vram[addr|readplane]; +//printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); + return svga->vram[addr | svga->readplane]; } -void svga_doblit(int y1, int y2) +void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) { - frames++; + svga->frames++; // pclog("doblit %i %i\n", y1, y2); if (y1 > y2) { @@ -1060,16 +1129,8 @@ void svga_doblit(int y1, int y2) ysize=wy+1; if (xsize<64) xsize=656; if (ysize<32) ysize=200; -/* if (bpp > 8) - { - if (vres) updatewindowsize(xsize<<1,ysize<<1); - else updatewindowsize(xsize<<1,ysize); - } - else - {*/ - if (vres) updatewindowsize(xsize,ysize<<1); - else updatewindowsize(xsize,ysize); -// } + + updatewindowsize(xsize,ysize); } if (vid_resize) { @@ -1082,12 +1143,15 @@ void svga_doblit(int y1, int y2) } -void svga_writew(uint32_t addr, uint16_t val, void *priv) +void svga_writew(uint32_t addr, uint16_t val, void *p) { - if (!svga_fast) + svga_t *svga = (svga_t *)p; + if (!svga) + exit(-1); + if (!svga->fast) { - svga_write(addr, val, priv); - svga_write(addr + 1, val >> 8, priv); + svga_write(addr, val, p); + svga_write(addr + 1, val >> 8, p); return; } @@ -1097,21 +1161,25 @@ void svga_writew(uint32_t addr, uint16_t val, void *priv) cycles_lost += video_timing_w; if (svga_output) pclog("Writew %05X ", addr); - addr = (addr & 0xffff) + svgawbank; + addr = (addr & 0xffff) + svga->write_bank; addr &= 0x7FFFFF; + if (addr >= svga->vram_limit) + return; if (svga_output) pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val); - changedvram[addr >> 10] = changeframecount; - *(uint16_t *)&vram[addr] = val; + svga->changedvram[addr >> 10] = changeframecount; + *(uint16_t *)&svga->vram[addr] = val; } -void svga_writel(uint32_t addr, uint32_t val, void *priv) +void svga_writel(uint32_t addr, uint32_t val, void *p) { - if (!svga_fast) + svga_t *svga = (svga_t *)p; + + if (!svga->fast) { - svga_write(addr, val, priv); - svga_write(addr + 1, val >> 8, priv); - svga_write(addr + 2, val >> 16, priv); - svga_write(addr + 3, val >> 24, priv); + svga_write(addr, val, p); + svga_write(addr + 1, val >> 8, p); + svga_write(addr + 2, val >> 16, p); + svga_write(addr + 3, val >> 24, p); return; } @@ -1121,18 +1189,22 @@ void svga_writel(uint32_t addr, uint32_t val, void *priv) cycles_lost += video_timing_l; if (svga_output) pclog("Writel %05X ", addr); - addr = (addr & 0xffff) + svgawbank; + addr = (addr & 0xffff) + svga->write_bank; addr &= 0x7FFFFF; + if (addr >= svga->vram_limit) + return; if (svga_output) pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val); - changedvram[addr >> 10] = changeframecount; - *(uint32_t *)&vram[addr] = val; + svga->changedvram[addr >> 10] = changeframecount; + *(uint32_t *)&svga->vram[addr] = val; } -uint16_t svga_readw(uint32_t addr, void *priv) +uint16_t svga_readw(uint32_t addr, void *p) { - if (!svga_fast) - return svga_read(addr, priv) | (svga_read(addr + 1, priv) << 8); + svga_t *svga = (svga_t *)p; + + if (!svga->fast) + return svga_read(addr, p) | (svga_read(addr + 1, p) << 8); egareads += 2; @@ -1140,18 +1212,20 @@ uint16_t svga_readw(uint32_t addr, void *priv) cycles_lost += video_timing_w; // pclog("Readw %05X ", addr); - addr = (addr & 0xffff) + svgarbank; + addr = (addr & 0xffff) + svga->read_bank; addr &= 0x7FFFFF; // pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]); - if (addr >= svga_vram_limit) return 0xffff; + if (addr >= svga->vram_limit) return 0xffff; - return *(uint16_t *)&vram[addr]; + return *(uint16_t *)&svga->vram[addr]; } -uint32_t svga_readl(uint32_t addr, void *priv) +uint32_t svga_readl(uint32_t addr, void *p) { - if (!svga_fast) - return svga_read(addr, priv) | (svga_read(addr + 1, priv) << 8) | (svga_read(addr + 2, priv) << 16) | (svga_read(addr + 3, priv) << 24); + svga_t *svga = (svga_t *)p; + + if (!svga->fast) + return svga_read(addr, p) | (svga_read(addr + 1, p) << 8) | (svga_read(addr + 2, p) << 16) | (svga_read(addr + 3, p) << 24); egareads += 4; @@ -1159,20 +1233,22 @@ uint32_t svga_readl(uint32_t addr, void *priv) cycles_lost += video_timing_l; // pclog("Readl %05X ", addr); - addr = (addr & 0xffff) + svgarbank; + addr = (addr & 0xffff) + svga->read_bank; addr &= 0x7FFFFF; // pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]); - if (addr >= svga_vram_limit) return 0xffffffff; + if (addr >= svga->vram_limit) return 0xffffffff; - return *(uint32_t *)&vram[addr]; + return *(uint32_t *)&svga->vram[addr]; } -void svga_writew_linear(uint32_t addr, uint16_t val, void *priv) +void svga_writew_linear(uint32_t addr, uint16_t val, void *p) { - if (!svga_fast) + svga_t *svga = (svga_t *)p; + + if (!svga->fast) { - svga_write_linear(addr, val, priv); - svga_write_linear(addr + 1, val >> 8, priv); + svga_write_linear(addr, val, p); + svga_write_linear(addr + 1, val >> 8, p); return; } @@ -1183,18 +1259,22 @@ void svga_writew_linear(uint32_t addr, uint16_t val, void *priv) if (svga_output) pclog("Write LFBw %08X %04X\n", addr, val); addr &= 0x7FFFFF; - changedvram[addr >> 10] = changeframecount; - *(uint16_t *)&vram[addr] = val; + if (addr >= svga->vram_limit) + return; + svga->changedvram[addr >> 10] = changeframecount; + *(uint16_t *)&svga->vram[addr] = val; } -void svga_writel_linear(uint32_t addr, uint32_t val, void *priv) +void svga_writel_linear(uint32_t addr, uint32_t val, void *p) { - if (!svga_fast) + svga_t *svga = (svga_t *)p; + + if (!svga->fast) { - svga_write_linear(addr, val, priv); - svga_write_linear(addr + 1, val >> 8, priv); - svga_write_linear(addr + 2, val >> 16, priv); - svga_write_linear(addr + 3, val >> 24, priv); + svga_write_linear(addr, val, p); + svga_write_linear(addr + 1, val >> 8, p); + svga_write_linear(addr + 2, val >> 16, p); + svga_write_linear(addr + 3, val >> 24, p); return; } @@ -1205,14 +1285,18 @@ void svga_writel_linear(uint32_t addr, uint32_t val, void *priv) if (svga_output) pclog("Write LFBl %08X %08X\n", addr, val); addr &= 0x7fffff; - changedvram[addr >> 10] = changeframecount; - *(uint32_t *)&vram[addr] = val; + if (addr >= svga->vram_limit) + return; + svga->changedvram[addr >> 10] = changeframecount; + *(uint32_t *)&svga->vram[addr] = val; } -uint16_t svga_readw_linear(uint32_t addr, void *priv) +uint16_t svga_readw_linear(uint32_t addr, void *p) { - if (!svga_fast) - return svga_read_linear(addr, priv) | (svga_read_linear(addr + 1, priv) << 8); + svga_t *svga = (svga_t *)p; + + if (!svga->fast) + return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8); egareads += 2; @@ -1220,15 +1304,17 @@ uint16_t svga_readw_linear(uint32_t addr, void *priv) cycles_lost += video_timing_w; addr &= 0x7FFFFF; - if (addr >= svga_vram_limit) return 0xffff; + if (addr >= svga->vram_limit) return 0xffff; - return *(uint16_t *)&vram[addr]; + return *(uint16_t *)&svga->vram[addr]; } -uint32_t svga_readl_linear(uint32_t addr, void *priv) +uint32_t svga_readl_linear(uint32_t addr, void *p) { - if (!svga_fast) - return svga_read_linear(addr, priv) | (svga_read_linear(addr + 1, priv) << 8) | (svga_read_linear(addr + 2, priv) << 16) | (svga_read_linear(addr + 3, priv) << 24); + svga_t *svga = (svga_t *)p; + + if (!svga->fast) + return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8) | (svga_read_linear(addr + 2, p) << 16) | (svga_read_linear(addr + 3, p) << 24); egareads += 4; @@ -1236,7 +1322,37 @@ uint32_t svga_readl_linear(uint32_t addr, void *priv) cycles_lost += video_timing_l; addr &= 0x7FFFFF; - if (addr >= svga_vram_limit) return 0xffffffff; + if (addr >= svga->vram_limit) return 0xffffffff; - return *(uint32_t *)&vram[addr]; + return *(uint32_t *)&svga->vram[addr]; +} + + +int svga_add_status_info(char *s, int max_len, void *p) +{ + svga_t *svga = (svga_t *)p; + char temps[128]; + int cur_len = max_len; + int len; + + if (svga->chain4) len = snprintf(s, max_len, "SVGA chained (possibly mode 13h)\n"); + else len = snprintf(s, max_len, "SVGA unchained (possibly mode-X)\n"); + if (len < 0) return; + cur_len -= len; + + if (!svga->video_bpp) strcpy(temps, "SVGA in text mode\n"); + else sprintf(temps, "SVGA colour depth : %i bpp\n", svga->video_bpp); + strncat(s, temps, cur_len); + cur_len -= strlen(temps); + + sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y); + strncat(s, temps, cur_len); + cur_len -= strlen(temps); + + sprintf(temps, "SVGA refresh rate : %i Hz\n\n", svga->frames); + svga->frames = 0; + strncat(s, temps, cur_len); + cur_len -= strlen(temps); + + return max_len - cur_len; } diff --git a/src/vid_svga.h b/src/vid_svga.h index f249295..b1c4f65 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -1,60 +1,123 @@ -/*Vertical timings*/ -extern int svga_vtotal, svga_dispend, svga_vsyncstart, svga_split; -/*Horizontal timings*/ -extern int svga_hdisp, svga_htotal, svga_hdisp_time, svga_rowoffset; -/*Flags - svga_lowres = 1/2 clock in 256+ colour modes, svga_interlace = interlace mode enabled*/ -extern int svga_lowres, svga_interlace; - -extern int svga_linedbl, svga_rowcount; - -/*Status of display on*/ -extern int svga_hdisp_on; - -extern double svga_clock; -extern uint32_t svga_ma; -extern void (*svga_recalctimings_ex)(); - -extern uint8_t svga_miscout; - -extern int svga_init(); -extern void svga_poll(); -extern void svga_recalctimings(); - -typedef struct +typedef struct svga_t { - int ena; - int x, y; - int xoff, yoff; - uint32_t addr; -} SVGA_HWCURSOR; + uint8_t crtcreg; + uint8_t crtc[128]; + uint8_t gdcreg[16]; + int gdcaddr; + uint8_t attrregs[32]; + int attraddr, attrff; + uint8_t seqregs[64]; + int seqaddr; + + uint8_t miscout; + int vidclock; + + uint32_t vram_limit; + + uint8_t la, lb, lc, ld; + + uint8_t dac_mask, dac_status; + int dac_read, dac_write, dac_pos; + + uint8_t cgastat; + + int fast; + uint8_t colourcompare, colournocare; + int readmode, writemode, readplane; + int chain4; + uint8_t writemask; + uint32_t charseta, charsetb; + + uint8_t egapal[16]; + uint32_t pallook[256]; + PALETTE vgapal; + + int vtotal, dispend, vsyncstart, split; + int hdisp, hdisp_old, htotal, hdisp_time, rowoffset; + int lowres, interlace; + int linedbl, rowcount; + double clock; + uint32_t ma_latch; + int bpp; + + int dispontime, dispofftime; + int vidtime; + + uint8_t scrblank; + + int dispon; + int hdisp_on; + + uint32_t ma, maback, ca; + int vc; + int sc; + int linepos, vslines, linecountff, oddeven; + int con, cursoron, blink; + int scrollcache; + + int firstline, lastline; + int firstline_draw, lastline_draw; + int displine; + + uint8_t *vram; + uint8_t *changedvram; + int vrammask; + + uint32_t write_bank, read_bank; + + int fullchange; + + int video_res_x, video_res_y, video_bpp; + int frames, fps; + + struct + { + int ena; + int x, y; + int xoff, yoff; + uint32_t addr; + } hwcursor, hwcursor_latch; + + int hwcursor_on; + + void (*render)(struct svga_t *svga); + void (*recalctimings_ex)(struct svga_t *svga); + + void (*video_out)(uint16_t addr, uint8_t val, void *p); + uint8_t (*video_in) (uint16_t addr, void *p); + + void (*hwcursor_draw)(struct svga_t *svga, int displine); + + void *p; +} svga_t; + +extern int svga_init(svga_t *svga, void *p, int memsize, + void (*recalctimings_ex)(struct svga_t *svga), + uint8_t (*video_in) (uint16_t addr, void *p), + void (*video_out)(uint16_t addr, uint8_t val, void *p), + void (*hwcursor_draw)(struct svga_t *svga, int displine)); +extern void svga_recalctimings(svga_t *svga); -extern SVGA_HWCURSOR svga_hwcursor, svga_hwcursor_latch; -//extern int svga_hwcursor_x, svga_hwcursor_y; -//extern int svga_hwcursor_xoff, svga_hwcursor_yoff; -//extern uint32_t /*svga_hwcursor_addr, */svga_hwcursor_addr_cur; -//extern int svga_hwcursor_ena; extern int svga_hwcursor_on; extern void (*svga_hwcursor_draw)(int displine); -uint8_t svga_read(uint32_t addr, void *priv); -uint16_t svga_readw(uint32_t addr, void *priv); -uint32_t svga_readl(uint32_t addr, void *priv); -void svga_write(uint32_t addr, uint8_t val, void *priv); -void svga_writew(uint32_t addr, uint16_t val, void *priv); -void svga_writel(uint32_t addr, uint32_t val, void *priv); -uint8_t svga_read_linear(uint32_t addr, void *priv); -uint16_t svga_readw_linear(uint32_t addr, void *priv); -uint32_t svga_readl_linear(uint32_t addr, void *priv); -void svga_write_linear(uint32_t addr, uint8_t val, void *priv); -void svga_writew_linear(uint32_t addr, uint16_t val, void *priv); -void svga_writel_linear(uint32_t addr, uint32_t val, void *priv); +uint8_t svga_read(uint32_t addr, void *p); +uint16_t svga_readw(uint32_t addr, void *p); +uint32_t svga_readl(uint32_t addr, void *p); +void svga_write(uint32_t addr, uint8_t val, void *p); +void svga_writew(uint32_t addr, uint16_t val, void *p); +void svga_writel(uint32_t addr, uint32_t val, void *p); +uint8_t svga_read_linear(uint32_t addr, void *p); +uint16_t svga_readw_linear(uint32_t addr, void *p); +uint32_t svga_readl_linear(uint32_t addr, void *p); +void svga_write_linear(uint32_t addr, uint8_t val, void *p); +void svga_writew_linear(uint32_t addr, uint16_t val, void *p); +void svga_writel_linear(uint32_t addr, uint32_t val, void *p); -void svga_doblit(int y1, int y2); - -extern uint32_t svga_vram_limit; +int svga_add_status_info(char *s, int max_len, void *p); extern uint8_t svga_rotate[8][256]; -void svga_out(uint16_t addr, uint8_t val, void *priv); -uint8_t svga_in(uint16_t addr, void *priv); +void svga_out(uint16_t addr, uint8_t val, void *p); +uint8_t svga_in(uint16_t addr, void *p); diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 20a6df6..c64a056 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -3,36 +3,39 @@ #include "vid_svga.h" #include "vid_svga_render.h" -void svga_render_blank() +void svga_render_blank(svga_t *svga) { int x, xx; - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; - for (x=0;xfirstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x < svga->hdisp; x++) { - switch (seqregs[1]&9) + switch (svga->seqregs[1] & 9) { case 0: - for (xx=0;xx<9;xx++) ((uint32_t *)buffer32->line[displine])[(x*9)+xx+32]=0; + for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 9) + xx + 32] = 0; break; case 1: - for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[(x*8)+xx+32]=0; + for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 8) + xx + 32] = 0; break; case 8: - for (xx=0;xx<18;xx++) ((uint32_t *)buffer32->line[displine])[(x*18)+xx+32]=0; + for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 18) + xx + 32] = 0; break; case 9: - for (xx=0;xx<16;xx++) ((uint32_t *)buffer32->line[displine])[(x*16)+xx+32]=0; + for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 16) + xx + 32] = 0; break; } } } -void svga_render_text_40() +void svga_render_text_40(svga_t *svga) { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; if (fullchange) { @@ -41,56 +44,59 @@ void svga_render_text_40() uint8_t chr, attr, dat; uint32_t charaddr; int fg, bg; - int xinc = (seqregs[1] & 1) ? 16 : 18; + int xinc = (svga->seqregs[1] & 1) ? 16 : 18; - for (x=0;xhdisp; x += xinc) { - drawcursor=((ma==ca) && con && cursoron); - chr=vram[(ma<<1)]; - attr=vram[(ma<<1)+4]; - if (attr&8) charaddr=charsetb+(chr*128); - else charaddr=charseta+(chr*128); + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + chr = svga->vram[(svga->ma << 1) & svga->vrammask]; + attr = svga->vram[((svga->ma << 1) + 4) & svga->vrammask]; + if (attr & 8) charaddr = svga->charsetb + (chr * 128); + else charaddr = svga->charseta + (chr * 128); if (drawcursor) { - bg=pallook[egapal[attr&15]]; - fg=pallook[egapal[attr>>4]]; + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; } else { - fg=pallook[egapal[attr&15]]; - bg=pallook[egapal[attr>>4]]; - if (attr&0x80 && attrregs[0x10]&8) + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg=pallook[egapal[(attr>>4)&7]]; - if (cgablink&16) fg=bg; + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; } } - dat=vram[charaddr+(sc<<2)]; - if (seqregs[1]&1) + dat = svga->vram[charaddr + (svga->sc << 2)]; + if (svga->seqregs[1] & 1) { - for (xx=0;xx<8;xx++) - ((uint32_t *)buffer32->line[displine])[(x+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[(x+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + (xx << 1)) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; } else { - for (xx=0;xx<8;xx++) - ((uint32_t *)buffer32->line[displine])[(x+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[(x+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; - if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) - ((uint32_t *)buffer32->line[displine])[(x+32+16)&2047]=((uint32_t *)buffer32->line[displine])[(x+32+17)&2047]=bg; + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + (xx << 1)) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 16) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 17) & 2047] = bg; else - ((uint32_t *)buffer32->line[displine])[(x+32+16)&2047]=((uint32_t *)buffer32->line[displine])[(x+32+17)&2047]=(dat&1)?fg:bg; + ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 16) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 17) & 2047] = (dat & 1) ? fg : bg; } - ma+=4; ma&=vrammask; + svga->ma += 4; + svga->ma &= svga->vrammask; } } } -void svga_render_text_80() +void svga_render_text_80(svga_t *svga) { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; if (fullchange) { @@ -99,388 +105,415 @@ void svga_render_text_80() uint8_t chr, attr, dat; uint32_t charaddr; int fg, bg; - int xinc = (seqregs[1] & 1) ? 8 : 9; + int xinc = (svga->seqregs[1] & 1) ? 8 : 9; - for (x=0;xhdisp; x += xinc) { - drawcursor=((ma==ca) && con && cursoron); - chr=vram[(ma<<1)]; - attr=vram[(ma<<1)+4]; - if (attr&8) charaddr=charsetb+(chr*128); - else charaddr=charseta+(chr*128); + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + chr = svga->vram[(svga->ma << 1) & svga->vrammask]; + attr = svga->vram[((svga->ma << 1) + 4) & svga->vrammask]; + if (attr & 8) charaddr = svga->charsetb + (chr * 128); + else charaddr = svga->charseta + (chr * 128); if (drawcursor) { - bg=pallook[egapal[attr&15]]; - fg=pallook[egapal[attr>>4]]; + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; } else { - fg=pallook[egapal[attr&15]]; - bg=pallook[egapal[attr>>4]]; - if (attr&0x80 && attrregs[0x10]&8) + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg=pallook[egapal[(attr>>4)&7]]; - if (cgablink&16) fg=bg; + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; } } - dat=vram[charaddr+(sc<<2)]; - if (seqregs[1]&1) + dat = svga->vram[charaddr + (svga->sc << 2)]; + if (svga->seqregs[1] & 1) { - for (xx=0;xx<8;xx++) - ((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; } else { - for (xx=0;xx<8;xx++) - ((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; - if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) - ((uint32_t *)buffer32->line[displine])[(x+32+8)&2047]=bg; + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 8) & 2047] = bg; else - ((uint32_t *)buffer32->line[displine])[(x+32+8)&2047]=(dat&1)?fg:bg; + ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 8) & 2047] = (dat & 1) ? fg : bg; } - ma+=4; ma&=vrammask; + svga->ma += 4; + svga->ma &= svga->vrammask; } } } -void svga_render_4bpp_lowres() +void svga_render_4bpp_lowres(svga_t *svga) { int x, offset; uint8_t edat[4], dat; - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - offset=((8-scrollcache)<<1)+16; - for (x = 0; x <= svga_hdisp; x += 16) + offset = ((8 - svga->scrollcache) << 1) + 16; + for (x = 0; x <= svga->hdisp; x += 16) { - edat[0]=vram[ma]; - edat[1]=vram[ma|0x1]; - edat[2]=vram[ma|0x2]; - edat[3]=vram[ma|0x3]; - ma+=4; ma&=vrammask; + edat[0] = svga->vram[svga->ma]; + edat[1] = svga->vram[svga->ma | 0x1]; + edat[2] = svga->vram[svga->ma | 0x2]; + edat[3] = svga->vram[svga->ma | 0x3]; + svga->ma += 4; + svga->ma &= svga->vrammask; - dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2); - ((uint32_t *)buffer32->line[displine])[x+14+offset]=((uint32_t *)buffer32->line[displine])[x+15+offset]=pallook[egapal[dat&0xF]]; - ((uint32_t *)buffer32->line[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[dat>>4]]; - dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2); - ((uint32_t *)buffer32->line[displine])[x+10+offset]=((uint32_t *)buffer32->line[displine])[x+11+offset]=pallook[egapal[dat&0xF]]; - ((uint32_t *)buffer32->line[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[egapal[dat>>4]]; - dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2); - ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[dat&0xF]]; - ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[dat>>4]]; - dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); - ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[dat&0xF]]; - ((uint32_t *)buffer32->line[displine])[x+offset]= ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[dat>>4]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[svga->displine])[x + 14 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 15 + offset] = svga->pallook[svga->egapal[dat & 0xf]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 12 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 13 + offset] = svga->pallook[svga->egapal[dat >> 4]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[svga->displine])[x + 10 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 11 + offset] = svga->pallook[svga->egapal[dat & 0xf]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 8 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 9 + offset] = svga->pallook[svga->egapal[dat >> 4]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[dat & 0xf]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[dat >> 4]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[dat & 0xf]]; + ((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[svga->egapal[dat >> 4]]; } } -void svga_render_4bpp_highres() +void svga_render_4bpp_highres(svga_t *svga) { int x, offset; uint8_t edat[4], dat; - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - offset=(8-scrollcache)+24; - for (x = 0; x <= svga_hdisp; x += 8) + offset = (8 - svga->scrollcache) + 24; + for (x = 0; x <= svga->hdisp; x += 8) { - edat[0]=vram[ma]; - edat[1]=vram[ma|0x1]; - edat[2]=vram[ma|0x2]; - edat[3]=vram[ma|0x3]; - ma+=4; ma&=vrammask; + edat[0] = svga->vram[svga->ma]; + edat[1] = svga->vram[svga->ma | 0x1]; + edat[2] = svga->vram[svga->ma | 0x2]; + edat[3] = svga->vram[svga->ma | 0x3]; + svga->ma += 4; + svga->ma &= svga->vrammask; - dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2); - ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[dat&0xF]]; - ((uint32_t *)buffer32->line[displine])[x+6+offset]=pallook[egapal[dat>>4]]; - dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2); - ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[dat&0xF]]; - ((uint32_t *)buffer32->line[displine])[x+4+offset]=pallook[egapal[dat>>4]]; - dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2); - ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[dat&0xF]]; - ((uint32_t *)buffer32->line[displine])[x+2+offset]=pallook[egapal[dat>>4]]; - dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); - ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[dat&0xF]]; - ((uint32_t *)buffer32->line[displine])[x+offset]= pallook[egapal[dat>>4]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[dat & 0xf]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = svga->pallook[svga->egapal[dat >> 4]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[dat & 0xf]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = svga->pallook[svga->egapal[dat >> 4]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[dat & 0xf]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = svga->pallook[svga->egapal[dat >> 4]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[svga->egapal[dat & 0xf]]; + ((uint32_t *)buffer32->line[svga->displine])[x + offset] = svga->pallook[svga->egapal[dat >> 4]]; } } -void svga_render_2bpp_lowres() +void svga_render_2bpp_lowres(svga_t *svga) { int x, offset; - uint8_t edat[4], dat; + uint8_t edat[2], dat; - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; - offset=((8-scrollcache)<<1)+16; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + offset = ((8 - svga->scrollcache) << 1) + 16; + /*Low res (320) only, though high res (640) should be possible*/ - for (x = 0; x <= svga_hdisp; x += 16) + for (x = 0; x <= svga->hdisp; x += 16) { - if (sc&1 && !(crtc[0x17]&1)) + if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) { - edat[0]=vram[(ma<<1)+0x8000]; - edat[1]=vram[(ma<<1)+0x8004]; + edat[0] = svga->vram[(svga->ma << 1) + 0x8000]; + edat[1] = svga->vram[(svga->ma << 1) + 0x8004]; } else { - edat[0]=vram[(ma<<1)]; - edat[1]=vram[(ma<<1)+4]; + edat[0] = svga->vram[(svga->ma << 1)]; + edat[1] = svga->vram[(svga->ma << 1) + 4]; } - ma+=4; ma&=vrammask; + svga->ma += 4; svga->ma &= svga->vrammask; - ((uint32_t *)buffer32->line[displine])[x+14+offset]=((uint32_t *)buffer32->line[displine])[x+15+offset]=pallook[egapal[edat[1]&3]]; - ((uint32_t *)buffer32->line[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[(edat[1]>>2)&3]]; - dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2); - ((uint32_t *)buffer32->line[displine])[x+10+offset]=((uint32_t *)buffer32->line[displine])[x+11+offset]=pallook[egapal[(edat[1]>>4)&3]]; - ((uint32_t *)buffer32->line[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[egapal[(edat[1]>>6)&3]]; - dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2); - ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[(edat[0]>>0)&3]]; - ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[(edat[0]>>2)&3]]; - dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); - ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[(edat[0]>>4)&3]]; - ((uint32_t *)buffer32->line[displine])[x+offset]= ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[(edat[0]>>6)&3]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 14 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 15 + offset] = svga->pallook[svga->egapal[edat[1] & 3]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 12 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 13 + offset] = svga->pallook[svga->egapal[(edat[1] >> 2) & 3]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 10 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 11 + offset] = svga->pallook[svga->egapal[(edat[1] >> 4) & 3]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 8 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 9 + offset] = svga->pallook[svga->egapal[(edat[1] >> 6) & 3]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[edat[0] & 3]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[(edat[0] >> 2) & 3]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[(edat[0] >> 4) & 3]]; + ((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[svga->egapal[(edat[0] >> 6) & 3]]; } } -void svga_render_8bpp_lowres() +void svga_render_8bpp_lowres(svga_t *svga) { int x, offset; uint8_t edat[4]; - if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) + if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange) { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - offset=(8-(scrollcache&6))+24; + offset = (8 - (svga->scrollcache & 6)) + 24; - for (x = 0; x <= svga_hdisp; x += 8) + for (x = 0; x <= svga->hdisp; x += 8) { - edat[0]=vram[ma]; - edat[1]=vram[ma|0x1]; - edat[2]=vram[ma|0x2]; - edat[3]=vram[ma|0x3]; - ma+=4; ma&=vrammask; - ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[edat[3]]; - ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[edat[2]]; - ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[edat[1]]; - ((uint32_t *)buffer32->line[displine])[x+offset]= ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[edat[0]]; + edat[0] = svga->vram[svga->ma]; + edat[1] = svga->vram[svga->ma | 0x1]; + edat[2] = svga->vram[svga->ma | 0x2]; + edat[3] = svga->vram[svga->ma | 0x3]; + svga->ma += 4; + svga->ma &= svga->vrammask; + ((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[edat[3]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[edat[2]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[edat[1]]; + ((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[edat[0]]; } } } -void svga_render_8bpp_highres() +void svga_render_8bpp_highres(svga_t *svga) { int x, offset; uint8_t edat[4]; - if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) + if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange) { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - offset = (8 - ((scrollcache & 6) >> 1)) + 24; + offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - for (x = 0; x <= svga_hdisp; x += 8) + for (x = 0; x <= svga->hdisp; x += 8) { - edat[0]=vram[ma]; - edat[1]=vram[ma|0x1]; - edat[2]=vram[ma|0x2]; - edat[3]=vram[ma|0x3]; - ma+=4; ma&=vrammask; - ((uint32_t *)buffer32->line[displine])[x+3+offset] = pallook[edat[3]]; - ((uint32_t *)buffer32->line[displine])[x+2+offset] = pallook[edat[2]]; - ((uint32_t *)buffer32->line[displine])[x+1+offset] = pallook[edat[1]]; - ((uint32_t *)buffer32->line[displine])[x+offset] = pallook[edat[0]]; - edat[0]=vram[ma]; - edat[1]=vram[ma|0x1]; - edat[2]=vram[ma|0x2]; - edat[3]=vram[ma|0x3]; - ma+=4; ma&=vrammask; - ((uint32_t *)buffer32->line[displine])[x+7+offset] = pallook[edat[3]]; - ((uint32_t *)buffer32->line[displine])[x+6+offset] = pallook[edat[2]]; - ((uint32_t *)buffer32->line[displine])[x+5+offset] = pallook[edat[1]]; - ((uint32_t *)buffer32->line[displine])[x+4+offset] = pallook[edat[0]]; + edat[0] = svga->vram[svga->ma]; + edat[1] = svga->vram[svga->ma | 0x1]; + edat[2] = svga->vram[svga->ma | 0x2]; + edat[3] = svga->vram[svga->ma | 0x3]; + svga->ma += 4; + svga->ma &= svga->vrammask; + ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[edat[3]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = svga->pallook[edat[2]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[edat[1]]; + ((uint32_t *)buffer32->line[svga->displine])[x + offset] = svga->pallook[edat[0]]; + + edat[0] = svga->vram[svga->ma]; + edat[1] = svga->vram[svga->ma | 0x1]; + edat[2] = svga->vram[svga->ma | 0x2]; + edat[3] = svga->vram[svga->ma | 0x3]; + svga->ma += 4; + svga->ma &= svga->vrammask; + ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[edat[3]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = svga->pallook[edat[2]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[edat[1]]; + ((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = svga->pallook[edat[0]]; } } } -void svga_render_15bpp_lowres() +void svga_render_15bpp_lowres(svga_t *svga) { int x, offset; uint16_t fg, bg; - if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) + if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange) { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - offset=(8-(scrollcache&6))+24; + offset = (8 - (svga->scrollcache & 6)) + 24; - for (x = 0; x <= svga_hdisp; x += 4) + for (x = 0; x <= svga->hdisp; x += 4) { - fg=vram[ma]|(vram[ma|0x1]<<8); - bg=vram[ma|0x2]|(vram[ma|0x3]<<8); - ma+=4; ma&=vrammask; - ((uint32_t *)buffer32->line[displine])[x+2+offset]=((uint32_t *)buffer32->line[displine])[x+3+offset]=((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19); - ((uint32_t *)buffer32->line[displine])[x+0+offset]=((uint32_t *)buffer32->line[displine])[x+1+offset]=((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19); + fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8); + bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8); + svga->ma += 4; + svga->ma &= svga->vrammask; + ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 31) << 11) | (((bg >> 10) & 31) << 19); + ((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((fg & 31) << 3) | (((fg >> 5) & 31) << 11) | (((fg >> 10) & 31) << 19); } } } -void svga_render_15bpp_highres() +void svga_render_15bpp_highres(svga_t *svga) { int x, offset; uint16_t fg, bg; - if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) + if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange) { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - offset = (8 - ((scrollcache & 6) >> 1)) + 24; + offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + + for (x = 0; x <= svga->hdisp; x += 2) + { + fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8); + bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8); + svga->ma += 4; + svga->ma &= svga->vrammask; + ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 31) << 11) | (((bg >> 10) & 31) << 19); + ((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((fg & 31) << 3) | (((fg >> 5) & 31) << 11) | (((fg >> 10) & 31) << 19); + } + } +} + +void svga_render_16bpp_lowres(svga_t *svga) +{ + int x, offset; + uint16_t fg, bg; + + if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange) + { + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + offset = (8 - (svga->scrollcache & 6)) + 24; + + for (x = 0; x <= svga->hdisp; x += 4) + { + fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8); + bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8); + svga->ma += 4; + svga->ma &= svga->vrammask; + ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 63) << 10) | (((bg >> 11) & 31) << 19); + ((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((fg & 31) << 3) | (((fg >> 5) & 63) << 10) | (((fg >> 11) & 31) << 19); + } + } +} + +void svga_render_16bpp_highres(svga_t *svga) +{ + int x, offset; + uint16_t fg, bg; + + if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange) + { + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - for (x = 0; x <= svga_hdisp; x += 2) + for (x = 0; x <= svga->hdisp; x += 2) { - fg=vram[ma]|(vram[ma|0x1]<<8); - bg=vram[ma|0x2]|(vram[ma|0x3]<<8); - ma+=4; ma&=vrammask; - ((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19); - ((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19); + fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8); + bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8); + svga->ma += 4; + svga->ma &= svga->vrammask; + ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 63) << 10) | (((bg >> 11) & 31) << 19); + ((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((fg & 31) << 3) | (((fg >> 5) & 63) << 10) | (((fg >> 11) & 31) << 19); } } } -void svga_render_16bpp_lowres() -{ - int x, offset; - uint16_t fg, bg; - - if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) - { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; - - offset=(8-(scrollcache&6))+24; - - for (x = 0; x <= svga_hdisp; x += 4) - { - fg=vram[ma]|(vram[ma|0x1]<<8); - bg=vram[ma|0x2]|(vram[ma|0x3]<<8); - ma+=4; ma&=vrammask; - ((uint32_t *)buffer32->line[displine])[x+2+offset]=((uint32_t *)buffer32->line[displine])[x+3+offset]=((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19); - ((uint32_t *)buffer32->line[displine])[x+0+offset]=((uint32_t *)buffer32->line[displine])[x+1+offset]=((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19); - } - } -} - -void svga_render_16bpp_highres() -{ - int x, offset; - uint16_t fg, bg; - - if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) - { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; - - offset = (8 - ((scrollcache & 6) >> 1)) + 24; - - for (x = 0; x <= svga_hdisp; x += 2) - { - fg=vram[ma]|(vram[ma|0x1]<<8); - bg=vram[ma|0x2]|(vram[ma|0x3]<<8); - ma+=4; ma&=vrammask; - ((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19); - ((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19); - } - } -} - -void svga_render_24bpp_lowres() +void svga_render_24bpp_lowres(svga_t *svga) { int x, offset; uint32_t fg; - if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) + if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange) { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - offset=(8-(scrollcache&6))+24; + offset = (8 - (svga->scrollcache & 6)) + 24; - for (x = 0; x <= svga_hdisp; x++) + for (x = 0; x <= svga->hdisp; x++) { - fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16); - ma+=3; ma&=vrammask; - ((uint32_t *)buffer32->line[displine])[(x<<1)+offset]=((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=fg; + fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); + svga->ma += 3; + svga->ma &= svga->vrammask; + ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg; } } } -void svga_render_24bpp_highres() +void svga_render_24bpp_highres(svga_t *svga) { int x, offset; uint32_t fg; - if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) + if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange) { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - offset = (8 - ((scrollcache & 6) >> 1)) + 24; + offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - for (x = 0; x <= svga_hdisp; x++) + for (x = 0; x <= svga->hdisp; x++) { - fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16); - ma+=3; ma&=vrammask; - ((uint32_t *)buffer32->line[displine])[x + offset] = fg; + fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); + svga->ma += 3; + svga->ma &= svga->vrammask; + ((uint32_t *)buffer32->line[svga->displine])[x + offset] = fg; } } } -void svga_render_32bpp_lowres() +void svga_render_32bpp_lowres(svga_t *svga) { int x, offset; uint32_t fg; - if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) + if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange) { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - offset=(8-(scrollcache&6))+24; + offset = (8 - (svga->scrollcache & 6)) + 24; - for (x = 0; x <= svga_hdisp; x++) + for (x = 0; x <= svga->hdisp; x++) { - fg = vram[ma] | (vram[ma + 1] << 8) | (vram[ma + 2] << 16); - ma += 4; ma &= vrammask; - ((uint32_t *)buffer32->line[displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[displine])[(x << 1) + 1 + offset] = fg; + fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); + svga->ma += 4; + svga->ma &= svga->vrammask; + ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg; } } } -void svga_render_32bpp_highres() +void svga_render_32bpp_highres(svga_t *svga) { int x, offset; uint32_t fg; - if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) + if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange) { - if (firstline_draw == 2000) firstline_draw = displine; - lastline_draw = displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - offset = (8 - ((scrollcache & 6) >> 1)) + 24; + offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - for (x = 0; x <= svga_hdisp; x++) + for (x = 0; x <= svga->hdisp; x++) { - fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16); - ma+=4; ma&=vrammask; - ((uint32_t *)buffer32->line[displine])[x + offset] = fg; + fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); + svga->ma += 4; + svga->ma &= svga->vrammask; + ((uint32_t *)buffer32->line[svga->displine])[x + offset] = fg; } } } diff --git a/src/vid_svga_render.h b/src/vid_svga_render.h index 63fac70..9ea9508 100644 --- a/src/vid_svga_render.h +++ b/src/vid_svga_render.h @@ -9,22 +9,22 @@ extern int scrollcache; extern uint8_t edatlookup[4][4]; -void svga_render_blank(); -void svga_render_text_40(); -void svga_render_text_80(); +void svga_render_blank(svga_t *svga); +void svga_render_text_40(svga_t *svga); +void svga_render_text_80(svga_t *svga); -void svga_render_2bpp_lowres(); -void svga_render_4bpp_lowres(); -void svga_render_4bpp_highres(); -void svga_render_8bpp_lowres(); -void svga_render_8bpp_highres(); -void svga_render_15bpp_lowres(); -void svga_render_15bpp_highres(); -void svga_render_16bpp_lowres(); -void svga_render_16bpp_highres(); -void svga_render_24bpp_lowres(); -void svga_render_24bpp_highres(); -void svga_render_32bpp_lowres(); -void svga_render_32bpp_highres(); +void svga_render_2bpp_lowres(svga_t *svga); +void svga_render_4bpp_lowres(svga_t *svga); +void svga_render_4bpp_highres(svga_t *svga); +void svga_render_8bpp_lowres(svga_t *svga); +void svga_render_8bpp_highres(svga_t *svga); +void svga_render_15bpp_lowres(svga_t *svga); +void svga_render_15bpp_highres(svga_t *svga); +void svga_render_16bpp_lowres(svga_t *svga); +void svga_render_16bpp_highres(svga_t *svga); +void svga_render_24bpp_lowres(svga_t *svga); +void svga_render_24bpp_highres(svga_t *svga); +void svga_render_32bpp_lowres(svga_t *svga); +void svga_render_32bpp_highres(svga_t *svga); -extern void (*svga_render)(); +extern void (*svga_render)(svga_t *svga); diff --git a/src/vid_tandy.c b/src/vid_tandy.c index 0dc702d..84d00c3 100644 --- a/src/vid_tandy.c +++ b/src/vid_tandy.c @@ -1,138 +1,171 @@ +#include +#include #include "ibm.h" -#include "video.h" +#include "device.h" #include "io.h" #include "mem.h" #include "timer.h" +#include "video.h" +#include "vid_tandy.h" -static int tandy_array_index; -static uint8_t tandy_array[32]; -static int tandy_memctrl=-1; -static uint32_t tandy_base; -static uint8_t tandy_mode,tandy_col; +static int i_filt[8],q_filt[8]; -static uint8_t *tandy_vram, *tandy_b8000; - -void tandy_recalcaddress(); -void tandy_recalctimings(); - -void tandy_out(uint16_t addr, uint8_t val, void *priv) +typedef struct tandy_t { + 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; // pclog("Tandy OUT %04X %02X\n",addr,val); switch (addr) { - case 0x3D4: - crtcreg=val&31; + case 0x3d4: + tandy->crtcreg = val & 0x1f; return; - case 0x3D5: - old=crtc[crtcreg]; - crtc[crtcreg]=val&crtcmask[crtcreg]; - if (old!=val) + case 0x3d5: + old = tandy->crtc[tandy->crtcreg]; + tandy->crtc[tandy->crtcreg] = val & crtcmask[tandy->crtcreg]; + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (tandy->crtcreg < 0xe || tandy->crtcreg > 0x10) { - fullchange=changeframecount; - tandy_recalctimings(); + fullchange = changeframecount; + tandy_recalctimings(tandy); } } return; - case 0x3D8: - tandy_mode=val; + case 0x3d8: + tandy->mode = val; return; - case 0x3D9: - tandy_col=val; + case 0x3d9: + tandy->col = val; return; - case 0x3DA: - tandy_array_index = val & 31; + case 0x3da: + tandy->array_index = val & 0x1f; break; - case 0x3DE: - if (tandy_array_index & 16) val &= 0xF; - tandy_array[tandy_array_index & 31] = val; + case 0x3de: + if (tandy->array_index & 16) + val &= 0xf; + tandy->array[tandy->array_index & 0x1f] = val; break; - case 0x3DF: - tandy_memctrl=val; - tandy_recalcaddress(); + case 0x3df: + tandy->memctrl = val; + tandy_recalcaddress(tandy); break; - case 0xA0: - tandy_base=((val>>1)&7)*128*1024; - tandy_recalcaddress(); + case 0xa0: + tandy->base = ((val >> 1) & 7) * 128 * 1024; + tandy_recalcaddress(tandy); 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); switch (addr) { - case 0x3D4: - return crtcreg; - case 0x3D5: - return crtc[crtcreg]; - case 0x3DA: - return cgastat; + case 0x3d4: + return tandy->crtcreg; + case 0x3d5: + return tandy->crtc[tandy->crtcreg]; + case 0x3da: + return tandy->stat; } 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_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); + tandy->vram = &ram[((tandy->memctrl & 0x06) << 14) + 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); } else { - tandy_vram =&ram[((tandy_memctrl&0x7)<<14) +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); + tandy->vram = &ram[((tandy->memctrl & 0x07) << 14) + 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); } } -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); - 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; -// pclog("Tandy VRAM read %05X %02X %04X:%04X\n",addr,tandy_b8000[addr&0x7FFF],CS,pc); - return tandy_b8000[addr&0x7FFF]; + tandy_t *tandy = (tandy_t *)p; + if (tandy->memctrl == -1) + 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; - if (tandy_mode&1) + double _dispontime, _dispofftime, disptime; + if (tandy->mode & 1) { - disptime=crtc[0]+1; - _dispontime=crtc[1]; + disptime = tandy->crtc[0] + 1; + _dispontime = tandy->crtc[1]; } else { - disptime=(crtc[0]+1)<<1; - _dispontime=crtc[1]<<1; + disptime = (tandy->crtc[0] + 1) << 1; + _dispontime = tandy->crtc[1] << 1; } - _dispofftime=disptime-_dispontime; - _dispontime*=CGACONST; - _dispofftime*=CGACONST; - dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + _dispofftime = disptime - _dispontime; + _dispontime *= CGACONST; + _dispofftime *= CGACONST; + tandy->dispontime = (int)(_dispontime * (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]= { {0,0,0,0,0,0,0,0}, /*Black*/ @@ -145,423 +178,455 @@ static int ntsc_col[8][8]= {1,1,1,1,1,1,1,1} /*White*/ }; -int i_filt[8],q_filt[8]; - /*static 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} };*/ -void tandy_poll() +void tandy_poll(void *p) { -// int *cgapal=cga4pal[((tandy_col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)]; - uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF; +// int *cgapal=cga4pal[((tandy->col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)]; + tandy_t *tandy = (tandy_t *)p; + uint16_t ca = (tandy->crtc[15] | (tandy->crtc[14] << 8)) & 0x3fff; int drawcursor; - int x,c; + int x, c; int oldvc; - uint8_t chr,attr; + uint8_t chr, attr; uint16_t dat; int cols[4]; int col; int oldsc; - int y_buf[8]={0,0,0,0,0,0,0,0},y_val,y_tot; - int i_buf[8]={0,0,0,0,0,0,0,0},i_val,i_tot; - int q_buf[8]={0,0,0,0,0,0,0,0},q_val,q_tot; - int r,g,b; - if (!linepos) + int y_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, y_val, y_tot; + int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_tot; + int q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot; + int r, g, b; + if (!tandy->linepos) { -// cgapal[0]=tandy_col&15; -// printf("Firstline %i Lastline %i Displine %i\n",firstline,lastline,displine); - vidtime+=dispofftime; - cgastat|=1; - linepos=1; - oldsc=sc; - if ((crtc[8]&3)==3) sc=(sc<<1)&7; - if (cgadispon) +// cgapal[0]=tandy->col&15; +// printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine); + tandy->vidtime += tandy->dispofftime; + tandy->stat |= 1; + tandy->linepos = 1; + oldsc = tandy->sc; + if ((tandy->crtc[8] & 3) == 3) + tandy->sc = (tandy->sc << 1) & 7; + if (tandy->dispon) { - if (displinedispline < tandy->firstline) { - firstline=displine; + tandy->firstline = tandy->displine; // printf("Firstline %i\n",firstline); } - lastline=displine; - cols[0]=(tandy_array[2]&0xF)+16; - for (c=0;c<8;c++) + tandy->lastline = tandy->displine; + cols[0] = (tandy->array[2] & 0xf) + 16; + for (c = 0; c < 8; c++) { - if (tandy_array[3]&4) + if (tandy->array[3] & 4) { - buffer->line[displine][c]=cols[0]; - if (tandy_mode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=cols[0]; - else buffer->line[displine][c+(crtc[1]<<4)+8]=cols[0]; + buffer->line[tandy->displine][c] = cols[0]; + if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 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; - if (tandy_mode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0; - else buffer->line[displine][c+(crtc[1]<<4)+8]=0; + buffer->line[tandy->displine][c] = 0; + if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = 0; + else buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = 0; } else { - buffer->line[displine][c]=(tandy_col&15)+16; - if (tandy_mode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(tandy_col&15)+16; - else buffer->line[displine][c+(crtc[1]<<4)+8]=(tandy_col&15)+16; + buffer->line[tandy->displine][c] = (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[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("Drawing %i %i %i\n",displine,vc,sc); - if ((tandy_array[3]&0x10) && (tandy_mode&1)) /*320x200x16*/ +// printf("Drawing %i %i %i\n",tandy->displine,vc,sc); + if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/ { - for (x=0;xcrtc[1]; x++) { - dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)+1]; - ma++; - buffer->line[displine][(x<<3)+8]=buffer->line[displine][(x<<3)+9] =tandy_array[((dat>>12)&tandy_array[1])+16]+16; - buffer->line[displine][(x<<3)+10]=buffer->line[displine][(x<<3)+11]=tandy_array[((dat>>8)&tandy_array[1])+16]+16; - buffer->line[displine][(x<<3)+12]=buffer->line[displine][(x<<3)+13]=tandy_array[((dat>>4)&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; + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; + tandy->ma++; + buffer->line[tandy->displine][(x << 3) + 8] = + buffer->line[tandy->displine][(x << 3) + 9] = tandy->array[((dat >> 12) & 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;xcrtc[1]; x++) { - dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)+1]; - ma++; - 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; - 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[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[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; + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; + tandy->ma++; + buffer->line[tandy->displine][(x << 4) + 8] = + buffer->line[tandy->displine][(x << 4) + 9] = + 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;xcrtc[1]; x++) { - dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)+1]; - ma++; - for (c=0;c<8;c++) + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; + tandy->ma++; + for (c = 0; c < 8; c++) { - chr=(dat>>7)&1; - chr|=((dat>>14)&2); - buffer->line[displine][(x<<3)+8+c]=tandy_array[(chr&tandy_array[1])+16]+16; - dat<<=1; + chr = (dat >> 7) & 1; + chr |= ((dat >> 14) & 2); + buffer->line[tandy->displine][(x << 3) + 8 + c] = tandy->array[(chr & tandy->array[1]) + 16] + 16; + dat <<= 1; } } } - else if (tandy_mode&1) + else if (tandy->mode & 1) { - for (x=0;xcrtc[1]; x++) { - chr=tandy_vram[(ma<<1)&0x3FFF]; - attr=tandy_vram[((ma<<1)+1)&0x3FFF]; - drawcursor=((ma==ca) && con && cursoron); - if (tandy_mode&0x20) + chr = tandy->vram[ (tandy->ma << 1) & 0x3fff]; + attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff]; + drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); + if (tandy->mode & 0x20) { - cols[1]=tandy_array[((attr&15)&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]; + cols[1] = tandy->array[ ((attr & 15) & tandy->array[1]) + 16] + 16; + cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16] + 16; + if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; } else { - cols[1]=tandy_array[((attr&15)&tandy_array[1])+16]+16; - cols[0]=tandy_array[((attr>>4)&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; } - if (sc&8) + if (tandy->sc & 8) { - for (c=0;c<8;c++) - buffer->line[displine][(x<<3)+c+8]=cols[0]; + for (c = 0; c < 8; c++) + buffer->line[tandy->displine][(x << 3) + c + 8] = cols[0]; } else { - for (c=0;c<8;c++) - buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]; + for (c = 0; c < 8; c++) + buffer->line[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 (drawcursor) { - for (c=0;c<8;c++) - buffer->line[displine][(x<<3)+c+8]^=15; + for (c = 0; c < 8; c++) + 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;xcrtc[1]; x++) { - chr=tandy_vram[(ma<<1)&0x3FFF]; - attr=tandy_vram[((ma<<1)+1)&0x3FFF]; - drawcursor=((ma==ca) && con && cursoron); - if (tandy_mode&0x20) + chr = tandy->vram[ (tandy->ma << 1) & 0x3fff]; + attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff]; + drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); + if (tandy->mode & 0x20) { - cols[1]=tandy_array[((attr&15)&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]; + cols[1] = tandy->array[ ((attr & 15) & tandy->array[1]) + 16] + 16; + cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16] + 16; + if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; } else { - cols[1]=tandy_array[((attr&15)&tandy_array[1])+16]+16; - cols[0]=tandy_array[((attr>>4)&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; } - ma++; - if (sc&8) + tandy->ma++; + if (tandy->sc & 8) { - 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]; + for (c = 0; c < 8; c++) + buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] = + buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[0]; } else { - for (c=0;c<8;c++) - buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]; + for (c = 0; c < 8; c++) + buffer->line[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) { - for (c=0;c<16;c++) - buffer->line[displine][(x<<4)+c+8]^=15; + for (c = 0; c < 16; c++) + 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; - col=(tandy_col&16)?24:16; - if (tandy_mode&4) + cols[0] = (tandy->col & 15) | 16; + col = (tandy->col & 16) ? 24 : 16; + if (tandy->mode & 4) { - cols[1]=col|3; - cols[2]=col|4; - cols[3]=col|7; + cols[1] = col | 3; + cols[2] = col | 4; + cols[3] = col | 7; } - else if (tandy_col&32) + else if (tandy->col & 32) { - cols[1]=col|3; - cols[2]=col|5; - cols[3]=col|7; + cols[1] = col | 3; + cols[2] = col | 5; + cols[3] = col | 7; } else { - cols[1]=col|2; - cols[2]=col|4; - cols[3]=col|6; + cols[1] = col | 2; + cols[2] = col | 4; + cols[3] = col | 6; } - for (x=0;xcrtc[1]; x++) { - dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1]; - ma++; - for (c=0;c<8;c++) + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; + tandy->ma++; + for (c = 0; c < 8; c++) { - buffer->line[displine][(x<<4)+(c<<1)+8]= - buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14]; - dat<<=2; + buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] = + buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + dat <<= 2; } } } else { - cols[0]=0; cols[1]=tandy_array[(tandy_col&tandy_array[1])+16]+16; - for (x=0;xarray[(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]; - ma++; - for (c=0;c<16;c++) + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; + tandy->ma++; + for (c = 0; c < 16; c++) { - buffer->line[displine][(x<<4)+c+8]=cols[dat>>15]; - dat<<=1; + buffer->line[tandy->displine][(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; } } } } 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); - else hline(buffer,0,displine,(crtc[1]<<4)+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, tandy->displine, (tandy->crtc[1] << 4) + 16, (tandy->array[2] & 0xf) + 16); } else { - cols[0]=((tandy_mode&0x12)==0x12)?0:(tandy_col&15)+16; - if (tandy_mode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]); - else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]); + cols[0] = ((tandy->mode & 0x12) == 0x12) ? 0 : (tandy->col & 0xf) + 16; + if (tandy->mode & 1) hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 3) + 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; - else x=(crtc[1]<<4)+16; + if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16; + else x = (tandy->crtc[1] << 4) + 16; if (cga_comp) { - for (c=0;cline[displine][c]&7][(c<<1)&6]?0x6000:0; - y_buf[(c<<1)&6]+=(buffer->line[displine][c]&8)?0x3000:0; - i_buf[(c<<1)&6]=y_buf[(c<<1)&6]*i_filt[(c<<1)&6]; - q_buf[(c<<1)&6]=y_buf[(c<<1)&6]*q_filt[(c<<1)&6]; - y_tot=y_buf[0]+y_buf[1]+y_buf[2]+y_buf[3]+y_buf[4]+y_buf[5]+y_buf[6]+y_buf[7]; - i_tot=i_buf[0]+i_buf[1]+i_buf[2]+i_buf[3]+i_buf[4]+i_buf[5]+i_buf[6]+i_buf[7]; - q_tot=q_buf[0]+q_buf[1]+q_buf[2]+q_buf[3]+q_buf[4]+q_buf[5]+q_buf[6]+q_buf[7]; + y_buf[(c << 1) & 6] = ntsc_col[buffer->line[tandy->displine][c] & 7][(c << 1) & 6] ? 0x6000 : 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]; + q_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * q_filt[(c << 1) & 6]; + y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7]; + i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7]; + q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7]; - y_val=y_tot>>10; - if (y_val>255) y_val=255; - y_val<<=16; - i_val=i_tot>>12; - if (i_val>39041) i_val=39041; - if (i_val<-39041) i_val=-39041; - q_val=q_tot>>12; - if (q_val>34249) q_val=34249; - if (q_val<-34249) q_val=-34249; + y_val = y_tot >> 10; + if (y_val > 255) y_val = 255; + y_val <<= 16; + i_val = i_tot >> 12; + if (i_val > 39041) i_val = 39041; + if (i_val < -39041) i_val = -39041; + q_val = q_tot >> 12; + if (q_val > 34249) q_val = 34249; + if (q_val < -34249) q_val = -34249; - r=(y_val+249*i_val+159*q_val)>>16; - g=(y_val-70*i_val-166*q_val)>>16; - b=(y_val-283*i_val+436*q_val)>>16; -// if (r>255) r=255; -// if (g>255) g=255; -// if (b>255) b=255; + r = (y_val + 249*i_val + 159*q_val) >> 16; + g = (y_val - 70*i_val - 166*q_val) >> 16; + b = (y_val - 283*i_val + 436*q_val) >> 16; - y_buf[((c<<1)&6)+1]=ntsc_col[buffer->line[displine][c]&7][((c<<1)&6)+1]?0x6000:0; - y_buf[((c<<1)&6)+1]+=(buffer->line[displine][c]&8)?0x3000:0; - i_buf[((c<<1)&6)+1]=y_buf[((c<<1)&6)+1]*i_filt[((c<<1)&6)+1]; - q_buf[((c<<1)&6)+1]=y_buf[((c<<1)&6)+1]*q_filt[((c<<1)&6)+1]; - y_tot=y_buf[0]+y_buf[1]+y_buf[2]+y_buf[3]+y_buf[4]+y_buf[5]+y_buf[6]+y_buf[7]; - i_tot=i_buf[0]+i_buf[1]+i_buf[2]+i_buf[3]+i_buf[4]+i_buf[5]+i_buf[6]+i_buf[7]; - q_tot=q_buf[0]+q_buf[1]+q_buf[2]+q_buf[3]+q_buf[4]+q_buf[5]+q_buf[6]+q_buf[7]; + y_buf[((c << 1) & 6) + 1] = ntsc_col[buffer->line[tandy->displine][c] & 7][((c << 1) & 6) + 1] ? 0x6000 : 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]; + q_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * q_filt[((c << 1) & 6) + 1]; + y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7]; + i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7]; + q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7]; - y_val=y_tot>>10; - if (y_val>255) y_val=255; - y_val<<=16; - i_val=i_tot>>12; - if (i_val>39041) i_val=39041; - if (i_val<-39041) i_val=-39041; - q_val=q_tot>>12; - if (q_val>34249) q_val=34249; - if (q_val<-34249) q_val=-34249; + y_val = y_tot >> 10; + if (y_val > 255) y_val = 255; + y_val <<= 16; + i_val = i_tot >> 12; + if (i_val > 39041) i_val = 39041; + if (i_val < -39041) i_val = -39041; + q_val = q_tot >> 12; + if (q_val > 34249) q_val = 34249; + if (q_val < -34249) q_val = -34249; - r+=(y_val+249*i_val+159*q_val)>>16; - g+=(y_val-70*i_val-166*q_val)>>16; - b+=(y_val-283*i_val+436*q_val)>>16; - if (r>511) r=511; - if (g>511) g=511; - if (b>511) b=511; + r = (y_val + 249*i_val + 159*q_val) >> 16; + g = (y_val - 70*i_val - 166*q_val) >> 16; + b = (y_val - 283*i_val + 436*q_val) >> 16; + if (r > 511) r = 511; + if (g > 511) g = 511; + if (b > 511) b = 511; - ((uint32_t *)buffer32->line[displine])[c]=makecol32(r/2,g/2,b/2); + ((uint32_t *)buffer32->line[tandy->displine])[c] = makecol32(r / 2, g / 2, b / 2); } } - sc=oldsc; - if (vc==crtc[7] && !sc) + tandy->sc = oldsc; + if (tandy->vc == tandy->crtc[7] && !tandy->sc) { - cgastat|=8; + tandy->stat |= 8; // printf("VSYNC on %i %i\n",vc,sc); } - displine++; - if (displine>=360) displine=0; + tandy->displine++; + if (tandy->displine >= 360) + tandy->displine = 0; } else { - vidtime+=dispontime; - if (cgadispon) cgastat&=~1; - linepos=0; - if (vsynctime) + tandy->vidtime += tandy->dispontime; + if (tandy->dispon) + tandy->stat &= ~1; + tandy->linepos = 0; + if (tandy->vsynctime) { - vsynctime--; - if (!vsynctime) + tandy->vsynctime--; + if (!tandy->vsynctime) { - cgastat&=~8; + tandy->stat &= ~8; // 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 (vadj) + if (tandy->sc == (tandy->crtc[11] & 31) || ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[11] & 31) >> 1))) + { + tandy->con = 0; + tandy->coff = 1; + } + if (tandy->vadj) { - sc++; - sc&=31; - ma=maback; - vadj--; - if (!vadj) + tandy->sc++; + tandy->sc &= 31; + tandy->ma = tandy->maback; + tandy->vadj--; + if (!tandy->vadj) { - cgadispon=1; - ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF; - sc=0; + tandy->dispon = 1; + tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; + tandy->sc = 0; // 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; // coff=0; - sc=0; - oldvc=vc; - vc++; - vc&=127; -// printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],cgadispon); - if (vc==crtc[6]) cgadispon=0; - if (oldvc==crtc[4]) + tandy->sc = 0; + oldvc = tandy->vc; + tandy->vc++; + tandy->vc &= 127; +// printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],tandy->dispon); + if (tandy->vc == tandy->crtc[6]) + tandy->dispon = 0; + if (oldvc == tandy->crtc[4]) { -// printf("Display over at %i\n",displine); - vc=0; - vadj=crtc[5]; - if (!vadj) cgadispon=1; - if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF; - if ((crtc[10]&0x60)==0x20) cursoron=0; - else cursoron=cgablink&16; +// printf("Display over at %i\n",tandy->displine); + tandy->vc = 0; + tandy->vadj = tandy->crtc[5]; + if (!tandy->vadj) + tandy->dispon = 1; + if (!tandy->vadj) + 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); } - if (vc==crtc[7]) + if (tandy->vc == tandy->crtc[7]) { - cgadispon=0; - displine=0; - vsynctime=16;//(crtc[3]>>4)+1; -// printf("Vsynctime %i %02X\n",vsynctime,crtc[3]); -// cgastat|=8; - if (crtc[7]) + tandy->dispon = 0; + tandy->displine = 0; + tandy->vsynctime = 16;//(crtc[3]>>4)+1; +// printf("tandy->vsynctime %i %02X\n",tandy->vsynctime,crtc[3]); +// tandy->stat|=8; + if (tandy->crtc[7]) { // 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; - else x=(crtc[1]<<4)+16; - lastline++; - if (x!=xsize || (lastline-firstline)!=ysize) + if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16; + else x = (tandy->crtc[1] << 4) + 16; + tandy->lastline++; + if (x != xsize || (tandy->lastline - tandy->firstline) != ysize) { - xsize=x; - ysize=lastline-firstline; + xsize = x; + ysize = tandy->lastline - tandy->firstline; // printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtc[1]); - if (xsize<64) xsize=656; - if (ysize<32) ysize=200; - updatewindowsize(xsize,(ysize<<1)+16); + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + updatewindowsize(xsize, (ysize << 1) + 16); } // printf("Blit %i %i\n",firstline,lastline); //printf("Xsize is %i\n",xsize); startblit(); 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 - 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(); frames++; video_res_x = xsize - 16; 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_bpp = 4; } - else if (tandy_array[3]&0x10) /*160x200x16*/ + else if (tandy->array[3] & 0x10) /*160x200x16*/ { video_res_x /= 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; - else if (tandy_mode&1) + else if (tandy->mode & 1) { video_res_x /= 8; - video_res_y /= crtc[9] + 1; + video_res_y /= tandy->crtc[9] + 1; video_bpp = 0; } - else if (!(tandy_mode&2)) + else if (!(tandy->mode & 2)) { video_res_x /= 16; - video_res_y /= crtc[9] + 1; + video_res_y /= tandy->crtc[9] + 1; video_bpp = 0; } - else if (!(tandy_mode&16)) + else if (!(tandy->mode & 16)) { video_res_x /= 2; video_bpp = 2; @@ -569,47 +634,63 @@ void tandy_poll() else video_bpp = 1; } - firstline=1000; - lastline=0; - cgablink++; + tandy->firstline = 1000; + tandy->lastline = 0; + tandy->blink++; } } else { - sc++; - sc&=31; - ma=maback; + tandy->sc++; + tandy->sc &= 31; + 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); - io_sethandler(0x00a0, 0x0002, tandy_in, NULL, NULL, tandy_out, NULL, NULL, NULL); - tandy_memctrl = -1; - return 0; + int c; + int tandy_tint = -2; + tandy_t *tandy = malloc(sizeof(tandy_t)); + 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, - /*IO at 3Cx/3Dx*/ - tandy_out, - tandy_in, - /*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 + tandy_close, + tandy_speed_changed, + NULL }; diff --git a/src/vid_tandy.h b/src/vid_tandy.h new file mode 100644 index 0000000..f0a386f --- /dev/null +++ b/src/vid_tandy.h @@ -0,0 +1 @@ +extern device_t tandy_device; diff --git a/src/vid_tkd8001_ramdac.c b/src/vid_tkd8001_ramdac.c index f15d0e5..4eb6bc6 100644 --- a/src/vid_tkd8001_ramdac.c +++ b/src/vid_tkd8001_ramdac.c @@ -7,29 +7,29 @@ static int tkd8001_state=0; static uint8_t tkd8001_ctrl; -void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv) +void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga) { // pclog("OUT RAMDAC %04X %02X %04X:%04X\n",addr,val,CS,pc); switch (addr) { case 0x3C6: - if (tkd8001_state == 4) + if (ramdac->state == 4) { - tkd8001_state = 0; - tkd8001_ctrl = val; - switch (val>>5) + ramdac->state = 0; + ramdac->ctrl = val; + switch (val >> 5) { case 0: case 1: case 2: case 3: - bpp = 8; + svga->bpp = 8; break; case 5: - bpp = 15; + svga->bpp = 15; break; case 6: - bpp = 24; + svga->bpp = 24; break; case 7: - bpp = 16; + svga->bpp = 16; break; } return; @@ -37,28 +37,28 @@ void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv) // tkd8001_state = 0; break; case 0x3C7: case 0x3C8: case 0x3C9: - tkd8001_state = 0; + ramdac->state = 0; break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv) +uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga) { // pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc); switch (addr) { case 0x3C6: - if (tkd8001_state == 4) + if (ramdac->state == 4) { //tkd8001_state = 0; - return tkd8001_ctrl; + return ramdac->ctrl; } - tkd8001_state++; + ramdac->state++; break; case 0x3C7: case 0x3C8: case 0x3C9: - tkd8001_state = 0; + ramdac->state = 0; break; } - return svga_in(addr, NULL); + return svga_in(addr, svga); } diff --git a/src/vid_tkd8001_ramdac.h b/src/vid_tkd8001_ramdac.h index 1cf083e..4b2afe3 100644 --- a/src/vid_tkd8001_ramdac.h +++ b/src/vid_tkd8001_ramdac.h @@ -1,2 +1,8 @@ -void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv); -uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv); +typedef struct tkd8001_ramdac_t +{ + int state; + uint8_t ctrl; +} tkd8001_ramdac_t; + +void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga); +uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga); diff --git a/src/vid_tvga.c b/src/vid_tvga.c index e07d010..99a999d 100644 --- a/src/vid_tvga.c +++ b/src/vid_tvga.c @@ -1,20 +1,52 @@ /*Trident TVGA (8900D) emulation*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_tkd8001_ramdac.h" +#include "vid_tvga.h" -void tvga_recalcmapping(); +typedef struct tvga_t +{ + svga_t svga; + tkd8001_ramdac_t ramdac; -uint8_t trident3d8,trident3d9; -int tridentoldmode; -uint8_t tridentoldctrl2,tridentnewctrl2; -uint8_t tridentdac; + struct + { + uint16_t src_x, src_y; + uint16_t dst_x, dst_y; + uint16_t size_x, size_y; + uint16_t fg_col, bg_col; + uint8_t rop; + uint16_t flags; + uint8_t pattern[0x80]; + int command; + int offset; + uint8_t ger22; + + int x, y; + uint32_t src, dst, src_old, dst_old; + int pat_x, pat_y; + int use_src; + + int pitch, bpp; + + uint16_t tvga_pattern[8][8]; + } accel; + + uint8_t tvga_3d8, tvga_3d9; + int oldmode; + uint8_t oldctrl2,newctrl2; + + uint32_t linear_base, linear_size; +} tvga_t; + +void tvga_recalcmapping(tvga_t *tvga); -uint32_t tvga_linear_base, tvga_linear_size; uint8_t tvga_accel_read(uint32_t addr, void *priv); uint16_t tvga_accel_read_w(uint32_t addr, void *priv); @@ -27,25 +59,39 @@ void tvga_accel_write_l(uint32_t addr, uint32_t val, void *priv); void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv); -void tvga_out(uint16_t addr, uint8_t val, void *priv) +void tvga_out(uint16_t addr, uint8_t val, void *p) { + tvga_t *tvga = (tvga_t *)p; + svga_t *svga = &tvga->svga; + uint8_t old; // pclog("tvga_out : %04X %02X %04X:%04X %i\n", addr, val, CS,pc, bpp); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { case 0x3C5: - switch (seqaddr&0xF) + switch (svga->seqaddr & 0xf) { - case 0xB: tridentoldmode=1; break; - case 0xC: if (seqregs[0xE]&0x80) seqregs[0xC]=val; break; - case 0xD: if (tridentoldmode) { tridentoldctrl2=val; rowdbl=val&0x10; } else tridentnewctrl2=val; break; + case 0xB: + tvga->oldmode=1; + break; + case 0xC: + if (svga->seqregs[0xe] & 0x80) + svga->seqregs[0xc] = val; + break; + case 0xd: + if (tvga->oldmode) + tvga->oldctrl2 = val; + else + tvga->newctrl2=val; + break; case 0xE: - seqregs[0xE]=val^2; - svgawbank=(seqregs[0xE]&0xF)*65536; - if (!(gdcreg[0xF]&1)) svgarbank=svgawbank; + svga->seqregs[0xe] = val ^ 2; + svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; + if (!(svga->gdcreg[0xf] & 1)) + svga->read_bank = svga->write_bank; return; } break; @@ -53,56 +99,56 @@ void tvga_out(uint16_t addr, uint8_t val, void *priv) case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: if (gfxcard != GFX_TGUI9440) { - tkd8001_ramdac_out(addr, val, NULL); + tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga); return; } break; case 0x3CF: - switch (gdcaddr&15) + switch (svga->gdcaddr & 15) { case 0x6: - if (gdcreg[6] != val) + if (svga->gdcreg[6] != val) { - gdcreg[6] = val; - tvga_recalcmapping(); + svga->gdcreg[6] = val; + tvga_recalcmapping(tvga); } return; case 0xE: - gdcreg[0xE]=val^2; - if ((gdcreg[0xF]&1)==1) - svgarbank=(gdcreg[0xE]&0xF)*65536; + svga->gdcreg[0xe] = val ^ 2; + if ((svga->gdcreg[0xf] & 1) == 1) + svga->read_bank = (svga->gdcreg[0xe] & 0xf) * 65536; break; case 0xF: - if (val&1) svgarbank=(gdcreg[0xE] &0xF)*65536; - else svgarbank=(seqregs[0xE]&0xF)*65536; - svgawbank=(seqregs[0xE]&0xF)*65536; + if (val & 1) svga->read_bank = (svga->gdcreg[0xe] & 0xf) *65536; + else svga->read_bank = (svga->seqregs[0xe] & 0xf) *65536; + svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; break; } break; case 0x3D4: - if (gfxcard == GFX_TGUI9440) crtcreg = val & 0x7f; - else crtcreg = val & 0x3f; + if (gfxcard == GFX_TGUI9440) svga->crtcreg = val & 0x7f; + else svga->crtcreg = val & 0x3f; return; case 0x3D5: - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; //if (crtcreg!=0xE && crtcreg!=0xF) pclog("CRTC R%02X = %02X\n",crtcreg,val); - if (old!=val) + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(svga); } } - switch (crtcreg) + switch (svga->crtcreg) { case 0x21: if (old != val) - tvga_recalcmapping(); + tvga_recalcmapping(tvga); break; @@ -111,262 +157,285 @@ void tvga_out(uint16_t addr, uint8_t val, void *priv) if (gfxcard != GFX_TGUI9440) break; - if ((val & 0xc) == 4) bpp = 16; - else if (!(val & 0xc)) bpp = 8; - else bpp = 24; + if ((val & 0xc) == 4) svga->bpp = 16; + else if (!(val & 0xc)) svga->bpp = 8; + else svga->bpp = 24; break; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: - svga_hwcursor.x = (crtc[0x40] | (crtc[0x41] << 8)) & 0x7ff; - svga_hwcursor.y = (crtc[0x42] | (crtc[0x43] << 8)) & 0x7ff; - svga_hwcursor.xoff = crtc[0x46] & 0x3f; - svga_hwcursor.yoff = crtc[0x47] & 0x3f; - svga_hwcursor.addr = (crtc[0x44] << 10) | ((crtc[0x45] & 0x7) << 18) | (svga_hwcursor.yoff * 8); + svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff; + svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; + svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; + svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f; + svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x7) << 18) | (svga->hwcursor.yoff * 8); break; case 0x50: - svga_hwcursor.ena = val & 0x80; + svga->hwcursor.ena = val & 0x80; break; } return; case 0x3D8: - trident3d8=val; - if (gdcreg[0xF]&4) + tvga->tvga_3d8 = val; + if (svga->gdcreg[0xf] & 4) { - svgawbank=(val&0x1F)*65536; + svga->write_bank = (val & 0x1f) * 65536; // pclog("SVGAWBANK 3D8 %08X %04X:%04X\n",svgawbank,CS,pc); - if (!(gdcreg[0xF]&1)) + if (!(svga->gdcreg[0xf] & 1)) { - svgarbank=(val&0x1F)*65536; + svga->read_bank = (val & 0x1f) * 65536; // pclog("SVGARBANK 3D8 %08X %04X:%04X\n",svgarbank,CS,pc); } } return; case 0x3D9: - trident3d9=val; - if ((gdcreg[0xF]&5)==5) + tvga->tvga_3d9=val; + if ((svga->gdcreg[0xf] & 5) == 5) { - svgarbank=(val&0x1F)*65536; + svga->read_bank = (val & 0x1F) * 65536; // pclog("SVGARBANK 3D9 %08X %04X:%04X\n",svgarbank,CS,pc); } return; } - svga_out(addr, val, priv); + svga_out(addr, val, svga); } -uint8_t tvga_in(uint16_t addr, void *priv) +uint8_t tvga_in(uint16_t addr, void *p) { + tvga_t *tvga = (tvga_t *)p; + svga_t *svga = &tvga->svga; + // if (addr != 0x3da) pclog("tvga_in : %04X %04X:%04X\n", addr, CS,pc); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { case 0x3C5: - if ((seqaddr&0xF)==0xB) + if ((svga->seqaddr & 0xf) == 0xb) { // printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); - tridentoldmode=0; + tvga->oldmode = 0; if (gfxcard == GFX_TVGA) return 0x33; /*TVGA8900D*/ else return 0xe3; /*TGUI9440AGi*/ } - if ((seqaddr&0xF)==0xC) + if ((svga->seqaddr & 0xf) == 0xc) { // printf("Read Trident Power Up 1 %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); // return 0x20; /*2 DRAM banks*/ } - if ((seqaddr&0xF)==0xD) + if ((svga->seqaddr & 0xf) == 0xd) { - if (tridentoldmode) return tridentoldctrl2; - return tridentnewctrl2; + if (tvga->oldmode) return tvga->oldctrl2; + return tvga->newctrl2; } break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: if (gfxcard != GFX_TGUI9440) - return tkd8001_ramdac_in(addr, NULL); + return tkd8001_ramdac_in(addr, &tvga->ramdac, svga); break; - case 0x3CD: /*Banking*/ - return svgaseg; case 0x3D4: - return crtcreg; + return svga->crtcreg; case 0x3D5: - return crtc[crtcreg]; + return svga->crtc[svga->crtcreg]; case 0x3d8: - return trident3d8; + return tvga->tvga_3d8; case 0x3d9: - return trident3d9; + return tvga->tvga_3d9; } - return svga_in(addr, priv); + return svga_in(addr, svga); } -void tvga_recalctimings() +void tvga_recalctimings(svga_t *svga) { - if (!svga_rowoffset) svga_rowoffset=0x100; /*This is the only sensible way I can see this being handled, - given that TVGA8900D has no overflow bits. - Some sort of overflow is required for 320x200x24 and 1024x768x16*/ + tvga_t *tvga = (tvga_t *)svga->p; + if (!svga->rowoffset) svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled, + given that TVGA8900D has no overflow bits. + Some sort of overflow is required for 320x200x24 and 1024x768x16*/ - if ((crtc[0x1E]&0xA0)==0xA0) svga_ma|=0x10000; - if ((crtc[0x27]&0x01)==0x01) svga_ma|=0x20000; - if ((crtc[0x27]&0x02)==0x02) svga_ma|=0x40000; + if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000; + if ((svga->crtc[0x27] & 0x01) == 0x01) svga->ma_latch |= 0x20000; + if ((svga->crtc[0x27] & 0x02) == 0x02) svga->ma_latch |= 0x40000; - if (tridentoldctrl2 & 0x10) + if (tvga->oldctrl2 & 0x10) { - svga_rowoffset<<=1; - svga_ma<<=1; + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; } - if (tridentoldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/ - svga_lowres=0; + if (tvga->oldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/ + svga->lowres=0; if (gfxcard == GFX_TGUI9440) - svga_lowres = !(crtc[0x2a] & 0x40); + svga->lowres = !(svga->crtc[0x2a] & 0x40); - if (gdcreg[0xF] & 8) + if (svga->gdcreg[0xf] & 8) { - svga_htotal<<=1; - svga_hdisp<<=1; + svga->htotal <<= 1; + svga->hdisp <<= 1; } - svga_interlace = crtc[0x1E] & 4; - if (svga_interlace) - svga_rowoffset >>= 1; + svga->interlace = svga->crtc[0x1e] & 4; + if (svga->interlace) + svga->rowoffset >>= 1; - switch (((svga_miscout>>2)&3) | ((tridentnewctrl2<<2)&4)) + switch (((svga->miscout >> 2) & 3) | ((tvga->newctrl2 << 2) & 4)) { - case 2: svga_clock = cpuclock/44900000.0; break; - case 3: svga_clock = cpuclock/36000000.0; break; - case 4: svga_clock = cpuclock/57272000.0; break; - case 5: svga_clock = cpuclock/65000000.0; break; - case 6: svga_clock = cpuclock/50350000.0; break; - case 7: svga_clock = cpuclock/40000000.0; break; + case 2: svga->clock = cpuclock/44900000.0; break; + case 3: svga->clock = cpuclock/36000000.0; break; + case 4: svga->clock = cpuclock/57272000.0; break; + case 5: svga->clock = cpuclock/65000000.0; break; + case 6: svga->clock = cpuclock/50350000.0; break; + case 7: svga->clock = cpuclock/40000000.0; break; } - if ((tridentoldctrl2 & 0x10) || (gfxcard == GFX_TGUI9440 && (crtc[0x2a] & 0x40))) + if ((tvga->oldctrl2 & 0x10) || (gfxcard == GFX_TGUI9440 && (svga->crtc[0x2a] & 0x40))) { - switch (bpp) + switch (svga->bpp) { case 8: - svga_render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_highres; break; case 15: - svga_render = svga_render_15bpp_highres; + svga->render = svga_render_15bpp_highres; break; case 16: - svga_render = svga_render_16bpp_highres; + svga->render = svga_render_16bpp_highres; break; case 24: - svga_render = svga_render_24bpp_highres; + svga->render = svga_render_24bpp_highres; break; case 32: - svga_render = svga_render_32bpp_highres; + svga->render = svga_render_32bpp_highres; break; } } } -void tvga_recalcmapping() +void tvga_recalcmapping(tvga_t *tvga) { - pclog("tvga_recalcmapping : %02X %02X\n", crtc[0x21], gdcreg[6]); - mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); - mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); - mem_removehandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL, NULL); + svga_t *svga = &tvga->svga; + + pclog("tvga_recalcmapping : %02X %02X\n", svga->crtc[0x21], svga->gdcreg[6]); + mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); + mem_removehandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, svga); + mem_removehandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL, tvga); - if (crtc[0x21] & 0x20) + if (svga->crtc[0x21] & 0x20) { - tvga_linear_base = ((crtc[0x21] & 0xf) | ((crtc[0x21] >> 2) & 0x30)) << 20; - tvga_linear_size = (crtc[0x21] & 0x10) ? 0x200000 : 0x100000; - mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); - pclog("Trident linear framebuffer at %08X - size %06X\n", tvga_linear_base, tvga_linear_size); - mem_sethandler(0xbc000, 0x4000, tvga_accel_read, tvga_accel_read_w, tvga_accel_read_l, tvga_accel_write, tvga_accel_write_w, tvga_accel_write_l, NULL); + tvga->linear_base = ((svga->crtc[0x21] & 0xf) | ((svga->crtc[0x21] >> 2) & 0x30)) << 20; + tvga->linear_size = (svga->crtc[0x21] & 0x10) ? 0x200000 : 0x100000; + mem_sethandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, svga); + pclog("Trident linear framebuffer at %08X - size %06X\n", tvga->linear_base, tvga->linear_size); + mem_sethandler(0xbc000, 0x4000, tvga_accel_read, tvga_accel_read_w, tvga_accel_read_l, tvga_accel_write, tvga_accel_write_w, tvga_accel_write_l, tvga); } else { // pclog("Write mapping %02X\n", val); - switch (gdcreg[6] & 0xC) + switch (svga->gdcreg[6] & 0xC) { case 0x0: /*128k at A0000*/ - mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0x4: /*64k at A0000*/ - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); - mem_sethandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL, NULL); + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); + mem_sethandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL, tvga); break; case 0x8: /*32k at B0000*/ - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; case 0xC: /*32k at B8000*/ - mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); break; } } } -void tvga_hwcursor_draw(int displine) +void tvga_hwcursor_draw(svga_t *svga, int displine) { -// int x; uint32_t dat[2]; int xx; - int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; -// pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y); -// for (x = 0; x < 32; x += 32) -// { - dat[0] = (vram[svga_hwcursor_latch.addr] << 24) | (vram[svga_hwcursor_latch.addr + 1] << 16) | (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3]; - dat[1] = (vram[svga_hwcursor_latch.addr + 4] << 24) | (vram[svga_hwcursor_latch.addr + 5] << 16) | (vram[svga_hwcursor_latch.addr + 6] << 8) | vram[svga_hwcursor_latch.addr + 7]; - for (xx = 0; xx < 32; xx++) + dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; + dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7]; + for (xx = 0; xx < 32; xx++) + { + if (offset >= svga->hwcursor_latch.x) { - if (offset >= svga_hwcursor_latch.x) - { - if (!(dat[0] & 0x80000000)) - ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x80000000) ? 0xffffff : 0; - else if (dat[1] & 0x80000000) - ((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]); - } - - offset++; - dat[0] <<= 1; - dat[1] <<= 1; + if (!(dat[0] & 0x80000000)) + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x80000000) ? 0xffffff : 0; + else if (dat[1] & 0x80000000) + ((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]); } - svga_hwcursor_latch.addr += 8; -// } + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + svga->hwcursor_latch.addr += 8; } -int tvga_init() +void *tvga8900d_init() { - svga_recalctimings_ex = tvga_recalctimings; - svga_hwcursor_draw = tvga_hwcursor_draw; - if (gfxcard == GFX_TVGA) - { - vrammask = 0xfffff; - svga_vram_limit = 1 << 20; /*1mb - chip supports 2mb, but drivers are buggy*/ - } - else - { - vrammask = 0x1fffff; - svga_vram_limit = 1 << 21; /*2mb*/ - } - return svga_init(); + tvga_t *tvga = malloc(sizeof(tvga_t)); + memset(tvga, 0, sizeof(tvga_t)); + + svga_init(&tvga->svga, tvga, 1 << 20, /*1mb - chip supports 2mb, but drivers are buggy*/ + tvga_recalctimings, + tvga_in, tvga_out, + NULL); + + io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga); + + return tvga; +} +void *tgui9440_init() +{ + tvga_t *tvga = malloc(sizeof(tvga_t)); + memset(tvga, 0, sizeof(tvga_t)); + + svga_init(&tvga->svga, tvga, 1 << 21, /*2mb*/ + tvga_recalctimings, + tvga_in, tvga_out, + tvga_hwcursor_draw); + + io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga); + + return tvga; } -struct tvga_accel +void tvga_close(void *p) { - uint16_t src_x, src_y; - uint16_t dst_x, dst_y; - uint16_t size_x, size_y; - uint16_t fg_col, bg_col; - uint8_t rop; - uint16_t flags; - uint8_t pattern[0x80]; - int command; - int offset; - uint8_t ger22; - - int x, y; - uint32_t src, dst, src_old, dst_old; - int pat_x, pat_y; - int use_src; - - int pitch, bpp; -} tvga_accel; + tvga_t *tvga = (tvga_t *)p; + + svga_close(&tvga->svga); + + free(tvga); +} + +void tvga_speed_changed(void *p) +{ + tvga_t *tvga = (tvga_t *)p; + + svga_recalctimings(&tvga->svga); +} + +device_t tvga8900d_device = +{ + "Trident TVGA 8900D", + tvga8900d_init, + tvga_close, + tvga_speed_changed, + svga_add_status_info +}; +device_t tgui9440_device = +{ + "Trident TGUI 9440", + tgui9440_init, + tvga_close, + tvga_speed_changed, + svga_add_status_info +}; enum { @@ -385,7 +454,7 @@ enum TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/ }; -#define READ(addr, dat) if (tvga_accel.bpp == 0) dat = vram[addr & 0x1fffff]; \ +#define READ(addr, dat) if (tvga->accel.bpp == 0) dat = svga->vram[addr & 0x1fffff]; \ else dat = vram_w[addr & 0xfffff]; #define MIX() do \ @@ -396,68 +465,67 @@ enum d=(dst_dat & (1<accel.rop & (1<accel.bpp == 0) \ { \ - vram[addr & 0x1fffff] = dat; \ - changedvram[((addr) & 0x1fffff) >> 10] = changeframecount; \ + svga->vram[addr & 0x1fffff] = dat; \ + svga->changedvram[((addr) & 0x1fffff) >> 10] = changeframecount; \ } \ else \ { \ vram_w[addr & 0xfffff] = dat; \ - changedvram[((addr) & 0xfffff) >> 9] = changeframecount; \ + svga->changedvram[((addr) & 0xfffff) >> 9] = changeframecount; \ } -static uint16_t tvga_pattern[8][8]; - void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv); void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv); -void tvga_accel_command(int count, uint32_t cpu_dat) +void tvga_accel_command(int count, uint32_t cpu_dat, tvga_t *tvga) { + svga_t *svga = &tvga->svga; int x, y; int c, d; uint16_t src_dat, dst_dat, pat_dat; uint16_t out; - int xdir = (tvga_accel.flags & 0x200) ? -1 : 1; - int ydir = (tvga_accel.flags & 0x100) ? -1 : 1; - uint16_t trans_col = (tvga_accel.flags & TGUI_TRANSREV) ? tvga_accel.fg_col : tvga_accel.bg_col; - uint16_t *vram_w = (uint16_t *)vram; + int xdir = (tvga->accel.flags & 0x200) ? -1 : 1; + int ydir = (tvga->accel.flags & 0x100) ? -1 : 1; + uint16_t trans_col = (tvga->accel.flags & TGUI_TRANSREV) ? tvga->accel.fg_col : tvga->accel.bg_col; + uint16_t *vram_w = (uint16_t *)svga->vram; - if (tvga_accel.bpp == 0) + if (tvga->accel.bpp == 0) trans_col &= 0xff; - if (count != -1 && !tvga_accel.x) + if (count != -1 && !tvga->accel.x) { - count -= tvga_accel.offset; - cpu_dat <<= tvga_accel.offset; + count -= tvga->accel.offset; + cpu_dat <<= tvga->accel.offset; } if (count == -1) { - tvga_accel.x = tvga_accel.y = 0; + tvga->accel.x = tvga->accel.y = 0; } - if (tvga_accel.flags & TGUI_SOLIDFILL) + if (tvga->accel.flags & TGUI_SOLIDFILL) { // pclog("SOLIDFILL\n"); for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { - tvga_pattern[y][x] = tvga_accel.fg_col; + tvga->accel.tvga_pattern[y][x] = tvga->accel.fg_col; } } } - else if (tvga_accel.flags & TGUI_PATMONO) + else if (tvga->accel.flags & TGUI_PATMONO) { // pclog("PATMONO\n"); for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { - tvga_pattern[y][x] = (tvga_accel.pattern[y] & (1 << x)) ? tvga_accel.fg_col : tvga_accel.bg_col; + tvga->accel.tvga_pattern[y][x] = (tvga->accel.pattern[y] & (1 << x)) ? tvga->accel.fg_col : tvga->accel.bg_col; } } } @@ -468,46 +536,46 @@ void tvga_accel_command(int count, uint32_t cpu_dat) { for (x = 0; x < 8; x++) { - tvga_pattern[y][x] = tvga_accel.pattern[x + y*8]; + tvga->accel.tvga_pattern[y][x] = tvga->accel.pattern[x + y*8]; } } } for (y = 0; y < 8; y++) { - if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, tvga_pattern[y][0], tvga_pattern[y][1], tvga_pattern[y][2], tvga_pattern[y][3], tvga_pattern[y][4], tvga_pattern[y][5], tvga_pattern[y][6], tvga_pattern[y][7]); + if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, tvga->accel.tvga_pattern[y][0], tvga->accel.tvga_pattern[y][1], tvga->accel.tvga_pattern[y][2], tvga->accel.tvga_pattern[y][3], tvga->accel.tvga_pattern[y][4], tvga->accel.tvga_pattern[y][5], tvga->accel.tvga_pattern[y][6], tvga->accel.tvga_pattern[y][7]); } - if (count == -1) pclog("Command %i %i\n", tvga_accel.command, TGUI_BITBLT); - switch (tvga_accel.command) + if (count == -1) pclog("Command %i %i\n", tvga->accel.command, TGUI_BITBLT); + switch (tvga->accel.command) { case TGUI_BITBLT: - if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tvga_accel.src_x, tvga_accel.src_y, tvga_accel.dst_x, tvga_accel.dst_y, tvga_accel.size_x, tvga_accel.size_y, tvga_accel.flags); + if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tvga->accel.src_x, tvga->accel.src_y, tvga->accel.dst_x, tvga->accel.dst_y, tvga->accel.size_x, tvga->accel.size_y, tvga->accel.flags); if (count == -1) { - tvga_accel.src = tvga_accel.src_old = tvga_accel.src_x + (tvga_accel.src_y * tvga_accel.pitch); - tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_x + (tvga_accel.dst_y * tvga_accel.pitch); - tvga_accel.pat_x = tvga_accel.dst_x; - tvga_accel.pat_y = tvga_accel.dst_y; + tvga->accel.src = tvga->accel.src_old = tvga->accel.src_x + (tvga->accel.src_y * tvga->accel.pitch); + tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_x + (tvga->accel.dst_y * tvga->accel.pitch); + tvga->accel.pat_x = tvga->accel.dst_x; + tvga->accel.pat_y = tvga->accel.dst_y; } - switch (tvga_accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP)) + switch (tvga->accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP)) { case TGUI_SRCCPU: if (count == -1) { // pclog("Blit start\n"); - if (crtc[0x21] & 0x20) + if (svga->crtc[0x21] & 0x20) { - mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); - mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); + mem_removehandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); + mem_sethandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); } - if (tvga_accel.use_src) + if (tvga->accel.use_src) return; } else count >>= 3; while (count) { - if (tvga_accel.bpp == 0) + if (tvga->accel.bpp == 0) { src_dat = cpu_dat >> 24; cpu_dat <<= 8; @@ -518,45 +586,45 @@ void tvga_accel_command(int count, uint32_t cpu_dat) cpu_dat <<= 16; count--; } - READ(tvga_accel.dst, dst_dat); - pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7]; + READ(tvga->accel.dst, dst_dat); + pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7]; - if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col) + if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) { MIX(); - WRITE(tvga_accel.dst, out); + WRITE(tvga->accel.dst, out); } -// pclog(" %i,%i %02X %02X %02X %02X\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out); +// pclog(" %i,%i %02X %02X %02X %02X\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out); - tvga_accel.src += xdir; - tvga_accel.dst += xdir; - tvga_accel.pat_x += xdir; + tvga->accel.src += xdir; + tvga->accel.dst += xdir; + tvga->accel.pat_x += xdir; - tvga_accel.x++; - if (tvga_accel.x > tvga_accel.size_x) + tvga->accel.x++; + if (tvga->accel.x > tvga->accel.size_x) { - tvga_accel.x = 0; - tvga_accel.y++; + tvga->accel.x = 0; + tvga->accel.y++; - tvga_accel.pat_x = tvga_accel.dst_x; + tvga->accel.pat_x = tvga->accel.dst_x; - tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch); - tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch); - tvga_accel.pat_y += ydir; + tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch); + tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch); + tvga->accel.pat_y += ydir; - if (tvga_accel.y > tvga_accel.size_y) + if (tvga->accel.y > tvga->accel.size_y) { - if (crtc[0x21] & 0x20) + if (svga->crtc[0x21] & 0x20) { // pclog("Blit end\n"); - mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); - mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); + mem_removehandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); + mem_sethandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); } return; } - if (tvga_accel.use_src) + if (tvga->accel.use_src) return; } count--; @@ -567,59 +635,59 @@ void tvga_accel_command(int count, uint32_t cpu_dat) if (count == -1) { // pclog("Blit start\n"); - if (crtc[0x21] & 0x20) + if (svga->crtc[0x21] & 0x20) { - mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); - mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); + mem_removehandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); + mem_sethandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); } - if (tvga_accel.use_src) + if (tvga->accel.use_src) return; } // pclog("TGUI_SRCMONO | TGUI_SRCCPU\n"); while (count) { - src_dat = ((cpu_dat >> 31) ? tvga_accel.fg_col : tvga_accel.bg_col); - if (tvga_accel.bpp == 0) + src_dat = ((cpu_dat >> 31) ? tvga->accel.fg_col : tvga->accel.bg_col); + if (tvga->accel.bpp == 0) src_dat &= 0xff; - READ(tvga_accel.dst, dst_dat); - pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7]; + READ(tvga->accel.dst, dst_dat); + pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7]; - if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col) + if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) { MIX(); - WRITE(tvga_accel.dst, out); + WRITE(tvga->accel.dst, out); } -// pclog(" %i,%i %02X %02X %02X %02X %i\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out, (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col)); +// pclog(" %i,%i %02X %02X %02X %02X %i\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out, (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)); cpu_dat <<= 1; - tvga_accel.src += xdir; - tvga_accel.dst += xdir; - tvga_accel.pat_x += xdir; + tvga->accel.src += xdir; + tvga->accel.dst += xdir; + tvga->accel.pat_x += xdir; - tvga_accel.x++; - if (tvga_accel.x > tvga_accel.size_x) + tvga->accel.x++; + if (tvga->accel.x > tvga->accel.size_x) { - tvga_accel.x = 0; - tvga_accel.y++; + tvga->accel.x = 0; + tvga->accel.y++; - tvga_accel.pat_x = tvga_accel.dst_x; + tvga->accel.pat_x = tvga->accel.dst_x; - tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch); - tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch); - tvga_accel.pat_y += ydir; + tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch); + tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch); + tvga->accel.pat_y += ydir; - if (tvga_accel.y > tvga_accel.size_y) + if (tvga->accel.y > tvga->accel.size_y) { - if (crtc[0x21] & 0x20) + if (svga->crtc[0x21] & 0x20) { // pclog("Blit end\n"); - mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); - mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); + mem_removehandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); + mem_sethandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); } return; } - if (tvga_accel.use_src) + if (tvga->accel.use_src) return; } count--; @@ -629,35 +697,35 @@ void tvga_accel_command(int count, uint32_t cpu_dat) default: while (count) { - READ(tvga_accel.src, src_dat); - READ(tvga_accel.dst, dst_dat); - pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7]; + READ(tvga->accel.src, src_dat); + READ(tvga->accel.dst, dst_dat); + pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7]; - if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col) + if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) { MIX(); - WRITE(tvga_accel.dst, out); + WRITE(tvga->accel.dst, out); } -// pclog(" %i,%i %02X %02X %02X %02X\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out); +// pclog(" %i,%i %02X %02X %02X %02X\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out); - tvga_accel.src += xdir; - tvga_accel.dst += xdir; - tvga_accel.pat_x += xdir; + tvga->accel.src += xdir; + tvga->accel.dst += xdir; + tvga->accel.pat_x += xdir; - tvga_accel.x++; - if (tvga_accel.x > tvga_accel.size_x) + tvga->accel.x++; + if (tvga->accel.x > tvga->accel.size_x) { - tvga_accel.x = 0; - tvga_accel.y++; + tvga->accel.x = 0; + tvga->accel.y++; - tvga_accel.pat_x = tvga_accel.dst_x; + tvga->accel.pat_x = tvga->accel.dst_x; - tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch); - tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch); - tvga_accel.pat_y += ydir; + tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch); + tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch); + tvga->accel.pat_y += ydir; - if (tvga_accel.y > tvga_accel.size_y) + if (tvga->accel.y > tvga->accel.size_y) return; } count--; @@ -668,93 +736,94 @@ void tvga_accel_command(int count, uint32_t cpu_dat) } } -void tvga_accel_write(uint32_t addr, uint8_t val, void *priv) +void tvga_accel_write(uint32_t addr, uint8_t val, void *p) { + tvga_t *tvga = (tvga_t *)p; pclog("tvga_accel_write : %08X %02X %04X(%08X):%08X %02X\n", addr, val, CS,cs,pc, opcode); if ((addr & ~0xff) != 0xbff00) return; switch (addr & 0xff) { case 0x22: - tvga_accel.ger22 = val; - tvga_accel.pitch = 512 << ((val >> 2) & 3); - tvga_accel.bpp = (val & 3) ? 1 : 0; - tvga_accel.pitch >>= tvga_accel.bpp; + tvga->accel.ger22 = val; + tvga->accel.pitch = 512 << ((val >> 2) & 3); + tvga->accel.bpp = (val & 3) ? 1 : 0; + tvga->accel.pitch >>= tvga->accel.bpp; break; case 0x24: /*Command*/ - tvga_accel.command = val; - tvga_accel_command(-1, 0); + tvga->accel.command = val; + tvga_accel_command(-1, 0, tvga); break; case 0x27: /*ROP*/ - tvga_accel.rop = val; - tvga_accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); - pclog("Write ROP %02X %i\n", val, tvga_accel.use_src); + tvga->accel.rop = val; + tvga->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); + pclog("Write ROP %02X %i\n", val, tvga->accel.use_src); break; case 0x28: /*Flags*/ - tvga_accel.flags = (tvga_accel.flags & 0xff00) | val; + tvga->accel.flags = (tvga->accel.flags & 0xff00) | val; break; case 0x29: /*Flags*/ - tvga_accel.flags = (tvga_accel.flags & 0xff) | (val << 8); + tvga->accel.flags = (tvga->accel.flags & 0xff) | (val << 8); break; case 0x2b: - tvga_accel.offset = val & 7; + tvga->accel.offset = val & 7; break; case 0x2c: /*Foreground colour*/ - tvga_accel.fg_col = (tvga_accel.fg_col & 0xff00) | val; + tvga->accel.fg_col = (tvga->accel.fg_col & 0xff00) | val; break; case 0x2d: /*Foreground colour*/ - tvga_accel.fg_col = (tvga_accel.fg_col & 0xff) | (val << 8); + tvga->accel.fg_col = (tvga->accel.fg_col & 0xff) | (val << 8); break; case 0x30: /*Background colour*/ - tvga_accel.bg_col = (tvga_accel.bg_col & 0xff00) | val; + tvga->accel.bg_col = (tvga->accel.bg_col & 0xff00) | val; break; case 0x31: /*Background colour*/ - tvga_accel.bg_col = (tvga_accel.bg_col & 0xff) | (val << 8); + tvga->accel.bg_col = (tvga->accel.bg_col & 0xff) | (val << 8); break; case 0x38: /*Dest X*/ - tvga_accel.dst_x = (tvga_accel.dst_x & 0xff00) | val; + tvga->accel.dst_x = (tvga->accel.dst_x & 0xff00) | val; break; case 0x39: /*Dest X*/ - tvga_accel.dst_x = (tvga_accel.dst_x & 0xff) | (val << 8); + tvga->accel.dst_x = (tvga->accel.dst_x & 0xff) | (val << 8); break; case 0x3a: /*Dest Y*/ - tvga_accel.dst_y = (tvga_accel.dst_y & 0xff00) | val; + tvga->accel.dst_y = (tvga->accel.dst_y & 0xff00) | val; break; case 0x3b: /*Dest Y*/ - tvga_accel.dst_y = (tvga_accel.dst_y & 0xff) | (val << 8); + tvga->accel.dst_y = (tvga->accel.dst_y & 0xff) | (val << 8); break; case 0x3c: /*Src X*/ - tvga_accel.src_x = (tvga_accel.src_x & 0xff00) | val; + tvga->accel.src_x = (tvga->accel.src_x & 0xff00) | val; break; case 0x3d: /*Src X*/ - tvga_accel.src_x = (tvga_accel.src_x & 0xff) | (val << 8); + tvga->accel.src_x = (tvga->accel.src_x & 0xff) | (val << 8); break; case 0x3e: /*Src Y*/ - tvga_accel.src_y = (tvga_accel.src_y & 0xff00) | val; + tvga->accel.src_y = (tvga->accel.src_y & 0xff00) | val; break; case 0x3f: /*Src Y*/ - tvga_accel.src_y = (tvga_accel.src_y & 0xff) | (val << 8); + tvga->accel.src_y = (tvga->accel.src_y & 0xff) | (val << 8); break; case 0x40: /*Size X*/ - tvga_accel.size_x = (tvga_accel.size_x & 0xff00) | val; + tvga->accel.size_x = (tvga->accel.size_x & 0xff00) | val; break; case 0x41: /*Size X*/ - tvga_accel.size_x = (tvga_accel.size_x & 0xff) | (val << 8); + tvga->accel.size_x = (tvga->accel.size_x & 0xff) | (val << 8); break; case 0x42: /*Size Y*/ - tvga_accel.size_y = (tvga_accel.size_y & 0xff00) | val; + tvga->accel.size_y = (tvga->accel.size_y & 0xff00) | val; break; case 0x43: /*Size Y*/ - tvga_accel.size_y = (tvga_accel.size_y & 0xff) | (val << 8); + tvga->accel.size_y = (tvga->accel.size_y & 0xff) | (val << 8); break; case 0x80: case 0x81: case 0x82: case 0x83: @@ -789,29 +858,32 @@ void tvga_accel_write(uint32_t addr, uint8_t val, void *priv) case 0xf4: case 0xf5: case 0xf6: case 0xf7: case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: - tvga_accel.pattern[addr & 0x7f] = val; + tvga->accel.pattern[addr & 0x7f] = val; break; } } -void tvga_accel_write_w(uint32_t addr, uint16_t val, void *priv) +void tvga_accel_write_w(uint32_t addr, uint16_t val, void *p) { + tvga_t *tvga = (tvga_t *)p; pclog("tvga_accel_write_w %08X %04X\n", addr, val); - tvga_accel_write(addr, val, NULL); - tvga_accel_write(addr + 1, val >> 8, NULL); + tvga_accel_write(addr, val, tvga); + tvga_accel_write(addr + 1, val >> 8, tvga); } -void tvga_accel_write_l(uint32_t addr, uint32_t val, void *priv) +void tvga_accel_write_l(uint32_t addr, uint32_t val, void *p) { + tvga_t *tvga = (tvga_t *)p; pclog("tvga_accel_write_l %08X %08X\n", addr, val); - tvga_accel_write(addr, val, NULL); - tvga_accel_write(addr + 1, val >> 8, NULL); - tvga_accel_write(addr + 2, val >> 16, NULL); - tvga_accel_write(addr + 3, val >> 24, NULL); + tvga_accel_write(addr, val, tvga); + tvga_accel_write(addr + 1, val >> 8, tvga); + tvga_accel_write(addr + 2, val >> 16, tvga); + tvga_accel_write(addr + 3, val >> 24, tvga); } -uint8_t tvga_accel_read(uint32_t addr, void *priv) +uint8_t tvga_accel_read(uint32_t addr, void *p) { + tvga_t *tvga = (tvga_t *)p; // pclog("tvga_accel_read : %08X\n", addr); if ((addr & ~0xff) != 0xbff00) return 0xff; @@ -821,52 +893,52 @@ uint8_t tvga_accel_read(uint32_t addr, void *priv) return 0; case 0x27: /*ROP*/ - return tvga_accel.rop; + return tvga->accel.rop; case 0x28: /*Flags*/ - return tvga_accel.flags & 0xff; + return tvga->accel.flags & 0xff; case 0x29: /*Flags*/ - return tvga_accel.flags >> 8; + return tvga->accel.flags >> 8; case 0x2b: - return tvga_accel.offset; + return tvga->accel.offset; case 0x2c: /*Background colour*/ - return tvga_accel.bg_col & 0xff; + return tvga->accel.bg_col & 0xff; case 0x2d: /*Background colour*/ - return tvga_accel.bg_col >> 8; + return tvga->accel.bg_col >> 8; case 0x30: /*Foreground colour*/ - return tvga_accel.fg_col & 0xff; + return tvga->accel.fg_col & 0xff; case 0x31: /*Foreground colour*/ - return tvga_accel.fg_col >> 8; + return tvga->accel.fg_col >> 8; case 0x38: /*Dest X*/ - return tvga_accel.dst_x & 0xff; + return tvga->accel.dst_x & 0xff; case 0x39: /*Dest X*/ - return tvga_accel.dst_x >> 8; + return tvga->accel.dst_x >> 8; case 0x3a: /*Dest Y*/ - return tvga_accel.dst_y & 0xff; + return tvga->accel.dst_y & 0xff; case 0x3b: /*Dest Y*/ - return tvga_accel.dst_y >> 8; + return tvga->accel.dst_y >> 8; case 0x3c: /*Src X*/ - return tvga_accel.src_x & 0xff; + return tvga->accel.src_x & 0xff; case 0x3d: /*Src X*/ - return tvga_accel.src_x >> 8; + return tvga->accel.src_x >> 8; case 0x3e: /*Src Y*/ - return tvga_accel.src_y & 0xff; + return tvga->accel.src_y & 0xff; case 0x3f: /*Src Y*/ - return tvga_accel.src_y >> 8; + return tvga->accel.src_y >> 8; case 0x40: /*Size X*/ - return tvga_accel.size_x & 0xff; + return tvga->accel.size_x & 0xff; case 0x41: /*Size X*/ - return tvga_accel.size_x >> 8; + return tvga->accel.size_x >> 8; case 0x42: /*Size Y*/ - return tvga_accel.size_y & 0xff; + return tvga->accel.size_y & 0xff; case 0x43: /*Size Y*/ - return tvga_accel.size_y >> 8; + return tvga->accel.size_y >> 8; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: @@ -900,83 +972,42 @@ uint8_t tvga_accel_read(uint32_t addr, void *priv) case 0xf4: case 0xf5: case 0xf6: case 0xf7: case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: - return tvga_accel.pattern[addr & 0x7f]; + return tvga->accel.pattern[addr & 0x7f]; } return 0xff; } -uint16_t tvga_accel_read_w(uint32_t addr, void *priv) +uint16_t tvga_accel_read_w(uint32_t addr, void *p) { + tvga_t *tvga = (tvga_t *)p; pclog("tvga_accel_read_w %08X\n", addr); - return tvga_accel_read(addr, NULL) | (tvga_accel_read(addr + 1, NULL) << 8); + return tvga_accel_read(addr, tvga) | (tvga_accel_read(addr + 1, tvga) << 8); } -uint32_t tvga_accel_read_l(uint32_t addr, void *priv) +uint32_t tvga_accel_read_l(uint32_t addr, void *p) { + tvga_t *tvga = (tvga_t *)p; pclog("tvga_accel_read_l %08X\n", addr); - return tvga_accel_read_w(addr, NULL) | (tvga_accel_read_w(addr + 2, NULL) << 16); + return tvga_accel_read_w(addr, tvga) | (tvga_accel_read_w(addr + 2, tvga) << 16); } -void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv) +void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *p) { + tvga_t *tvga = (tvga_t *)p; // pclog("tvga_accel_write_fb_b %08X %02X\n", addr, val); - tvga_accel_command(8, val << 24); + tvga_accel_command(8, val << 24, tvga); } -void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv) +void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *p) { + tvga_t *tvga = (tvga_t *)p; // pclog("tvga_accel_write_fb_w %08X %04X\n", addr, val); - tvga_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16); + tvga_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tvga); } -void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv) +void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *p) { + tvga_t *tvga = (tvga_t *)p; // pclog("tvga_accel_write_fb_l %08X %08X\n", addr, val); - tvga_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); + tvga_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tvga); } - -GFXCARD vid_tvga = -{ - tvga_init, - /*IO at 3Cx/3Dx*/ - tvga_out, - tvga_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - svga_poll, - svga_recalctimings, - - svga_write, - video_write_null, - video_write_null, - - svga_read, - video_read_null, - video_read_null -}; - -GFXCARD vid_tgui9440 = -{ - tvga_init, - /*IO at 3Cx/3Dx*/ - tvga_out, - tvga_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - svga_poll, - svga_recalctimings, - - svga_write, - video_write_null, - video_write_null, - - svga_read, - video_read_null, - video_read_null -}; - - diff --git a/src/vid_tvga.h b/src/vid_tvga.h new file mode 100644 index 0000000..ced63d3 --- /dev/null +++ b/src/vid_tvga.h @@ -0,0 +1,2 @@ +extern device_t tvga8900d_device; +extern device_t tgui9440_device; diff --git a/src/vid_unk_ramdac.c b/src/vid_unk_ramdac.c index 964826a..1812a31 100644 --- a/src/vid_unk_ramdac.c +++ b/src/vid_unk_ramdac.c @@ -6,61 +6,58 @@ #include "vid_svga.h" #include "vid_unk_ramdac.h" -static int unk_state=0; -static uint8_t unk_ctrl; - -void unk_ramdac_out(uint16_t addr, uint8_t val, void *priv) +void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga) { //pclog("OUT RAMDAC %04X %02X\n",addr,val); switch (addr) { case 0x3C6: - if (unk_state == 4) + if (ramdac->state == 4) { - unk_state = 0; - unk_ctrl = val; + ramdac->state = 0; + ramdac->ctrl = val; switch ((val&1)|((val&0xE0)>>4)) { case 0: case 1: case 2: case 3: - bpp = 8; + svga->bpp = 8; break; case 6: case 7: - bpp = 24; + svga->bpp = 24; break; case 8: case 9: case 0xA: case 0xB: - bpp = 15; + svga->bpp = 15; break; case 0xC: case 0xD: case 0xE: case 0xF: - bpp = 16; + svga->bpp = 16; break; } return; } - unk_state = 0; + ramdac->state = 0; break; case 0x3C7: case 0x3C8: case 0x3C9: - unk_state = 0; + ramdac->state = 0; break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t unk_ramdac_in(uint16_t addr, void *priv) +uint8_t unk_ramdac_in(uint16_t addr, unk_ramdac_t *ramdac, svga_t *svga) { //pclog("IN RAMDAC %04X\n",addr); switch (addr) { case 0x3C6: - if (unk_state == 4) + if (ramdac->state == 4) { - unk_state = 0; - return unk_ctrl; + ramdac->state = 0; + return ramdac->ctrl; } - unk_state++; + ramdac->state++; break; case 0x3C7: case 0x3C8: case 0x3C9: - unk_state = 0; + ramdac->state = 0; break; } - return svga_in(addr, NULL); + return svga_in(addr, svga); } diff --git a/src/vid_unk_ramdac.h b/src/vid_unk_ramdac.h index b4f1406..4f6e51a 100644 --- a/src/vid_unk_ramdac.h +++ b/src/vid_unk_ramdac.h @@ -1,2 +1,8 @@ -void unk_ramdac_out(uint16_t addr, uint8_t val, void *priv); -uint8_t unk_ramdac_in(uint16_t addr, void *priv); +typedef struct unk_ramdac_t +{ + int state; + uint8_t ctrl; +} unk_ramdac_t; + +void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga); +uint8_t unk_ramdac_in(uint16_t addr, unk_ramdac_t *ramdac, svga_t *svga); diff --git a/src/vid_vga.c b/src/vid_vga.c index dce8a8d..d37abc9 100644 --- a/src/vid_vga.c +++ b/src/vid_vga.c @@ -1,92 +1,116 @@ /*IBM VGA emulation*/ +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "video.h" #include "vid_svga.h" +#include "vid_vga.h" -void vga_out(uint16_t addr, uint8_t val, void *priv) +typedef struct vga_t { + svga_t svga; +} vga_t; + +void vga_out(uint16_t addr, uint8_t val, void *p) +{ + vga_t *vga = (vga_t *)p; + svga_t *svga = &vga->svga; uint8_t old; pclog("vga_out : %04X %02X %04X:%04X %02X %i\n", addr, val, CS,pc, ram[0x489], ins); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { case 0x3D4: - crtcreg = val & 0x1f; + svga->crtcreg = val & 0x1f; return; case 0x3D5: - if (crtcreg <= 7 && crtc[0x11] & 0x80) return; - old=crtc[crtcreg]; - crtc[crtcreg]=val; - if (old!=val) + if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { - if (crtcreg<0xE || crtcreg>0x10) + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - fullchange=changeframecount; - svga_recalctimings(); + fullchange = changeframecount; + svga_recalctimings(svga); } } break; } - svga_out(addr, val, NULL); + svga_out(addr, val, svga); } -uint8_t vga_in(uint16_t addr, void *priv) +uint8_t vga_in(uint16_t addr, void *p) { + vga_t *vga = (vga_t *)p; + svga_t *svga = &vga->svga; uint8_t temp; if (addr != 0x3da) pclog("vga_in : %04X ", addr); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { case 0x3D4: - temp = crtcreg; + temp = svga->crtcreg; break; case 0x3D5: - temp = crtc[crtcreg]; + temp = svga->crtc[svga->crtcreg]; break; default: - temp = svga_in(addr, NULL); + temp = svga_in(addr, svga); break; } if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); return temp; } -int vga_init() +void *vga_init() { - svga_recalctimings_ex = NULL; - svga_vram_limit = 1 << 18; /*256kb*/ - vrammask = 0x3ffff; - svgawbank = svgarbank = 0; - bpp = 8; - svga_miscout = 1; - return svga_init(); + vga_t *vga = malloc(sizeof(vga_t)); + memset(vga, 0, sizeof(vga_t)); + + svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ + NULL, + vga_in, vga_out, + NULL); + + io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + + vga->svga.bpp = 8; + vga->svga.miscout = 1; + + return vga; } -GFXCARD vid_vga = +void vga_close(void *p) { + vga_t *vga = (vga_t *)p; + + svga_close(&vga->svga); + + free(vga); +} + +void vga_speed_changed(void *p) +{ + vga_t *vga = (vga_t *)p; + + svga_recalctimings(&vga->svga); +} + +device_t vga_device = +{ + "VGA", vga_init, - /*IO at 3Cx/3Dx*/ - vga_out, - vga_in, - /*IO at 3Ax/3Bx*/ - video_out_null, - video_in_null, - - svga_poll, - svga_recalctimings, - - svga_write, - video_write_null, - video_write_null, - - svga_read, - video_read_null, - video_read_null + vga_close, + vga_speed_changed, + svga_add_status_info }; diff --git a/src/vid_vga.h b/src/vid_vga.h new file mode 100644 index 0000000..12a65f9 --- /dev/null +++ b/src/vid_vga.h @@ -0,0 +1 @@ +extern device_t vga_device; diff --git a/src/video.c b/src/video.c index c87fb36..babf0ce 100644 --- a/src/video.c +++ b/src/video.c @@ -1,13 +1,45 @@ #include #include #include "ibm.h" +#include "device.h" #include "video.h" #include "vid_svga.h" #include "io.h" #include "cpu.h" #include "timer.h" -int video_timer; +#include "vid_ati18800.h" +#include "vid_ati28800.h" +#include "vid_ati_mach64.h" +#include "vid_cga.h" +#include "vid_cl5429.h" +#include "vid_ega.h" +#include "vid_et4000.h" +#include "vid_et4000w32.h" +#include "vid_hercules.h" +#include "vid_mda.h" +#include "vid_olivetti_m24.h" +#include "vid_oti067.h" +#include "vid_paradise.h" +#include "vid_pc1512.h" +#include "vid_pc1640.h" +#include "vid_pc200.h" +#include "vid_s3.h" +#include "vid_s3_virge.h" +#include "vid_tandy.h" +#include "vid_tvga.h" +#include "vid_vga.h" + +int egareads=0,egawrites=0; +int changeframecount=2; + +uint8_t rotatevga[8][256]; + +int frames = 0; + +int fullchange; + +uint8_t edatlookup[4][4]; /*Video timing settings - @@ -84,70 +116,6 @@ int video_res_x, video_res_y, video_bpp; void (*video_blit_memtoscreen)(int x, int y, int y1, int y2, int w, int h); void (*video_blit_memtoscreen_8)(int x, int y, int w, int h); -void (*video_out) (uint16_t addr, uint8_t val, void *priv); -void (*video_mono_out)(uint16_t addr, uint8_t val, void *priv); -uint8_t (*video_in) (uint16_t addr, void *priv); -uint8_t (*video_mono_in)(uint16_t addr, void *priv); - -void (*video_write_a000)(uint32_t addr, uint8_t val, void *priv); -void (*video_write_b000)(uint32_t addr, uint8_t val, void *priv); -void (*video_write_b800)(uint32_t addr, uint8_t val, void *priv); - -void (*video_write_a000_w)(uint32_t addr, uint16_t val, void *priv); -void (*video_write_a000_l)(uint32_t addr, uint32_t val, void *priv); - -uint8_t (*video_read_a000)(uint32_t addr, void *priv); -uint8_t (*video_read_b000)(uint32_t addr, void *priv); -uint8_t (*video_read_b800)(uint32_t addr, void *priv); - -void (*video_recalctimings)(); - -void video_out_null(uint16_t addr, uint8_t val, void *priv) -{ -} - -uint8_t video_in_null(uint16_t addr, void *priv) -{ - return 0xFF; -} - -void video_write_null(uint32_t addr, uint8_t val, void *priv) -{ -} - -uint8_t video_read_null(uint32_t addr, void *priv) -{ - return 0xff; -} - -void video_load(GFXCARD g) -{ - io_sethandler(0x03a0, 0x0020, g.mono_in, NULL, NULL, g.mono_out, NULL, NULL, NULL); - io_sethandler(0x03c0, 0x0020, g.in, NULL, NULL, g.out, NULL, NULL, NULL); - - video_out = g.out; - video_in = g.in; - video_mono_out = g.mono_out; - video_mono_in = g.mono_in; - - pollvideo = g.poll; - video_recalctimings = g.recalctimings; - - video_write_a000 = g.write_a000; - video_write_b000 = g.write_b000; - video_write_b800 = g.write_b800; - - video_read_a000 = g.read_a000; - video_read_b000 = g.read_b000; - video_read_b800 = g.read_b800; - - video_write_a000_w = video_write_a000_l = NULL; - - g.init(); - - video_timer = timer_add(pollvideo, &vidtime, TIMER_ALWAYS_ENABLED, NULL); -} - void video_init() { pclog("Video_init %i %i\n",romset,gfxcard); @@ -155,107 +123,108 @@ void video_init() switch (romset) { case ROM_TANDY: - video_load(vid_tandy); + device_add(&tandy_device); return; case ROM_PC1512: - video_load(vid_pc1512); + device_add(&pc1512_device); return; case ROM_PC1640: - video_load(vid_pc1640); + device_add(&pc1640_device); return; case ROM_PC200: - video_load(vid_pc200); + device_add(&pc200_device); return; case ROM_OLIM24: - video_load(vid_m24); + device_add(&m24_device); return; case ROM_PC2086: case ROM_PC3086: + device_add(¶dise_pvga1a_device); + return; case ROM_MEGAPC: - video_load(vid_paradise); + device_add(¶dise_wd90c11_device); return; case ROM_ACER386: - video_load(vid_oti067); + device_add(&oti067_device); return; } switch (gfxcard) { case GFX_MDA: - video_load(vid_mda); + device_add(&mda_device); break; case GFX_HERCULES: - video_load(vid_hercules); + device_add(&hercules_device); break; case GFX_CGA: - video_load(vid_cga); + device_add(&cga_device); break; case GFX_EGA: - video_load(vid_ega); + device_add(&ega_device); break; case GFX_TVGA: - video_load(vid_tvga); + device_add(&tvga8900d_device); break; case GFX_ET4000: - video_load(vid_et4000); + device_add(&et4000_device); break; case GFX_ET4000W32: - video_load(vid_et4000w32p); + device_add(&et4000w32p_device); break; case GFX_BAHAMAS64: - video_load(vid_s3); + device_add(&s3_bahamas64_device); break; case GFX_N9_9FX: - video_load(vid_s3); + device_add(&s3_9fx_device); break; case GFX_STEALTH64: - video_load(vid_s3); break; case GFX_VIRGE: - video_load(vid_s3_virge); + device_add(&s3_virge_device); break; case GFX_TGUI9440: - video_load(vid_tgui9440); + device_add(&tgui9440_device); break; case GFX_VGA: - video_load(vid_vga); + device_add(&vga_device); break; case GFX_VGAEDGE16: - video_load(vid_ati18800); + device_add(&ati18800_device); break; case GFX_VGACHARGER: - video_load(vid_ati28800); + device_add(&ati18800_device); break; case GFX_OTI067: - video_load(vid_oti067); + device_add(&oti067_device); return; case GFX_MACH64GX: - video_load(vid_mach64); + device_add(&mach64gx_device); return; case GFX_CL_GD5429: - video_load(vid_gd5429); + device_add(&gd5429_device); return; default: @@ -263,78 +232,26 @@ void video_init() } } -uint32_t cga32[256]; -BITMAP *buffer,*vbuf;//,*vbuf2; -BITMAP *buffer32; -int speshul=0; +BITMAP *buffer, *buffer32; uint8_t fontdat[256][8]; uint8_t fontdatm[256][16]; -int dispontime,dispofftime; -double disptime; -int svgaon; -uint8_t cgamode=1,cgastat,cgacol=7,ocgamode; -int linepos=0; -int output; -uint8_t *vram,*ram; - -int cgadispon=0; -int cgablink; - -uint8_t port3de,port3dd,port3df; - -uint8_t crtc[128],crtcreg; -uint8_t crtcmask[128]={0xFF,0xFF,0xFF,0xFF,0x7F,0x1F,0x7F,0x7F,0xF3,0x1F,0x7F,0x1F,0x3F,0xFF,0x3F,0xFF,0xFF,0xFF}; -uint8_t charbuffer[256]; -int crtcams[64]={0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1}; -int nmi=0; - - int xsize=1,ysize=1; -int firstline=1000,lastline=0; -int ntsc_col[8][8]= + +PALETTE cgapal;/* = { - {0,0,0,0,0,0,0,0}, /*Black*/ - {0,0,1,1,1,1,0,0}, /*Blue*/ - {1,0,0,0,0,1,1,1}, /*Green*/ - {0,0,0,0,1,1,1,1}, /*Cyan*/ - {1,1,1,1,0,0,0,0}, /*Red*/ - {0,1,1,1,1,0,0,0}, /*Magenta*/ - {1,1,0,0,0,0,1,1}, /*Yellow*/ - {1,1,1,1,1,1,1,1} /*White*/ -}; + { 0, 0, 0},{0,42,0},{42,0,0},{42,21,0}, + { 0, 0, 0},{0,42,42},{42,0,42},{42,42,42}, + { 0, 0, 0},{21,63,21},{63,21,21},{63,63,21}, + { 0, 0, 0},{21,63,63},{63,21,63},{63,63,63}, - -extern int fullchange; - -extern uint32_t vrammask; - - -int mdacols[256][2][2]; -uint8_t gdcreg[16]; - - -int cga4pal[8][4]= -{ - {0,2,4,6},{0,3,5,7},{0,3,4,7},{0,3,4,7}, - {0,10,12,14},{0,11,13,15},{0,11,12,15},{0,11,12,15} -}; - - -PALETTE cgapal= -{ - {0,0,0},{0,42,0},{42,0,0},{42,21,0}, - {0,0,0},{0,42,42},{42,0,42},{42,42,42}, - {0,0,0},{21,63,21},{63,21,21},{63,63,21}, - {0,0,0},{21,63,63},{63,21,63},{63,63,63}, - - {0,0,0},{0,0,42},{0,42,0},{0,42,42}, - {42,0,0},{42,0,42},{42,21,00},{42,42,42}, - {21,21,21},{21,21,63},{21,63,21},{21,63,63}, - {63,21,21},{63,21,63},{63,63,21},{63,63,63}, + {0, 0, 0}, { 0, 0, 42}, { 0, 42, 0}, { 0, 42, 42}, + {42, 0, 0}, {42, 0, 42}, {42, 21, 00}, {42, 42, 42}, + {21, 21, 21}, {21, 21, 63}, {21, 63, 21}, {21, 63, 63}, + {63, 21, 21}, {63, 21, 63}, {63, 63, 21}, {63, 63, 63}, {0,0,0},{0,21,0},{0,0,42},{0,42,42}, {42,0,21},{21,10,21},{42,0,42},{42,0,63}, @@ -345,7 +262,7 @@ PALETTE cgapal= {0,0,0},{0,42,42},{42,0,0},{42,42,42}, {0,0,0},{0,63,63},{63,0,0},{63,63,63}, {0,0,0},{0,63,63},{63,0,0},{63,63,63}, -}; +};*/ void loadfont(char *s, int format) { @@ -419,102 +336,53 @@ void loadfont(char *s, int format) } -void drawscreen() -{ -// printf("Drawscreen %i %i %i %i\n",gfxcard,MDA,EGA,TANDY); -// if (EGA) drawscreenega(buffer,vbuf); -/* else if (MDA) {}//drawscreenmda(); - else if (TANDY) - { - if ((cgamode&3)==3 || array[3]&0x10) drawscreentandy(tandyvram); - else drawscreencga(tandyvram); - }*/ -// else drawscreencga(&vram[0x8000]); -} - -PALETTE comppal= -{ - {0,0,0},{0,21,0},{0,0,42},{0,42,42}, - {42,0,21},{21,10,21},{42,0,42},{42,0,63}, - {21,21,21},{21,63,21},{42,21,42},{21,63,31}, - {63,0,0},{42,42,0},{63,21,42},{41,41,41} -}; - void initvideo() { - int c; -// set_color_depth(desktop_color_depth()); -// if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,2048,2048,0,0)) -// set_gfx_mode(GFX_AUTODETECT_WINDOWED,1024,768,0,0); -// vbuf=create_video_bitmap(1280+32,1024+32); -// set_color_depth(32); - buffer32=create_bitmap(2048,2048); -// set_color_depth(8); - buffer=create_bitmap(2048,2048); -// set_color_depth(32); - for (c=0;c<64;c++) - { - cgapal[c+64].r=(((c&4)?2:0)|((c&0x10)?1:0))*21; - cgapal[c+64].g=(((c&2)?2:0)|((c&0x10)?1:0))*21; - cgapal[c+64].b=(((c&1)?2:0)|((c&0x10)?1:0))*21; - if ((c&0x17)==6) cgapal[c+64].g>>=1; - } - for (c=0;c<64;c++) - { - cgapal[c+128].r=(((c&4)?2:0)|((c&0x20)?1:0))*21; - cgapal[c+128].g=(((c&2)?2:0)|((c&0x10)?1:0))*21; - cgapal[c+128].b=(((c&1)?2:0)|((c&0x08)?1:0))*21; - } - for (c=0;c<256;c++) cga32[c]=makecol(cgapal[c].r<<2,cgapal[c].g<<2,cgapal[c].b<<2); -// for (c=0;c<16;c++) cgapal[c+192]=comppal[c]; -// set_palette(cgapal); - if (MDA && !TANDY && !AMSTRAD && romset!=ROM_PC200) updatewindowsize(720,350); - else updatewindowsize(656,416); - for (c=17;c<64;c++) crtcmask[c]=0xFF; -} + int c, d, e; -void resetvideo() -{ - int c; - if (MDA && !TANDY && !AMSTRAD && romset!=ROM_PC200) updatewindowsize(720,350); - else updatewindowsize(656,416); - cgastat=0; - set_palette(cgapal); + buffer32 = create_bitmap(2048, 2048); - for (c=18;c<64;c++) crtcmask[c]=0xFF; - crtc[0]=0x38; - crtc[1]=0x28; -// crtc[3]=0xFA; - crtc[4]=0x7F; - crtc[5]=0x06; - crtc[6]=0x64; - crtc[7]=0x70; - crtc[8]=0x02; - crtc[9]=1; + buffer = create_bitmap(2048, 2048); - cgacol=7; - for (c=0;c<256;c++) + for (c = 0; c < 64; c++) { - mdacols[c][0][0]=mdacols[c][1][0]=mdacols[c][1][1]=16; - if (c&8) mdacols[c][0][1]=15+16; - else mdacols[c][0][1]=7+16; + cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; + cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; + cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; + if ((c & 0x17) == 6) + cgapal[c + 64].g >>= 1; + } + for (c = 0; c < 64; c++) + { + cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21; + cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; + cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21; + } + + for (c = 0; c < 256; c++) + { + e = c; + for (d = 0; d < 8; d++) + { + rotatevga[d][c] = e; + e = (e >> 1) | ((e & 1) ? 0x80 : 0); + } + } + for (c = 0; c < 4; c++) + { + for (d = 0; d < 4; d++) + { + edatlookup[c][d] = 0; + if (c & 1) edatlookup[c][d] |= 1; + if (d & 1) edatlookup[c][d] |= 2; + if (c & 2) edatlookup[c][d] |= 0x10; + if (d & 2) edatlookup[c][d] |= 0x20; +// printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]); + } } - mdacols[0x70][0][1]=16; - mdacols[0x70][0][0]=mdacols[0x70][1][0]=mdacols[0x70][1][1]=16+15; - mdacols[0xF0][0][1]=16; - mdacols[0xF0][0][0]=mdacols[0xF0][1][0]=mdacols[0xF0][1][1]=16+15; - mdacols[0x78][0][1]=16+7; - mdacols[0x78][0][0]=mdacols[0x78][1][0]=mdacols[0x78][1][1]=16+15; - mdacols[0xF8][0][1]=16+7; - mdacols[0xF8][0][0]=mdacols[0xF8][1][0]=mdacols[0xF8][1][1]=16+15; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; } void closevideo() { destroy_bitmap(buffer); - destroy_bitmap(vbuf); } diff --git a/src/video.h b/src/video.h index 2909fad..de7fa3f 100644 --- a/src/video.h +++ b/src/video.h @@ -1,70 +1,8 @@ extern int egareads,egawrites; -extern int bpp; -extern uint8_t svgaseg,svgaseg2; - -extern uint8_t crtcreg; -extern uint8_t crtc[128]; -extern uint8_t crtcmask[128]; -extern uint8_t gdcreg[16]; -extern int gdcaddr; -extern uint8_t attrregs[32]; -extern int attraddr,attrff; -extern uint8_t seqregs[64]; -extern int seqaddr; -extern int svgaon; - -extern uint8_t cgamode,cgacol,cgastat; -extern int egapal[16]; - -extern int scrblank; - -extern uint8_t writemask,charset; -extern int charseta,charsetb; -extern uint8_t colourcompare,colournocare; -extern int readplane,readmode,writemode; - -extern int vidclock; -extern int vres; - -extern uint32_t *pallook,pallook16[256],pallook64[256],pallook256[256]; - extern int fullchange; extern int changeframecount; -extern int firstline,lastline; -extern int ega_hdisp,ega_rowoffset,ega_split,ega_dispend,ega_vsyncstart,ega_vtotal; -extern int dispontime,dispofftime; -extern double disptime; - -extern void (*video_out) (uint16_t addr, uint8_t val, void *priv); -extern void (*video_mono_out)(uint16_t addr, uint8_t val, void *priv); -extern uint8_t (*video_in) (uint16_t addr, void *priv); -extern uint8_t (*video_mono_in)(uint16_t addr, void *priv); - -extern void (*video_write_a000)(uint32_t addr, uint8_t val, void *priv); -extern void (*video_write_b000)(uint32_t addr, uint8_t val, void *priv); -extern void (*video_write_b800)(uint32_t addr, uint8_t val, void *priv); - -extern uint8_t (*video_read_a000)(uint32_t addr, void *priv); -extern uint8_t (*video_read_b000)(uint32_t addr, void *priv); -extern uint8_t (*video_read_b800)(uint32_t addr, void *priv); - -extern void (*video_write_a000_w)(uint32_t addr, uint16_t val, void *priv); -extern void (*video_write_a000_l)(uint32_t addr, uint32_t val, void *priv); - -extern void video_out_null(uint16_t addr, uint8_t val, void *priv); -extern uint8_t video_in_null(uint16_t addr, void *priv); - -extern void video_write_null(uint32_t addr, uint8_t val, void *priv); -extern uint8_t video_read_null (uint32_t addr, void *priv); - - -extern int video_timer; - -extern uint8_t tridentoldctrl2,tridentnewctrl2; -extern int rowdbl; - typedef struct { int w, h; @@ -72,73 +10,23 @@ typedef struct uint8_t *line[0]; } BITMAP; -extern BITMAP *buffer,*buffer32,*vbuf; +extern BITMAP *buffer, *buffer32; extern BITMAP *screen; BITMAP *create_bitmap(int w, int h); -extern int wx,wy; - extern uint8_t fontdat[256][8]; extern uint8_t fontdatm[256][16]; - extern int xsize,ysize; -extern int dacread,dacwrite,dacpos; - typedef struct { uint8_t r, g, b; } RGB; typedef RGB PALETTE[256]; -extern PALETTE vgapal; -extern int palchange; - - -extern uint32_t vrammask; - -typedef struct -{ - int (*init)(); - void (*out)(uint16_t addr, uint8_t val, void *priv); - uint8_t (*in)(uint16_t addr, void *priv); - void (*mono_out)(uint16_t addr, uint8_t val, void *priv); - uint8_t (*mono_in)(uint16_t addr, void *priv); - void (*poll)(); - void (*recalctimings)(); - void (*write_a000)(uint32_t addr, uint8_t val, void *priv); - void (*write_b000)(uint32_t addr, uint8_t val, void *priv); - void (*write_b800)(uint32_t addr, uint8_t val, void *priv); - uint8_t (*read_a000)(uint32_t addr, void *priv); - uint8_t (*read_b000)(uint32_t addr, void *priv); - uint8_t (*read_b800)(uint32_t addr, void *priv); -} GFXCARD; - -extern GFXCARD vid_cga; -extern GFXCARD vid_mda; -extern GFXCARD vid_hercules; -extern GFXCARD vid_pc1512; -extern GFXCARD vid_pc1640; -extern GFXCARD vid_pc200; -extern GFXCARD vid_m24; -extern GFXCARD vid_paradise; -extern GFXCARD vid_tandy; -extern GFXCARD vid_ega; -extern GFXCARD vid_oti067; -extern GFXCARD vid_tvga; -extern GFXCARD vid_et4000; -extern GFXCARD vid_et4000w32p; -extern GFXCARD vid_s3; -extern GFXCARD vid_s3_virge; -extern GFXCARD vid_tgui9440; -extern GFXCARD vid_vga; -extern GFXCARD vid_ati18800; -extern GFXCARD vid_ati28800; -extern GFXCARD vid_mach64; -extern GFXCARD vid_gd5429; extern float cpuclock; @@ -154,7 +42,6 @@ extern void (*video_recalctimings)(); extern void (*video_blit_memtoscreen)(int x, int y, int y1, int y2, int w, int h); extern void (*video_blit_memtoscreen_8)(int x, int y, int w, int h); - extern int video_timing_b, video_timing_w, video_timing_l; extern int video_speed; diff --git a/src/win.c b/src/win.c index 9f67ade..6a0203b 100644 --- a/src/win.c +++ b/src/win.c @@ -377,6 +377,9 @@ int WINAPI WinMain (HINSTANCE hThisInstance, } } } + + loadbios(); + timeBeginPeriod(1); // soundobject=CreateEvent(NULL, FALSE, FALSE, NULL); // soundthreadh=CreateThread(NULL,0,soundthread,NULL,NULL,NULL); @@ -758,8 +761,8 @@ BOOL CALLBACK configdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara sound_card_current = temp_sound_card_current; mem_resize(); - loadbios(); mem_load_video_bios(); + loadbios(); resetpchard(); } else @@ -1327,6 +1330,7 @@ BOOL CALLBACK statusdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara { int egasp; char s[256]; + char device_s[4096]; switch (message) { case WM_INITDIALOG: @@ -1350,18 +1354,8 @@ BOOL CALLBACK statusdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara SendDlgItemMessage(hdlg,IDC_STEXT7,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); sprintf(s,"Timer 0 frequency : %fHz",pit_timer0_freq()); SendDlgItemMessage(hdlg,IDC_STEXT8,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); - if (chain4) sprintf(s,"VGA chained (possibly mode 13h)"); - else sprintf(s,"VGA unchained (possibly mode-X)"); - SendDlgItemMessage(hdlg,IDC_STEXT9,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); -/* if (!video_bpp) sprintf(s,"VGA in text mode"); - else */sprintf(s,"VGA colour depth : %i bpp", video_bpp); - SendDlgItemMessage(hdlg,IDC_STEXT10,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); - sprintf(s,"VGA resolution : %i x %i", video_res_x, video_res_y); - SendDlgItemMessage(hdlg,IDC_STEXT11,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); - sprintf(s,"SB frequency : %i Hz",0); - SendDlgItemMessage(hdlg,IDC_STEXT12,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); - sprintf(s,"Video refresh rate : %i Hz", emu_fps); - SendDlgItemMessage(hdlg,IDC_STEXT13,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); + device_add_status_info(device_s, 4096); + SendDlgItemMessage(hdlg,IDC_STEXT_DEVICE,WM_SETTEXT,(WPARAM)NULL,(LPARAM)device_s); return TRUE; case WM_COMMAND: switch (LOWORD(wParam))