diff --git a/src/386.c b/src/386.c index a8fa33e..eb2b800 100644 --- a/src/386.c +++ b/src/386.c @@ -64,7 +64,7 @@ int cgate32; uint32_t mmucache[0x100000]; uint8_t romext[32768]; -uint8_t *ram,*rom,*vram,*vrom; +uint8_t *ram,*rom; uint16_t biosmask; uint32_t rmdat32; diff --git a/src/808x.c b/src/808x.c index b6f19df..1848b4b 100644 --- a/src/808x.c +++ b/src/808x.c @@ -561,14 +561,8 @@ chdir(pcempath); f=fopen("ram8.bin","wb"); fwrite(ram+0x3D210,0x200,1,f); fclose(f); */ - f=fopen("vram.dmp","wb"); - fwrite(vram,0x400000,1,f); - fclose(f); /* f=fopen("bios.dmp","wb"); fwrite(rom,0x20000,1,f); - fclose(f); - f=fopen("vbios.dmp","wb"); - fwrite(vrom,0x8000,1,f); fclose(f);*/ /* f=fopen("kernel.dmp","wb"); for (c=0;c<0x200000;c++) putc(readmemb(c+0xC0000000),f); diff --git a/src/Makefile.mingw b/src/Makefile.mingw index cf34e12..31aa708 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -4,7 +4,7 @@ CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \ - config.o cpu.o dac.o device.o dma.o ega.o fdc.o \ + config.o cpu.o dac.o device.o dma.o fdc.o \ headland.o i430vx.o ide.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o \ mouse.o mouse_ps2.o mouse_serial.o neat.o nvr.o olivetti_m24.o \ diff --git a/src/ali1429.c b/src/ali1429.c index 5a156c2..8c22573 100644 --- a/src/ali1429.c +++ b/src/ali1429.c @@ -9,9 +9,42 @@ static int ali1429_index; static uint8_t ali1429_regs[256]; +static void ali1429_recalc() +{ + int c; + + for (c = 0; c < 8; c++) + { + uint32_t base = 0xc0000 + (c << 15); + if (ali1429_regs[0x13] & (1 << c)) + { + switch (ali1429_regs[0x14] & 3) + { + case 0: + mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + } + else + mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + + flushmmucache(); +} + void ali1429_write(uint16_t port, uint8_t val, void *priv) { -// return; + int c; + if (!(port & 1)) ali1429_index = val; else @@ -21,35 +54,12 @@ void ali1429_write(uint16_t port, uint8_t val, void *priv) switch (ali1429_index) { case 0x13: - if (!(val & 0xc0)) - { - shadowbios = 0; - if (!shadowbios_write) - mem_bios_set_state(0xf0000, 0x10000, 0, 0); - else - mem_bios_set_state(0xf0000, 0x10000, 0, 1); - flushmmucache(); - } + ali1429_recalc(); break; case 0x14: shadowbios = val & 1; shadowbios_write = val & 2; - switch (val & 3) - { - case 0: - mem_bios_set_state(0xf0000, 0x10000, 0, 0); - break; - case 1: - mem_bios_set_state(0xf0000, 0x10000, 1, 0); - break; - case 2: - mem_bios_set_state(0xf0000, 0x10000, 0, 1); - break; - case 3: - mem_bios_set_state(0xf0000, 0x10000, 1, 1); - break; - } - flushmmucache(); + ali1429_recalc(); break; } } diff --git a/src/ega.c b/src/ega.c deleted file mode 100644 index 2dcca31..0000000 --- a/src/ega.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "ibm.h" -#include "video.h" - - -void dumpegaregs() -{ -/* int c; - printf("CRTC :"); - for (c=0;c<0x20;c++) printf(" %02X",crtc[c]); - printf("\n"); - printf(" EXT :"); - for (c=0;c<0x20;c++) printf(" %02X",crtc[c+32]); - printf("\n"); - printf(" EXT2:"); - for (c=0;c<0x20;c++) printf(" %02X",crtc[c+64]); - printf("\n"); - printf("SEQ :"); - for (c=0;c<0x10;c++) printf(" %02X",seqregs[c]); - printf("\n"); - printf(" EXT :"); - for (c=0;c<0x10;c++) printf(" %02X",seqregs[c + 0x10]); - printf("\n"); - printf("ATTR :"); - for (c=0;c<0x20;c++) printf(" %02X",attrregs[c]); - printf("\n"); - printf("GDC :"); - 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);*/ -} - diff --git a/src/headland.c b/src/headland.c index d6fae72..b4f460f 100644 --- a/src/headland.c +++ b/src/headland.c @@ -20,9 +20,9 @@ void headland_write(uint16_t addr, uint8_t val, void *priv) shadowbios = val & 0x10; shadowbios_write = !(val & 0x10); if (shadowbios) - mem_bios_set_state(0xf0000, 0x10000, 1, 0); + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); else - mem_bios_set_state(0xf0000, 0x10000, 0, 1); + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); } } else diff --git a/src/i430vx.c b/src/i430vx.c index f058ccc..5f2cb05 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -13,16 +13,22 @@ static void i430vx_map(uint32_t addr, uint32_t size, int state) { switch (state & 3) { - case 0x0: mem_bios_set_state(addr, size, 0, 0); break; /*DRAM disabled, accesses directed to PCI bus*/ - case 0x1: mem_bios_set_state(addr, size, 1, 0); break; /*Read only, DRAM write protected, non-cacheable*/ - case 0x2: mem_bios_set_state(addr, size, 0, 1); break; /*Write only*/ - case 0x3: mem_bios_set_state(addr, size, 1, 1); break; /*Read/write, non-cacheable*/ - /*Below are redundant*/ -// case 0x5: mem_sethandler(addr, size, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL ); break; /*Read only, DRAM write protected, cacheable*/ -// case 0x7: mem_sethandler(addr, size, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); break; /*Read/write, non-cacheable*/ + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; } flushmmucache_nopc(); } + void i430vx_write(int func, int addr, uint8_t val, void *priv) { if (func) @@ -43,18 +49,42 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv) } pclog("i430vx_write : PAM0 write %02X\n", val); break; + case 0x5a: /*PAM1*/ + if ((card_i430vx[0x5a] ^ val) & 0x0f) + i430vx_map(0xc0000, 0x04000, val & 0xf); + if ((card_i430vx[0x5a] ^ val) & 0xf0) + i430vx_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((card_i430vx[0x5b] ^ val) & 0x0f) + i430vx_map(0xc8000, 0x04000, val & 0xf); + if ((card_i430vx[0x5b] ^ val) & 0xf0) + i430vx_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((card_i430vx[0x5c] ^ val) & 0x0f) + i430vx_map(0xd0000, 0x04000, val & 0xf); + if ((card_i430vx[0x5c] ^ val) & 0xf0) + i430vx_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((card_i430vx[0x5d] ^ val) & 0x0f) + i430vx_map(0xd8000, 0x04000, val & 0xf); + if ((card_i430vx[0x5d] ^ val) & 0xf0) + i430vx_map(0xdc000, 0x04000, val >> 4); + break; case 0x5e: /*PAM5*/ if ((card_i430vx[0x5e] ^ val) & 0x0f) - i430vx_map(0xe0000, 0x04000, val & 0xf); + i430vx_map(0xe0000, 0x04000, val & 0xf); if ((card_i430vx[0x5e] ^ val) & 0xf0) - i430vx_map(0xe4000, 0x04000, val >> 4); + i430vx_map(0xe4000, 0x04000, val >> 4); pclog("i430vx_write : PAM5 write %02X\n", val); break; case 0x5f: /*PAM6*/ if ((card_i430vx[0x5f] ^ val) & 0x0f) - i430vx_map(0xe8000, 0x04000, val & 0xf); + i430vx_map(0xe8000, 0x04000, val & 0xf); if ((card_i430vx[0x5f] ^ val) & 0xf0) - i430vx_map(0xec000, 0x04000, val >> 4); + i430vx_map(0xec000, 0x04000, val >> 4); pclog("i430vx_write : PAM6 write %02X\n", val); break; } diff --git a/src/mem.c b/src/mem.c index 15fe5c6..5e74022 100644 --- a/src/mem.c +++ b/src/mem.c @@ -16,20 +16,25 @@ #include "cpu.h" #include "rom.h" -static uint8_t (*_mem_read_b[0x40000])(uint32_t addr, void *priv); -static uint16_t (*_mem_read_w[0x40000])(uint32_t addr, void *priv); -static uint32_t (*_mem_read_l[0x40000])(uint32_t addr, void *priv); -static void (*_mem_write_b[0x40000])(uint32_t addr, uint8_t val, void *priv); -static void (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv); -static void (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv); -static void *_mem_priv[0x40000]; -static mem_mapping_t *_mem_mapping[0x40000]; +static uint8_t (*_mem_read_b[0x40000])(uint32_t addr, void *priv); +static uint16_t (*_mem_read_w[0x40000])(uint32_t addr, void *priv); +static uint32_t (*_mem_read_l[0x40000])(uint32_t addr, void *priv); +static void (*_mem_write_b[0x40000])(uint32_t addr, uint8_t val, void *priv); +static void (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv); +static void (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv); +static uint8_t *_mem_exec[0x40000]; +static void *_mem_priv_r[0x40000]; +static void *_mem_priv_w[0x40000]; +static mem_mapping_t *_mem_mapping_r[0x40000]; +static mem_mapping_t *_mem_mapping_w[0x40000]; +static int _mem_state[0x40000]; static mem_mapping_t base_mapping; static mem_mapping_t ram_low_mapping; static mem_mapping_t ram_high_mapping; +static mem_mapping_t ram_mid_mapping; static mem_mapping_t bios_mapping[8]; -static mem_mapping_t vrom_mapping; +static mem_mapping_t bios_high_mapping[8]; static mem_mapping_t romext_mapping; int shadowbios,shadowbios_write; @@ -42,7 +47,7 @@ uint32_t biosmask; int readlnum=0,writelnum=0; int cachesize=256; -uint8_t *ram,*rom,*vram,*vrom; +uint8_t *ram,*rom,*vram; uint8_t romext[32768]; static void mem_load_xtide_bios() @@ -71,179 +76,6 @@ static void mem_load_atide_bios() } } -int mem_load_video_bios() -{ - FILE *f = NULL; - int c; - switch (gfxcard) - { - case GFX_EGA: - f=romfopen("roms/ibm_6277356_ega_card_u44_27128.bin","rb"); - if (f) - { - pclog("Read EGA ROM!\n"); - fread(vrom,16384,1,f); - if (vrom[0x3FFE]==0xAA && vrom[0x3FFF]==0x55) - { - pclog("Read EGA ROM in reverse\n"); - fseek(f,0,SEEK_SET); - for (c=0x3FFF;c>=0;c--) - vrom[c]=getc(f); - } - fclose(f); - return 1; - } - break; - - case GFX_TVGA: - f=romfopen("roms/trident.bin","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_ET4000: - f=romfopen("roms/et4000.bin","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_ET4000W32: - f=romfopen("roms/et4000w32.bin","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_BAHAMAS64: - f=romfopen("roms/bahamas64.bin","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_N9_9FX: - f=romfopen("roms/s3_764.bin","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_STEALTH64: - f=romfopen("roms/TRIO64 (Ver. 1.5-07) [VGA] (S3 Incorporated).bin","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_VIRGE: - f=romfopen("roms/s3virge.bin","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_TGUI9440: - f=romfopen("roms/9440.vbi","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_VGA: - f=romfopen("roms/ibm_vga.bin","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_VGAEDGE16: - f=romfopen("roms/vgaedge16.vbi","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_VGACHARGER: - f=romfopen("roms/bios.bin","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_OTI067: - f=romfopen("roms/oti067/bios.bin","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_MACH64GX: - f=romfopen("roms/mach64gx/bios.bin","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - case GFX_CL_GD5429: - f=romfopen("roms/5429.vbi","rb"); - if (f) - { - fread(vrom,32768,1,f); - fclose(f); - return 1; - } - break; - - default: - memset(vrom,0x63,0x8000); - return 1; - } - pclog("mem_load_video_bios : failed to load video BIOS for gfxcard %i\n", gfxcard); - memset(vrom,0x63,0x8000); - return 0; -} - int loadbios() { FILE *f=NULL,*ff=NULL; @@ -270,7 +102,6 @@ int loadbios() } fclose(ff); fclose(f); - memset(vrom,0x63,0x8000); mem_load_xtide_bios(); loadfont("roms/pc1512/40078.ic127", 2); return 1; @@ -287,7 +118,6 @@ int loadbios() fclose(f); f=romfopen("roms/pc1640/40100","rb"); if (!f) break; - fread(vrom,0x8000,1,f); fclose(f); mem_load_xtide_bios(); return 1; @@ -302,7 +132,6 @@ int loadbios() } fclose(ff); fclose(f); - memset(vrom,0x63,0x8000); mem_load_xtide_bios(); loadfont("roms/pc200/40109.bin", 1); return 1; @@ -311,7 +140,6 @@ int loadbios() if (!f) break; fread(rom,65536,1,f); fclose(f); - memset(vrom,0x63,0x8000); mem_load_xtide_bios(); return 1; /* case ROM_IBMPCJR: @@ -350,7 +178,6 @@ int loadbios() if (!f) break; fread(rom, 0x10000, 1, f); fclose(f); - memset(vrom,0x63,0x8000); return 1; case ROM_GENXT: @@ -396,11 +223,8 @@ int loadbios() fclose(f); f = romfopen("roms/pc2086/40186.ic171", "rb"); if (!f) break; - pclog("Loading VBIOS\n"); - fread(vrom, 32768, 1, f); fclose(f); mem_load_xtide_bios(); - pclog("%02X %02X %02X\n", rom[0xfff0], rom[0xfff1], rom[0xfff2]); biosmask = 0x3fff; return 1; @@ -411,11 +235,8 @@ int loadbios() fclose(f); f = romfopen("roms/pc3086/c000.bin", "rb"); if (!f) break; - pclog("Loading VBIOS\n"); - fread(vrom, 32768, 1, f); fclose(f); mem_load_xtide_bios(); - pclog("%02X %02X %02X\n", rom[0xfff0], rom[0xfff1], rom[0xfff2]); biosmask = 0x3fff; return 1; @@ -488,9 +309,7 @@ int loadbios() rom[0x40d4]=0x51; /*PUSH CX*/ f=romfopen("roms/acer386/oti067.bin","rb"); if (!f) break; - fread(vrom,0x8000,1,f); fclose(f); - vrom[0x5D]=0x74; return 1; case ROM_AMI286: @@ -536,15 +355,9 @@ int loadbios() return 1; case ROM_MEGAPC: - pclog("Loading MegaPC\n"); f = romfopen("roms/megapc/41651-bios lo.u18", "rb"); ff = romfopen("roms/megapc/211253-bios hi.u19", "rb"); if (!f || !ff) break; - for (c = 0x0000; c < 0x8000; c+=2) - { - vrom[c]=getc(f); - vrom[c+1]=getc(ff); - } fseek(f, 0x8000, SEEK_SET); fseek(ff, 0x8000, SEEK_SET); for (c = 0x0000; c < 0x10000; c+=2) @@ -567,7 +380,6 @@ int loadbios() case ROM_WIN486: // f=romfopen("roms/win486/win486.bin","rb"); f=romfopen("roms/win486/ALI1429G.AMW","rb"); - if (!f) break; fread(rom,65536,1,f); fclose(f); @@ -589,6 +401,7 @@ int loadbios() fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; + pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]); return 1; case ROM_430VX: @@ -970,10 +783,17 @@ pctrans=1; addreadlookup(a2,a); // if (a > 0xc0000000) // printf("%016X %016X %016X\n", ((long)a&0xFFFFF000), ((long)a2&~0xFFF), (uint8_t *)(a&0xFFFFF000) - (uint8_t *)(a2&~0xFFF)); +// pclog("getpccache: virt=%08x phys=%08x RAM\n", a2, a); return &ram[(uint8_t *)(a&0xFFFFF000) - (uint8_t *)(a2&~0xFFF)]; } // if (logit) printf("PCCACHE - %08X -> %08X\n",a2,a); - switch (a>>16) + if (_mem_exec[a >> 14]) + { +// pclog("getpccache: %p %p %p\n", ram, rom, &_mem_exec[a >> 14][(a & 0x3000) - (a2 & ~0xFFF)]); +// pclog("getpccache: virt=%08x phys=%08x %08x %08x %08x %08x\n", a2, a, _mem_exec[a >> 14], &_mem_exec[a >> 14][(a & 0x3000) - (a2 & ~0xFFF)], &_mem_exec[a >> 14][(a & 0x3000) - (a2 & ~0xFFF)] + 0xf0000, rom); + return &_mem_exec[a >> 14][(a & 0x3000) - (a2 & ~0xFFF)]; + } +/* switch (a>>16) { case 0xC: if (a&0x8000) return &romext[(uint8_t *)(a&0x7000) - (uint8_t *)(a2&~0xFFF)]; return &vrom[(uint8_t *)(a&0x7000) - (uint8_t *)(a2&~0xFFF)]; @@ -982,7 +802,8 @@ pctrans=1; case 0xF: if (shadowbios) return &ram[(uint8_t *)(a&0xFFF000) - (uint8_t *)(a2&~0xFFF)]; return &rom[(uint8_t *)((a & biosmask) & ~ 0xfff) - (uint8_t *)(a2 & ~0xFFF)]; } - return &rom[(long)(a&0xF000) - (long)(a2&~0xFFF)]; + return &rom[(long)(a&0xF000) - (long)(a2&~0xFFF)];*/ + fatal("Bad getpccache %08X\n", a); /*printf("Bad getpccache %08X\n",a); dumpregs(); exit(-1);*/ @@ -1000,7 +821,7 @@ uint8_t readmembl(uint32_t addr) } addr &= rammask; - if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv[addr >> 14]); + if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); // pclog("Bad readmembl %08X %04X:%08X\n", addr, CS, pc); return 0xFF; } @@ -1016,8 +837,8 @@ void writemembl(uint32_t addr, uint8_t val) } addr &= rammask; - if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv[addr >> 14]); -// else pclog("Bad write %08X %02X %04X:%08X\n", addr, val, CS, pc); + if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); +// else pclog("Bad writemembl %08X %02X %04X:%08X\n", addr, val, CS, pc); } uint8_t readmemb386l(uint32_t seg, uint32_t addr) @@ -1042,7 +863,7 @@ uint8_t readmemb386l(uint32_t seg, uint32_t addr) addr &= rammask; - if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv[addr >> 14]); + if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); // pclog("Bad readmemb386l %08X %04X:%08X\n", addr, CS, pc); return 0xFF; } @@ -1068,8 +889,8 @@ void writememb386l(uint32_t seg, uint32_t addr, uint8_t val) /* if (addr >= 0xa0000 && addr < 0xc0000) pclog("writemembl %08X %02X\n", addr, val);*/ - if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv[addr >> 14]); -// else pclog("Bad write %08X %02X %04X:%08X\n", addr, val, CS, pc); + if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); +// else pclog("Bad writememb386l %08X %02X %04X:%08X\n", addr, val, CS, pc); } uint16_t readmemwl(uint32_t seg, uint32_t addr) @@ -1099,13 +920,14 @@ uint16_t readmemwl(uint32_t seg, uint32_t addr) addr2 &= rammask; - if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]); + if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]); if (_mem_read_b[addr2 >> 14]) { - if (AT) return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv[addr2 >> 14]) << 8); - else return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv[addr2 >> 14]) << 8); + if (AT) return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8); + else return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv_r[addr2 >> 14]) << 8); } +// pclog("Bad readmemwl %08X\n", addr2); return 0xffff; } @@ -1151,17 +973,17 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val) if (_mem_write_w[addr2 >> 14]) { - _mem_write_w[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]); + _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); return; } if (_mem_write_b[addr2 >> 14]) { - _mem_write_b[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]); - _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); return; } -// pclog("Bad write %08X %04X\n", addr2, val); +// pclog("Bad writememwl %08X %04X\n", addr2, val); } uint32_t readmemll(uint32_t seg, uint32_t addr) @@ -1192,12 +1014,13 @@ uint32_t readmemll(uint32_t seg, uint32_t addr) addr2&=rammask; - if (_mem_read_l[addr2 >> 14]) return _mem_read_l[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]); + if (_mem_read_l[addr2 >> 14]) return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]); - if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv[addr2 >> 14]) << 16); + if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16); - if (_mem_read_b[addr2 >> 14]) return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv[addr2 >> 14]) << 8) | (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv[addr2 >> 14]) << 16) | (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv[addr2 >> 14]) << 24); + if (_mem_read_b[addr2 >> 14]) return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8) | (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16) | (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv_r[addr2 >> 14]) << 24); +// pclog("Bad readmemll %08X\n", addr2); return 0xffffffff; } @@ -1235,24 +1058,24 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) if (_mem_write_l[addr2 >> 14]) { - _mem_write_l[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]); + _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); return; } if (_mem_write_w[addr2 >> 14]) { - _mem_write_w[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv[addr2 >> 14]); + _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); return; } if (_mem_write_b[addr2 >> 14]) { - _mem_write_b[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]); return; } -// pclog("Bad write %08X %08X\n", addr2, val); +// pclog("Bad writememll %08X %08X\n", addr2, val); } uint8_t mem_readb_phys(uint32_t addr) @@ -1260,7 +1083,7 @@ uint8_t mem_readb_phys(uint32_t addr) mem_logical_addr = 0xffffffff; if (_mem_read_b[addr >> 14]) - return _mem_read_b[addr >> 14](addr, _mem_priv[addr >> 14]); + return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); return 0xff; } @@ -1270,24 +1093,24 @@ void mem_writeb_phys(uint32_t addr, uint8_t val) mem_logical_addr = 0xffffffff; if (_mem_write_b[addr >> 14]) - _mem_write_b[addr >> 14](addr, val, _mem_priv[addr >> 14]); + _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); } uint8_t mem_read_ram(uint32_t addr, void *priv) { -// if (addr >= 0xe0000 && addr < 0x100000) pclog("Read RAMb %08X\n", addr); +// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMb %08X\n", addr); addreadlookup(mem_logical_addr, addr); return ram[addr]; } uint16_t mem_read_ramw(uint32_t addr, void *priv) { -// if (addr >= 0xe0000 && addr < 0x100000) pclog("Read RAMw %08X\n", addr); +// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMw %08X\n", addr); addreadlookup(mem_logical_addr, addr); return *(uint16_t *)&ram[addr]; } uint32_t mem_read_raml(uint32_t addr, void *priv) { -// if (addr >= 0xe0000 && addr < 0x100000) pclog("Read RAMl %08X\n", addr); +// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMl %08X\n", addr); addreadlookup(mem_logical_addr, addr); return *(uint32_t *)&ram[addr]; } @@ -1296,19 +1119,19 @@ void mem_write_ram(uint32_t addr, uint8_t val, void *priv) { addwritelookup(mem_logical_addr, addr); ram[addr] = val; -// if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMb %08X\n", addr); +// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Write RAMb %08X\n", addr); } void mem_write_ramw(uint32_t addr, uint16_t val, void *priv) { addwritelookup(mem_logical_addr, addr); *(uint16_t *)&ram[addr] = val; -// if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMw %08X %04X:%04X %i %04X %04X:%04X %04X:%04X\n", addr, CS, pc, ins, val, DS,SI, ES,DI); +// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Write RAMw %08X %04X:%04X %i %04X %04X:%04X %04X:%04X\n", addr, CS, pc, ins, val, DS,SI, ES,DI); } void mem_write_raml(uint32_t addr, uint32_t val, void *priv) { addwritelookup(mem_logical_addr, addr); *(uint32_t *)&ram[addr] = val; -// if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMl %08X %04X:%04X %04X:%04X %04X:%04X\n", addr, CS, pc, DS,SI, ES,DI); +// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Write RAMl %08X %04X:%04X %04X:%04X %04X:%04X\n", addr, CS, pc, DS,SI, ES,DI); } uint8_t mem_read_bios(uint32_t addr, void *priv) @@ -1333,19 +1156,6 @@ uint32_t mem_read_biosl(uint32_t addr, void *priv) return *(uint32_t *)&rom[addr & biosmask]; } -uint8_t mem_read_vrom(uint32_t addr, void *priv) -{ - return vrom[addr & 0x7fff]; -} -uint16_t mem_read_vromw(uint32_t addr, void *priv) -{ - return *(uint16_t *)&vrom[addr & 0x7fff]; -} -uint32_t mem_read_vroml(uint32_t addr, void *priv) -{ - return *(uint32_t *)&vrom[addr & 0x7fff]; -} - uint8_t mem_read_romext(uint32_t addr, void *priv) { return romext[addr & 0x7fff]; @@ -1359,6 +1169,15 @@ uint32_t mem_read_romextl(uint32_t addr, void *priv) return *(uint32_t *)&romext[addr & 0x7fff]; } +void mem_write_null(uint32_t addr, uint8_t val, void *p) +{ +} +void mem_write_nullw(uint32_t addr, uint16_t val, void *p) +{ +} +void mem_write_nulll(uint32_t addr, uint32_t val, void *p) +{ +} void mem_updatecache() { @@ -1383,50 +1202,88 @@ void mem_updatecache() } } -static void mem_mapping_recalc(uint32_t base, uint32_t size) +static inline int mem_mapping_read_allowed(uint32_t flags, int state) { - uint32_t c; +// pclog("mem_mapping_read_allowed: flags=%x state=%x\n", flags, state); + switch (state & MEM_READ_MASK) + { + case MEM_READ_ANY: + return 1; + case MEM_READ_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL); + case MEM_READ_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + default: + fatal("mem_mapping_read_allowed : bad state %x\n", state); + } +} + +static inline int mem_mapping_write_allowed(uint32_t flags, int state) +{ + switch (state & MEM_WRITE_MASK) + { + case MEM_WRITE_DISABLED: + return 0; + case MEM_WRITE_ANY: + return 1; + case MEM_WRITE_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL); + case MEM_WRITE_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + default: + fatal("mem_mapping_write_allowed : bad state %x\n", state); + } +} + +static void mem_mapping_recalc(uint64_t base, uint64_t size) +{ + uint64_t c; mem_mapping_t *mapping = base_mapping.next; - if ((base + size) > 0xffff8000) - size = 0xffff0000 - base; - /*Clear out old mappings*/ for (c = base; c < base + size; c += 0x4000) { _mem_read_b[c >> 14] = NULL; _mem_read_w[c >> 14] = NULL; _mem_read_l[c >> 14] = NULL; + _mem_priv_r[c >> 14] = NULL; + _mem_mapping_r[c >> 14] = NULL; _mem_write_b[c >> 14] = NULL; _mem_write_w[c >> 14] = NULL; _mem_write_l[c >> 14] = NULL; - _mem_priv[c >> 14] = NULL; - _mem_mapping[c >> 14] = NULL; + _mem_priv_w[c >> 14] = NULL; + _mem_mapping_w[c >> 14] = NULL; } -// pclog("mem_mapping_recalc %08X %08X\n", base, size); + /*Walk mapping list*/ while (mapping != NULL) { -// pclog("mapping=%p next=%p base=%08X size=%08X enable=%i\n", mapping, mapping->next, mapping->base, mapping->size, mapping->enable); /*In range?*/ - if (mapping->enable && mapping->base < (base + size) && (mapping->base + mapping->size) >= base) + if (mapping->enable && (uint64_t)mapping->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)mapping->base + (uint64_t)mapping->size) > (uint64_t)base) { - uint32_t start = (mapping->base < base) ? mapping->base : base; - uint32_t end = ((mapping->base + mapping->size) < (base + size)) ? (mapping->base + mapping->size) : (base + size); - + uint64_t start = (mapping->base < base) ? mapping->base : base; + uint64_t end = (((uint64_t)mapping->base + (uint64_t)mapping->size) < (base + size)) ? ((uint64_t)mapping->base + (uint64_t)mapping->size) : (base + size); + for (c = start; c < end; c += 0x4000) { - if (_mem_mapping[c >> 14] == NULL) + if ((mapping->read_b || mapping->read_w || mapping->read_l) && + mem_mapping_read_allowed(mapping->flags, _mem_state[c >> 14])) { -// pclog(" Add %08X\n", c); _mem_read_b[c >> 14] = mapping->read_b; _mem_read_w[c >> 14] = mapping->read_w; _mem_read_l[c >> 14] = mapping->read_l; + _mem_exec[c >> 14] = mapping->exec + (c - mapping->base); + _mem_priv_r[c >> 14] = mapping->p; + _mem_mapping_r[c >> 14] = mapping; + } + if ((mapping->write_b || mapping->write_w || mapping->write_l) && + mem_mapping_write_allowed(mapping->flags, _mem_state[c >> 14])) + { _mem_write_b[c >> 14] = mapping->write_b; _mem_write_w[c >> 14] = mapping->write_w; _mem_write_l[c >> 14] = mapping->write_l; - _mem_priv[c >> 14] = mapping->p; - _mem_mapping[c >> 14] = mapping; + _mem_priv_w[c >> 14] = mapping->p; + _mem_mapping_w[c >> 14] = mapping; } } } @@ -1443,6 +1300,8 @@ void mem_mapping_add(mem_mapping_t *mapping, void (*write_b)(uint32_t addr, uint8_t val, void *p), void (*write_w)(uint32_t addr, uint16_t val, void *p), void (*write_l)(uint32_t addr, uint32_t val, void *p), + uint8_t *exec, + uint32_t flags, void *p) { mem_mapping_t *dest = &base_mapping; @@ -1464,6 +1323,8 @@ void mem_mapping_add(mem_mapping_t *mapping, mapping->write_b = write_b; mapping->write_w = write_w; mapping->write_l = write_l; + mapping->exec = exec; + mapping->flags = flags; mapping->p = p; mapping->next = NULL; @@ -1502,6 +1363,13 @@ void mem_mapping_set_addr(mem_mapping_t *mapping, uint32_t base, uint32_t size) mem_mapping_recalc(mapping->base, mapping->size); } +void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec) +{ + mapping->exec = exec; + + mem_mapping_recalc(mapping->base, mapping->size); +} + void mem_mapping_set_p(mem_mapping_t *mapping, void *p) { mapping->p = p; @@ -1521,6 +1389,38 @@ void mem_mapping_enable(mem_mapping_t *mapping) mem_mapping_recalc(mapping->base, mapping->size); } +void mem_set_mem_state(uint32_t base, uint32_t size, int state) +{ + uint32_t c; + +// pclog("mem_set_pci_enable: base=%08x size=%08x\n", base, size); + for (c = 0; c < size; c += 0x4000) + _mem_state[(c + base) >> 14] = state; + + mem_mapping_recalc(base, size); +} + +void mem_add_bios() +{ + mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_EXTERNAL, 0); + mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_EXTERNAL, 0); + mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_EXTERNAL, 0); + mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_EXTERNAL, 0); + mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_EXTERNAL, 0); + mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_EXTERNAL, 0); + mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_EXTERNAL, 0); + mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_EXTERNAL, 0); + + mem_mapping_add(&bios_high_mapping[0], 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, 0, 0); + mem_mapping_add(&bios_high_mapping[1], 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[2], 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[3], 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[4], 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[5], 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[6], 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[7], 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), 0, 0); +} + void mem_init() { int c; @@ -1528,7 +1428,6 @@ void mem_init() ram = malloc(mem_size * 1024 * 1024); rom = malloc(0x20000); vram = malloc(0x800000); - vrom = malloc(0x8000); readlookup2 = malloc(1024 * 1024 * 4); writelookup2 = malloc(1024 * 1024 * 4); cachelookup2 = malloc(1024 * 1024); @@ -1553,21 +1452,16 @@ void mem_init() memset(&base_mapping, 0, sizeof(base_mapping)); - mem_mapping_add(&ram_low_mapping, 0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); + memset(_mem_state, 0, sizeof(_mem_state)); + + mem_set_mem_state(0xc0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + mem_mapping_add(&ram_low_mapping, 0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram, 0, NULL); if (mem_size > 1) - mem_mapping_add(&ram_low_mapping, 0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); + mem_mapping_add(&ram_high_mapping, 0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, 0, NULL); + mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - - mem_mapping_add(&vrom_mapping, 0xc0000, 0x08000, mem_read_vrom, mem_read_vromw, mem_read_vroml, NULL, NULL, NULL, NULL); - mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, NULL); + mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); // pclog("Mem resize %i %i\n",mem_size,c); } @@ -1595,57 +1489,23 @@ void mem_resize() memset(_mem_write_l, 0, sizeof(_mem_write_l)); memset(&base_mapping, 0, sizeof(base_mapping)); + + memset(_mem_state, 0, sizeof(_mem_state)); - mem_mapping_add(&ram_low_mapping, 0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); + mem_set_mem_state(0xc0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + mem_mapping_add(&ram_low_mapping, 0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram, 0, NULL); if (mem_size > 1) - mem_mapping_add(&ram_low_mapping, 0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - - mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); - mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); + mem_mapping_add(&ram_high_mapping, 0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, 0, NULL); + mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_add(&vrom_mapping, 0xc0000, 0x08000, mem_read_vrom, mem_read_vromw, mem_read_vroml, NULL, NULL, NULL, NULL); - mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, NULL); + mem_add_bios(); + + mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); // pclog("Mem resize %i %i\n",mem_size,c); } -void mem_bios_set_state(uint32_t base, uint32_t size, int read_ram, int write_ram) -{ - uint32_t c; - int state = (read_ram ? 1 : 0) | (write_ram ? 2: 0); - - if (base < 0xe0000 || base > 0xfffff) - return; - if ((base + size) > 0x100000) - size = 0x100000 - base; - - for (c = base; c < (base + size); c+= 0x4000) - { -// pclog("mem_bios_set_state: c=%08X base=%08X size=%08X bios=%i\n", c, base, size, (c - 0xe0000) >> 14); - switch (state) - { - case 0: - mem_mapping_set_handler(&bios_mapping[(c - 0xe0000) >> 14], mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL); - break; - case 1: - mem_mapping_set_handler(&bios_mapping[(c - 0xe0000) >> 14], mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL); - break; - case 2: - mem_mapping_set_handler(&bios_mapping[(c - 0xe0000) >> 14], mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml); - break; - case 3: - mem_mapping_set_handler(&bios_mapping[(c - 0xe0000) >> 14], mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); - break; - } - } -} - int mem_a20_key = 0, mem_a20_alt = 0; static int mem_a20_state = 0; diff --git a/src/mem.h b/src/mem.h index dfafb66..b130239 100644 --- a/src/mem.h +++ b/src/mem.h @@ -14,10 +14,19 @@ typedef struct mem_mapping_t void (*write_w)(uint32_t addr, uint16_t val, void *priv); void (*write_l)(uint32_t addr, uint32_t val, void *priv); + uint8_t *exec; + + uint32_t flags; + void *p; } mem_mapping_t; -extern uint8_t *ram,*rom,*vram,*vrom; +/*Only present on external bus (ISA/PCI)*/ +#define MEM_MAPPING_EXTERNAL 1 +/*Only present on internal bus (RAM)*/ +#define MEM_MAPPING_INTERNAL 2 + +extern uint8_t *ram,*rom; extern uint8_t romext[32768]; extern int readlnum,writelnum; extern int memspeed[11]; @@ -34,6 +43,8 @@ void mem_mapping_add(mem_mapping_t *mapping, void (*write_b)(uint32_t addr, uint8_t val, void *p), void (*write_w)(uint32_t addr, uint16_t val, void *p), void (*write_l)(uint32_t addr, uint32_t val, void *p), + uint8_t *exec, + uint32_t flags, void *p); void mem_mapping_set_handler(mem_mapping_t *mapping, uint8_t (*read_b)(uint32_t addr, void *p), @@ -44,10 +55,22 @@ void mem_mapping_set_handler(mem_mapping_t *mapping, void (*write_l)(uint32_t addr, uint32_t val, void *p)); void mem_mapping_set_p(mem_mapping_t *mapping, void *p); void mem_mapping_set_addr(mem_mapping_t *mapping, uint32_t base, uint32_t size); +void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec); void mem_mapping_disable(mem_mapping_t *mapping); void mem_mapping_enable(mem_mapping_t *mapping); -void mem_bios_set_state(uint32_t base, uint32_t size, int read_ram, int write_ram); +void mem_set_mem_state(uint32_t base, uint32_t size, int state); + +#define MEM_READ_ANY 0x00 +#define MEM_READ_INTERNAL 0x10 +#define MEM_READ_EXTERNAL 0x20 +#define MEM_READ_MASK 0xf0 + +#define MEM_WRITE_ANY 0x00 +#define MEM_WRITE_INTERNAL 0x01 +#define MEM_WRITE_EXTERNAL 0x02 +#define MEM_WRITE_DISABLED 0x03 +#define MEM_WRITE_MASK 0x0f extern int mem_a20_alt; extern int mem_a20_key; @@ -68,6 +91,8 @@ uint8_t mem_read_bios(uint32_t addr, void *priv); uint16_t mem_read_biosw(uint32_t addr, void *priv); uint32_t mem_read_biosl(uint32_t addr, void *priv); -FILE *romfopen(char *fn, char *mode); +void mem_write_null(uint32_t addr, uint8_t val, void *p); +void mem_write_nullw(uint32_t addr, uint16_t val, void *p); +void mem_write_nulll(uint32_t addr, uint32_t val, void *p); -int mem_load_video_bios(); +FILE *romfopen(char *fn, char *mode); diff --git a/src/model.c b/src/model.c index eb20bfb..8d94136 100644 --- a/src/model.c +++ b/src/model.c @@ -78,12 +78,17 @@ MODEL models[] = {"AMI 386 clone", ROM_AMI386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, at_headland_init}, {"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init}, {"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init}, - {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_um8881f_init}, +/* {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_um8881f_init},*/ {"Award SiS 496/497", ROM_SIS496, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_sis496_init}, {"Award 430VX PCI", ROM_430VX, { "IDT", cpus_WinChip, "", NULL, "", NULL}, 0, at_i430vx_init}, {"", -1, {"", 0, "", 0, "", 0}, 0} }; +int model_count() +{ + return (sizeof(models) / sizeof(MODEL)) - 1; +} + int model_getromset() { return models[model].id; diff --git a/src/model.h b/src/model.h index 9f42c5c..91e1ebd 100644 --- a/src/model.h +++ b/src/model.h @@ -15,6 +15,7 @@ extern MODEL models[]; extern int model; +int model_count(); int model_getromset(); int model_getmodel(int romset); char *model_getname(); diff --git a/src/pc.c b/src/pc.c index 2d70adb..1895eb2 100644 --- a/src/pc.c +++ b/src/pc.c @@ -85,6 +85,7 @@ void fatal(const char *format, ...) va_end(ap); fputs(buf,pclogf); fflush(pclogf); + dumppic(); dumpregs(); exit(-1); } @@ -206,9 +207,9 @@ void initpc() initvideo(); mem_init(); - mem_load_video_bios(); loadbios(); - + mem_add_bios(); + loaddisc(0,discfns[0]); loaddisc(1,discfns[1]); @@ -436,6 +437,9 @@ void loadconfig() model = get_config_int(NULL, "model", 14); + if (model >= model_count()) + model = model_count() - 1; + romset = model_getromset(); cpu_manufacturer = get_config_int(NULL, "cpu_manufacturer", 0); cpu = get_config_int(NULL, "cpu", 0); diff --git a/src/pc.rc b/src/pc.rc index 352767a..6f690bb 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -47,20 +47,20 @@ BEGIN END END -ConfigureDlg DIALOGEX 0, 0, 182, 240 +ConfigureDlg DIALOGEX 0, 0, 232, 240 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configure PCem" FONT 8, "MS Sans Serif" BEGIN - DEFPUSHBUTTON "OK",IDOK,17,216,50,14, WS_TABSTOP - PUSHBUTTON "Cancel",IDCANCEL,71,216,50,14, WS_TABSTOP - COMBOBOX IDC_COMBO1,62,16,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBOVID,62,36,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBOCPUM,62,56,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO3,62,76,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBOCHC,62,96,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBOSPD,62,116,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBOSND,62,136,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,64,216,50,14, WS_TABSTOP + PUSHBUTTON "Cancel",IDCANCEL,128,216,50,14, WS_TABSTOP + COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBOCPUM,62,56,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO3,62,76,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBOCHC,62,96,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBOSPD,62,116,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBOSND,62,136,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP EDITTEXT IDC_MEMTEXT, 62, 152, 36, 14, ES_AUTOHSCROLL | ES_NUMBER CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 152, 12, 14 LTEXT "MB", IDC_STATIC, 98, 152, 40, 10 diff --git a/src/pci.h b/src/pci.h index eec1f33..f053f2f 100644 --- a/src/pci.h +++ b/src/pci.h @@ -1,3 +1,8 @@ void pci_init(); void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); + +#define PCI_REG_COMMAND 0x04 + +#define PCI_COMMAND_IO 0x01 +#define PCI_COMMAND_MEM 0x02 diff --git a/src/rom.c b/src/rom.c index d04c960..87fc885 100644 --- a/src/rom.c +++ b/src/rom.c @@ -1,5 +1,7 @@ +#include #include #include "ibm.h" +#include "mem.h" #include "rom.h" FILE *romfopen(char *fn, char *mode) @@ -27,3 +29,97 @@ int rom_present(char *fn) } return 0; } + +static uint8_t rom_read(uint32_t addr, void *p) +{ + rom_t *rom = (rom_t *)p; +// pclog("rom_read : %08x %08x %02x\n", addr, rom->mask, rom->rom[addr & rom->mask]); + return rom->rom[addr & rom->mask]; +} +uint16_t rom_readw(uint32_t addr, void *p) +{ + rom_t *rom = (rom_t *)p; +// pclog("rom_readw: %08x %08x %04x\n", addr, rom->mask, *(uint16_t *)&rom->rom[addr & rom->mask]); + return *(uint16_t *)&rom->rom[addr & rom->mask]; +} +uint32_t rom_readl(uint32_t addr, void *p) +{ + rom_t *rom = (rom_t *)p; +// pclog("rom_readl: %08x %08x %08x\n", addr, rom->mask, *(uint32_t *)&rom->rom[addr & rom->mask]); + return *(uint32_t *)&rom->rom[addr & rom->mask]; +} + +int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags) +{ + FILE *f = romfopen(fn, "rb"); + + if (!f) + { + pclog("ROM image not found : %s\n", fn); + return -1; + } + + rom->rom = malloc(size); + fseek(f, file_offset, SEEK_SET); + fread(rom->rom, size, 1, f); + fclose(f); + + rom->mask = mask; + + mem_mapping_add(&rom->mapping, address, size, rom_read, + rom_readw, + rom_readl, + mem_write_null, + mem_write_nullw, + mem_write_nulll, + rom->rom, + flags, + rom); + + return 0; +} + +int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags) +{ + FILE *f_low = romfopen(fn_low, "rb"); + FILE *f_high = romfopen(fn_high, "rb"); + int c; + + if (!f_low || !f_high) + { + if (!f_low) + pclog("ROM image not found : %s\n", fn_low); + else + fclose(f_low); + if (!f_high) + pclog("ROM image not found : %s\n", fn_high); + else + fclose(f_high); + return -1; + } + + rom->rom = malloc(size); + fseek(f_low, file_offset, SEEK_SET); + fseek(f_high, file_offset, SEEK_SET); + for (c = 0; c < size; c += 2) + { + rom->rom[c] = getc(f_low); + rom->rom[c + 1] = getc(f_high); + } + fclose(f_high); + fclose(f_low); + + rom->mask = mask; + + mem_mapping_add(&rom->mapping, address, size, rom_read, + rom_readw, + rom_readl, + mem_write_null, + mem_write_nullw, + mem_write_nulll, + rom->rom, + flags, + rom); + + return 0; +} diff --git a/src/rom.h b/src/rom.h index 62624c1..06ace63 100644 --- a/src/rom.h +++ b/src/rom.h @@ -1,2 +1,12 @@ FILE *romfopen(char *fn, char *mode); int rom_present(char *fn); + +typedef struct rom_t +{ + uint8_t *rom; + uint32_t mask; + mem_mapping_t mapping; +} rom_t; + +int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags); +int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags); diff --git a/src/sis496.c b/src/sis496.c index d18cab3..51633b4 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -14,45 +14,32 @@ typedef struct sis496_t void sis496_recalcmapping(sis496_t *sis496) { - if (sis496->pci_conf[0x44] & 0x10) + int c; + + for (c = 0; c < 8; c++) { - if (sis496->pci_conf[0x45] & 0x01) - mem_bios_set_state(0xe0000, 0x08000, 1, 0); + uint32_t base = 0xc0000 + (c << 15); + if (sis496->pci_conf[0x44] & (1 << c)) + { + switch (sis496->pci_conf[0x45] & 3) + { + case 0: + mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 1: + mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + } + } else - mem_bios_set_state(0xe0000, 0x08000, 1, 1); + mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } - else - mem_bios_set_state(0xe0000, 0x08000, 0, 1); - - if (sis496->pci_conf[0x44] & 0x20) - { - if (sis496->pci_conf[0x45] & 0x01) - mem_bios_set_state(0xe8000, 0x08000, 1, 0); - else - mem_bios_set_state(0xe8000, 0x08000, 1, 1); - } - else - mem_bios_set_state(0xe8000, 0x08000, 0, 1); - - if (sis496->pci_conf[0x44] & 0x40) - { - if (sis496->pci_conf[0x45] & 0x01) - mem_bios_set_state(0xf0000, 0x08000, 1, 0); - else - mem_bios_set_state(0xf0000, 0x08000, 1, 1); - } - else - mem_bios_set_state(0xf0000, 0x08000, 0, 1); - - if (sis496->pci_conf[0x44] & 0x80) - { - if (sis496->pci_conf[0x45] & 0x01) - mem_bios_set_state(0xf8000, 0x08000, 1, 0); - else - mem_bios_set_state(0xf8000, 0x08000, 1, 1); - } - else - mem_bios_set_state(0xf8000, 0x08000, 0, 1); flushmmucache(); shadowbios = (sis496->pci_conf[0x44] & 0xf0); @@ -61,7 +48,7 @@ void sis496_recalcmapping(sis496_t *sis496) void sis496_write(int func, int addr, uint8_t val, void *p) { sis496_t *sis496 = (sis496_t *)p; -//pclog("sis496_write : addr=%02x val=%02x\n", addr, val); + //pclog("sis496_write : addr=%02x val=%02x\n", addr, val); switch (addr) { case 0x44: /*Shadow configure*/ @@ -72,8 +59,6 @@ void sis496_write(int func, int addr, uint8_t val, void *p) } break; case 0x45: /*Shadow configure*/ - //if (val == 3) - // output = 3; if ((sis496->pci_conf[0x45] & val) ^ 0x01) { sis496->pci_conf[0x45] = val; diff --git a/src/sound_gus.c b/src/sound_gus.c index 03b0fed..b801923 100644 --- a/src/sound_gus.c +++ b/src/sound_gus.c @@ -638,8 +638,8 @@ uint8_t readgus(uint16_t addr, void *p) val = 0xff; break; - default: - fatal("Bad GUS global low read %02X\n",gus->global); +// default: +// fatal("Bad GUS global low read %02X\n",gus->global); } break; case 0x345: /*Global high*/ @@ -693,8 +693,8 @@ uint8_t readgus(uint16_t addr, void *p) val = 0xff; break; - default: - fatal("Bad GUS global high read %02X\n",gus->global); +// default: +// fatal("Bad GUS global high read %02X\n",gus->global); } break; case 0x346: return 0xff; diff --git a/src/um8881f.c b/src/um8881f.c index a045797..b469bbd 100644 --- a/src/um8881f.c +++ b/src/um8881f.c @@ -10,28 +10,29 @@ static uint8_t card_18[256]; void um8881f_write(int func, int addr, uint8_t val, void *priv) { +// pclog("um8881f_write : addr=%02x val=%02x %04x:%04x\n", addr, val, CS, pc); if (addr == 0x54) { - if ((card_16[0x54] ^ val) & 0x01) +/* if ((card_16[0x54] ^ val) & 0x01) { if (val & 1) mem_bios_set_state(0xe0000, 0x10000, 1, 1); else mem_bios_set_state(0xe0000, 0x10000, 0, 0); - } + }*/ flushmmucache_nopc(); } if (addr == 0x55) { if ((card_16[0x55] ^ val) & 0xc0) { - switch (val & 0xc0) +/* switch (val & 0xc0) { case 0x00: mem_bios_set_state(0xf0000, 0x10000, 0, 1); break; case 0x40: mem_bios_set_state(0xf0000, 0x10000, 0, 0); break; case 0x80: mem_bios_set_state(0xf0000, 0x10000, 1, 1); break; case 0xc0: mem_bios_set_state(0xf0000, 0x10000, 1, 0); break; - } + }*/ shadowbios = val & 0x80; shadowbios_write = !(val & 0x40); flushmmucache_nopc(); diff --git a/src/vid_ati18800.c b/src/vid_ati18800.c index 656d1bd..fa40d74 100644 --- a/src/vid_ati18800.c +++ b/src/vid_ati18800.c @@ -4,6 +4,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "video.h" #include "vid_ati18800.h" #include "vid_ati_eeprom.h" @@ -13,6 +14,8 @@ typedef struct ati18800_t { svga_t svga; ati_eeprom_t eeprom; + + rom_t bios_rom; uint8_t regs[256]; int index; @@ -122,6 +125,8 @@ void *ati18800_init() ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); memset(ati18800, 0, sizeof(ati18800_t)); + rom_init(&ati18800->bios_rom, "roms/vgaedge16.vbi", 0xc0000, 0x8000, 0x7fff, 0, 0); + svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/ NULL, ati18800_in, ati18800_out, @@ -137,6 +142,11 @@ void *ati18800_init() return ati18800; } +static int ati18800_available() +{ + return rom_present("roms/vgaedge16.vbi"); +} + void ati18800_close(void *p) { ati18800_t *ati18800 = (ati18800_t *)p; @@ -173,7 +183,7 @@ device_t ati18800_device = 0, ati18800_init, ati18800_close, - NULL, + ati18800_available, ati18800_speed_changed, ati18800_force_redraw, ati18800_add_status_info diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 19361a2..b68e5d2 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -4,6 +4,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "video.h" #include "vid_ati28800.h" #include "vid_ati_eeprom.h" @@ -15,6 +16,8 @@ typedef struct ati28800_t svga_t svga; ati_eeprom_t eeprom; + rom_t bios_rom; + uint8_t regs[256]; int index; } ati28800_t; @@ -143,6 +146,8 @@ void *ati28800_init() ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); memset(ati28800, 0, sizeof(ati28800_t)); + rom_init(&ati28800->bios_rom, "roms/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, 0); + svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ ati28800_recalctimings, ati28800_in, ati28800_out, @@ -158,6 +163,11 @@ void *ati28800_init() return ati28800; } +static int ati28800_available() +{ + return rom_present("roms/bios.bin"); +} + void ati28800_close(void *p) { ati28800_t *ati28800 = (ati28800_t *)p; @@ -194,7 +204,7 @@ device_t ati28800_device = 0, ati28800_init, ati28800_close, - NULL, + ati28800_available, ati28800_speed_changed, ati28800_force_redraw, ati28800_add_status_info diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index 03a44fd..4270f1a 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -5,6 +5,7 @@ #include "io.h" #include "mem.h" #include "pci.h" +#include "rom.h" #include "video.h" #include "vid_svga.h" #include "vid_ati68860_ramdac.h" @@ -25,8 +26,12 @@ typedef struct mach64_t ics2595_t ics2595; svga_t svga; + rom_t bios_rom; + uint8_t regs[256]; int index; + + uint8_t pci_regs[256]; int bank_r[2]; int bank_w[2]; @@ -338,6 +343,16 @@ void mach64_updatemapping(mach64_t *mach64) { svga_t *svga = &mach64->svga; + if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) + { + pclog("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&mach64->linear_mapping); + mem_mapping_disable(&mach64->mmio_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping); + return; + } + mem_mapping_disable(&mach64->mmio_mapping); // pclog("Write mapping %02X\n", val); switch (svga->gdcreg[6] & 0xc) @@ -1835,9 +1850,13 @@ uint16_t mach64_ext_inw(uint16_t port, void *p) switch (port) { default: +#ifdef MACH64_DEBUG pclog(" "); +#endif ret = mach64_ext_inb(port, p); +#ifdef MACH64_DEBUG pclog(" "); +#endif ret |= (mach64_ext_inb(port + 1, p) << 8); break; } @@ -1860,9 +1879,13 @@ uint32_t mach64_ext_inl(uint16_t port, void *p) break; default: +#ifdef MACH64_DEBUG pclog(" "); +#endif ret = mach64_ext_inw(port, p); +#ifdef MACH64_DEBUG pclog(" "); +#endif ret |= (mach64_ext_inw(port + 2, p) << 16); break; } @@ -2053,6 +2076,42 @@ void mach64_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += 16; } +static void mach64_io_remove(mach64_t *mach64) +{ + int c; + + io_removehandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); + + for (c = 0; c < 8; c++) + { + io_removehandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_removehandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_removehandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_removehandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + } + + io_removehandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); +} + +static void mach64_io_set(mach64_t *mach64) +{ + int c; + + mach64_io_remove(mach64); + + 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, 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, mach64); +} + uint8_t mach64_pci_read(int func, int addr, void *p) { mach64_t *mach64 = (mach64_t *)p; @@ -2068,7 +2127,8 @@ uint8_t mach64_pci_read(int func, int addr, void *p) case 0x02: return 'X'; /*88800GX*/ case 0x03: return 'G'; - case 0x04: return 0x03; /*Respond to IO and memory accesses*/ + case PCI_REG_COMMAND: + return mach64->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ @@ -2083,10 +2143,10 @@ uint8_t mach64_pci_read(int func, int addr, void *p) case 0x12: return mach64->linear_base >> 16; case 0x13: return mach64->linear_base >> 24; - case 0x30: return 0x01; /*BIOS ROM address*/ + case 0x30: return mach64->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ case 0x31: return 0x00; - case 0x32: return 0x0C; - case 0x33: return 0x00; + case 0x32: return mach64->pci_regs[0x32]; + case 0x33: return mach64->pci_regs[0x33]; } return 0; } @@ -2099,6 +2159,15 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) switch (addr) { + case PCI_REG_COMMAND: + mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27; + if (val & PCI_COMMAND_IO) + mach64_io_set(mach64); + else + mach64_io_remove(mach64); + mach64_updatemapping(mach64); + break; + case 0x12: mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16); mach64_updatemapping(mach64); @@ -2107,6 +2176,21 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24); mach64_updatemapping(mach64); break; + + case 0x30: case 0x32: case 0x33: + mach64->pci_regs[addr] = val; + if (mach64->pci_regs[0x30] & 0x01) + { + uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24); + pclog("Mach64 bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000); + } + else + { + pclog("Mach64 bios_rom disabled\n"); + mem_mapping_disable(&mach64->bios_rom.mapping); + } + return; } } @@ -2121,24 +2205,23 @@ void *mach64gx_init() mach64_in, mach64_out, mach64_hwcursor_draw); - mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &mach64->svga); - mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, mach64); - mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, mach64); + rom_init(&mach64->bios_rom, "roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (PCI) + mem_mapping_disable(&mach64->bios_rom.mapping); + + mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &mach64->svga); + mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); + mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); mem_mapping_disable(&mach64->mmio_mapping); - 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, 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, mach64); + mach64_io_set(mach64); pci_add(mach64_pci_read, mach64_pci_write, mach64); + + mach64->pci_regs[PCI_REG_COMMAND] = 3; + mach64->pci_regs[0x30] = 0x00; + mach64->pci_regs[0x32] = 0x0c; + mach64->pci_regs[0x33] = 0x00; ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); @@ -2149,6 +2232,11 @@ void *mach64gx_init() return mach64; } +int mach64gx_available() +{ + return rom_present("roms/mach64gx/bios.bin"); +} + void mach64_close(void *p) { mach64_t *mach64 = (mach64_t *)p; @@ -2225,7 +2313,7 @@ device_t mach64gx_device = 0, mach64gx_init, mach64_close, - NULL, + mach64gx_available, mach64_speed_changed, mach64_force_redraw, mach64_add_status_info diff --git a/src/vid_cga.c b/src/vid_cga.c index 5982eb7..6c3293a 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -499,7 +499,7 @@ void *cga_standalone_init() q_filt[c] = 512.0 * sin((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0); } timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); - mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, cga); + mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); return cga; } diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index a60dab0..dc4264c 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -4,6 +4,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "video.h" #include "vid_cl5429.h" #include "vid_svga.h" @@ -16,6 +17,8 @@ typedef struct gd5429_t svga_t svga; + rom_t bios_rom; + uint32_t bank[2]; uint32_t mask; @@ -816,6 +819,8 @@ void *gd5429_init() svga_t *svga = &gd5429->svga; memset(gd5429, 0, sizeof(gd5429_t)); + rom_init(&gd5429->bios_rom, "roms/5429.vbi", 0xc0000, 0x8000, 0x7fff, 0, 0); + svga_init(&gd5429->svga, gd5429, 1 << 21, /*2mb*/ gd5429_recalctimings, gd5429_in, gd5429_out, @@ -824,7 +829,7 @@ void *gd5429_init() mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL); mem_mapping_set_p(&gd5429->svga.mapping, gd5429); - mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, gd5429); + mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, NULL, 0, gd5429); io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); @@ -836,6 +841,11 @@ void *gd5429_init() return gd5429; } +static int gd5429_available() +{ + return rom_present("roms/5429.vbi"); +} + void gd5429_close(void *p) { gd5429_t *gd5429 = (gd5429_t *)p; @@ -872,7 +882,7 @@ device_t gd5429_device = DEVICE_NOT_WORKING, gd5429_init, gd5429_close, - NULL, + gd5429_available, gd5429_speed_changed, gd5429_force_redraw, gd5429_add_status_info diff --git a/src/vid_ega.c b/src/vid_ega.c index 734994d..388f618 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -4,6 +4,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "timer.h" #include "video.h" #include "vid_ega.h" @@ -810,15 +811,35 @@ void *ega_standalone_init() int c, d, e; ega_t *ega = malloc(sizeof(ega_t)); memset(ega, 0, sizeof(ega_t)); + + rom_init(&ega->bios_rom, "roms/ibm_6277356_ega_card_u44_27128.bin", 0xc0000, 0x8000, 0x7fff, 0, 0); + + if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) + { + int c; + pclog("Read EGA ROM in reverse\n"); + + for (c = 0; c < 0x2000; c++) + { + uint8_t temp = ega->bios_rom.rom[c]; + ega->bios_rom.rom[c] = ega->bios_rom.rom[0x3fff - c]; + ega->bios_rom.rom[0x3fff - c] = temp; + } + } ega_init(ega); - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, ega); + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); 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; } +static int ega_standalone_available() +{ + return rom_present("roms/ibm_6277356_ega_card_u44_27128.bin"); +} + void ega_close(void *p) { ega_t *ega = (ega_t *)p; @@ -840,7 +861,7 @@ device_t ega_device = 0, ega_standalone_init, ega_close, - NULL, + ega_standalone_available, ega_speed_changed, NULL, NULL diff --git a/src/vid_ega.h b/src/vid_ega.h index f8039c5..47de8f4 100644 --- a/src/vid_ega.h +++ b/src/vid_ega.h @@ -2,6 +2,8 @@ typedef struct ega_t { mem_mapping_t mapping; + rom_t bios_rom; + uint8_t crtcreg; uint8_t crtc[32]; uint8_t gdcreg[16]; diff --git a/src/vid_et4000.c b/src/vid_et4000.c index 50395e7..e6dd38d 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -4,6 +4,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "video.h" #include "vid_svga.h" #include "vid_unk_ramdac.h" @@ -15,6 +16,8 @@ typedef struct et4000_t svga_t svga; unk_ramdac_t ramdac; + rom_t bios_rom; + uint8_t banking; } et4000_t; @@ -129,7 +132,9 @@ void *et4000_init() { et4000_t *et4000 = malloc(sizeof(et4000_t)); memset(et4000, 0, sizeof(et4000_t)); - + + rom_init(&et4000->bios_rom, "roms/et4000.bin", 0xc0000, 0x8000, 0x7fff, 0, 0); + io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ @@ -140,6 +145,11 @@ void *et4000_init() return et4000; } +static int et4000_available() +{ + return rom_present("roms/et4000.bin"); +} + void et4000_close(void *p) { et4000_t *et4000 = (et4000_t *)p; diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index 129f808..2bffd96 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -9,6 +9,7 @@ #include "io.h" #include "mem.h" #include "pci.h" +#include "rom.h" #include "video.h" #include "vid_svga.h" #include "vid_icd2061.h" @@ -19,6 +20,8 @@ typedef struct et4000w32p_t mem_mapping_t linear_mapping; mem_mapping_t mmu_mapping; + rom_t bios_rom; + svga_t svga; stg_ramdac_t ramdac; icd2061_t icd2061; @@ -28,7 +31,9 @@ typedef struct et4000w32p_t uint32_t linearbase, linearbase_old; uint8_t banking, banking2; - + + uint8_t pci_regs[256]; + /*Accelerator*/ struct { @@ -260,6 +265,15 @@ void et4000w32p_recalcmapping(et4000w32p_t *et4000) { svga_t *svga = &et4000->svga; + if (!(et4000->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) + { + pclog("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&et4000->linear_mapping); + mem_mapping_disable(&et4000->mmu_mapping); + return; + } + pclog("recalcmapping %p\n", svga); if (svga->crtc[0x36] & 0x10) /*Linear frame buffer*/ { @@ -887,6 +901,36 @@ void et4000w32p_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += 16; } +static void et4000w32p_io_remove(et4000w32p_t *et4000) +{ + io_removehandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + + io_removehandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); +} + +static void et4000w32p_io_set(et4000w32p_t *et4000) +{ + et4000w32p_io_remove(et4000); + + 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); +} + uint8_t et4000w32p_pci_read(int func, int addr, void *p) { et4000w32p_t *et4000 = (et4000w32p_t *)p; @@ -902,7 +946,8 @@ uint8_t et4000w32p_pci_read(int func, int addr, void *p) case 0x02: return 0x06; /*ET4000W32p Rev D*/ case 0x03: return 0x32; - case 0x04: return 0x03; /*Respond to IO and memory accesses*/ + case PCI_REG_COMMAND: + return et4000->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ @@ -917,10 +962,10 @@ uint8_t et4000w32p_pci_read(int func, int addr, void *p) case 0x12: return svga->crtc[0x5a] & 0x80; case 0x13: return svga->crtc[0x59]; - case 0x30: return 0x01; /*BIOS ROM address*/ + case 0x30: return et4000->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ case 0x31: return 0x00; - case 0x32: return 0x0C; - case 0x33: return 0x00; + case 0x32: return et4000->pci_regs[0x32]; + case 0x33: return et4000->pci_regs[0x33]; } return 0; } @@ -931,10 +976,34 @@ void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p) switch (addr) { + case PCI_REG_COMMAND: + et4000->pci_regs[PCI_REG_COMMAND] = val & 0x27; + if (val & PCI_COMMAND_IO) + et4000w32p_io_set(et4000); + else + et4000w32p_io_remove(et4000); + et4000w32p_recalcmapping(et4000); + break; + case 0x13: et4000->linearbase = val << 24; et4000w32p_recalcmapping(et4000); break; + + case 0x30: case 0x32: case 0x33: + et4000->pci_regs[addr] = val; + if (et4000->pci_regs[0x30] & 0x01) + { + uint32_t addr = (et4000->pci_regs[0x32] << 16) | (et4000->pci_regs[0x33] << 24); + pclog("ET4000 bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&et4000->bios_rom.mapping, addr, 0x8000); + } + else + { + pclog("ET4000 bios_rom disabled\n"); + mem_mapping_disable(&et4000->bios_rom.mapping); + } + return; } } @@ -948,25 +1017,31 @@ void *et4000w32p_init() et4000w32p_in, et4000w32p_out, et4000w32p_hwcursor_draw); - mem_mapping_add(&et4000->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &et4000->svga); - mem_mapping_add(&et4000->mmu_mapping, 0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, et4000); + rom_init(&et4000->bios_rom, "roms/et4000w32.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (PCI) + mem_mapping_disable(&et4000->bios_rom.mapping); - io_sethandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + mem_mapping_add(&et4000->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &et4000->svga); + mem_mapping_add(&et4000->mmu_mapping, 0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL, 0, 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); + et4000w32p_io_set(et4000); pci_add(et4000w32p_pci_read, et4000w32p_pci_write, et4000); + + et4000->pci_regs[0x04] = 7; + + et4000->pci_regs[0x30] = 0x00; + et4000->pci_regs[0x32] = 0x0c; + et4000->pci_regs[0x33] = 0x00; return et4000; } +int et4000w32p_available() +{ + return rom_present("roms/et4000w32.bin"); +} + void et4000w32p_close(void *p) { et4000w32p_t *et4000 = (et4000w32p_t *)p; @@ -1003,7 +1078,7 @@ device_t et4000w32p_device = 0, et4000w32p_init, et4000w32p_close, - NULL, + et4000w32p_available, et4000w32p_speed_changed, et4000w32p_force_redraw, et4000w32p_add_status_info diff --git a/src/vid_hercules.c b/src/vid_hercules.c index 68343e3..b9832f0 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -313,7 +313,7 @@ void *hercules_init() hercules->vram = malloc(0x10000); timer_add(hercules_poll, &hercules->vidtime, TIMER_ALWAYS_ENABLED, hercules); - mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, hercules); + mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL, 0, hercules); io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules); for (c = 0; c < 256; c++) diff --git a/src/vid_mda.c b/src/vid_mda.c index 43db3a5..3897624 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -270,7 +270,7 @@ void *mda_init() mda->vram = malloc(0x1000); timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda); - mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, mda); + mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, 0, mda); io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); for (c = 0; c < 256; c++) diff --git a/src/vid_olivetti_m24.c b/src/vid_olivetti_m24.c index 73bc128..aadfe9b 100644 --- a/src/vid_olivetti_m24.c +++ b/src/vid_olivetti_m24.c @@ -459,7 +459,7 @@ void *m24_init() m24->vram = malloc(0x8000); timer_add(m24_poll, &m24->vidtime, TIMER_ALWAYS_ENABLED, m24); - mem_mapping_add(&m24->mapping, 0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, m24); + mem_mapping_add(&m24->mapping, 0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, NULL, 0, m24); io_sethandler(0x03d0, 0x0010, m24_in, NULL, NULL, m24_out, NULL, NULL, m24); return m24; } diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 0f00854..939d2fa 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -4,6 +4,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "video.h" #include "vid_oti067.h" #include "vid_svga.h" @@ -12,6 +13,8 @@ typedef struct oti067_t { svga_t svga; + rom_t bios_rom; + int index; uint8_t regs[32]; } oti067_t; @@ -110,11 +113,13 @@ void oti067_recalctimings(svga_t *svga) svga->interlace = oti067->regs[0x14] & 0x80; } -void *oti067_init() +void *oti067_common_init(char *bios_fn) { oti067_t *oti067 = malloc(sizeof(oti067_t)); memset(oti067, 0, sizeof(oti067_t)); + rom_init(&oti067->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, 0); + svga_init(&oti067->svga, oti067, 1 << 19, /*512kb*/ oti067_recalctimings, oti067_in, oti067_out, @@ -126,6 +131,26 @@ void *oti067_init() return oti067; } +void *oti067_init() +{ + return oti067_common_init("roms/oti067/bios.bin"); +} + +void *oti067_acer386_init() +{ + oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin"); + + if (oti067) + oti067->bios_rom.rom[0x5d] = 0x74; + + return oti067; +} + +static int oti067_available() +{ + return rom_present("roms/oti067/bios.bin"); +} + void oti067_close(void *p) { oti067_t *oti067 = (oti067_t *)p; @@ -162,7 +187,18 @@ device_t oti067_device = 0, oti067_init, oti067_close, - NULL, + oti067_available, + oti067_speed_changed, + oti067_force_redraw, + oti067_add_status_info +}; +device_t oti067_acer386_device = +{ + "Oak OTI-067 (Acermate 386SX/25N)", + 0, + oti067_acer386_init, + oti067_close, + oti067_available, oti067_speed_changed, oti067_force_redraw, oti067_add_status_info diff --git a/src/vid_oti067.h b/src/vid_oti067.h index 3e28595..81d4358 100644 --- a/src/vid_oti067.h +++ b/src/vid_oti067.h @@ -1 +1,2 @@ extern device_t oti067_device; +extern device_t oti067_acer386_device; diff --git a/src/vid_paradise.c b/src/vid_paradise.c index 7fbd2db..5d75a99 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -7,6 +7,7 @@ #include "ibm.h" #include "device.h" #include "mem.h" +#include "rom.h" #include "video.h" #include "vid_paradise.h" #include "vid_svga.h" @@ -17,6 +18,8 @@ typedef struct paradise_t { svga_t svga; + rom_t bios_rom; + enum { PVGA1A = 0, @@ -312,6 +315,38 @@ void *paradise_wd90c11_init() return paradise; } +static void *paradise_pvga1a_pc2086_init() +{ + paradise_t *paradise = paradise_pvga1a_init(); + + if (paradise) + rom_init(¶dise->bios_rom, "roms/pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, 0); + + return paradise; +} +static void *paradise_pvga1a_pc3086_init() +{ + paradise_t *paradise = paradise_pvga1a_init(); + + if (paradise) + rom_init(¶dise->bios_rom, "roms/pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, 0); + + return paradise; +} + +static void *paradise_wd90c11_megapc_init() +{ + paradise_t *paradise = paradise_wd90c11_init(); + + if (paradise) + rom_init_interleaved(¶dise->bios_rom, + "roms/megapc/41651-bios lo.u18", + "roms/megapc/211253-bios hi.u19", + 0xc0000, 0x8000, 0x7fff, 0, 0); + + return paradise; +} + void paradise_close(void *p) { paradise_t *paradise = (paradise_t *)p; @@ -342,22 +377,33 @@ int paradise_add_status_info(char *s, int max_len, void *p) return svga_add_status_info(s, max_len, ¶dise->svga); } -device_t paradise_pvga1a_device = +device_t paradise_pvga1a_pc2086_device = { - "Paradise PVGA1A", + "Paradise PVGA1A (Amstrad PC2086)", 0, - paradise_pvga1a_init, + paradise_pvga1a_pc2086_init, paradise_close, NULL, paradise_speed_changed, paradise_force_redraw, paradise_add_status_info }; -device_t paradise_wd90c11_device = +device_t paradise_pvga1a_pc3086_device = { - "Paradise WD90C11", + "Paradise PVGA1A (Amstrad PC3086)", 0, - paradise_wd90c11_init, + paradise_pvga1a_pc3086_init, + paradise_close, + NULL, + paradise_speed_changed, + paradise_force_redraw, + paradise_add_status_info +}; +device_t paradise_wd90c11_megapc_device = +{ + "Paradise WD90C11 (Amstrad MegaPC)", + 0, + paradise_wd90c11_megapc_init, paradise_close, NULL, paradise_speed_changed, diff --git a/src/vid_paradise.h b/src/vid_paradise.h index b791d46..e25d5b3 100644 --- a/src/vid_paradise.h +++ b/src/vid_paradise.h @@ -1,2 +1,3 @@ -extern device_t paradise_pvga1a_device; -extern device_t paradise_wd90c11_device; +extern device_t paradise_pvga1a_pc2086_device; +extern device_t paradise_pvga1a_pc3086_device; +extern device_t paradise_wd90c11_megapc_device; diff --git a/src/vid_pc1512.c b/src/vid_pc1512.c index 7026cf2..9fd57e4 100644 --- a/src/vid_pc1512.c +++ b/src/vid_pc1512.c @@ -460,7 +460,7 @@ static void *pc1512_init() pc1512->cgamode = 0x12; timer_add(pc1512_poll, &pc1512->vidtime, TIMER_ALWAYS_ENABLED, pc1512); - mem_mapping_add(&pc1512->mapping, 0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, pc1512); + mem_mapping_add(&pc1512->mapping, 0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, NULL, 0, pc1512); io_sethandler(0x03d0, 0x0010, pc1512_in, NULL, NULL, pc1512_out, NULL, NULL, pc1512); return pc1512; } diff --git a/src/vid_pc1640.c b/src/vid_pc1640.c index 6abba50..3cad4b6 100644 --- a/src/vid_pc1640.c +++ b/src/vid_pc1640.c @@ -5,6 +5,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "timer.h" #include "video.h" #include "vid_cga.h" @@ -19,6 +20,8 @@ typedef struct pc1640_t cga_t cga; ega_t ega; + rom_t bios_rom; + int cga_enabled; int dispontime, dispofftime, vidtime; } pc1640_t; @@ -114,14 +117,16 @@ void *pc1640_init() ega_t *ega = &pc1640->ega; memset(pc1640, 0, sizeof(pc1640_t)); + rom_init(&pc1640->bios_rom, "roms/pc1640/40100", 0xc0000, 0x8000, 0x7fff, 0, 0); + 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_mapping_add(&pc1640->cga_mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, cga); - mem_mapping_add(&pc1640->ega_mapping, 0, 0, ega_read, NULL, NULL, ega_write, NULL, NULL, ega); + mem_mapping_add(&pc1640->cga_mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); + mem_mapping_add(&pc1640->ega_mapping, 0, 0, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); io_sethandler(0x03a0, 0x0040, pc1640_in, NULL, NULL, pc1640_out, NULL, NULL, pc1640); return pc1640; } diff --git a/src/vid_pc200.c b/src/vid_pc200.c index 57dce0b..888a766 100644 --- a/src/vid_pc200.c +++ b/src/vid_pc200.c @@ -111,7 +111,7 @@ void *pc200_init() cga_init(&pc200->cga); timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); - mem_mapping_add(&pc200->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, cga); + mem_mapping_add(&pc200->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); io_sethandler(0x03d0, 0x0010, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200); return cga; } diff --git a/src/vid_pcjr.c b/src/vid_pcjr.c index 8e39d02..1c5959d 100644 --- a/src/vid_pcjr.c +++ b/src/vid_pcjr.c @@ -615,7 +615,7 @@ static void *pcjr_video_init() q_filt[c] = 512.0 * sin((3.14 * (pcjr_tint + c * 4) / 16.0) - 33.0 / 180.0); } timer_add(pcjr_poll, &pcjr->vidtime, TIMER_ALWAYS_ENABLED, pcjr); - mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, pcjr_read, NULL, NULL, pcjr_write, NULL, NULL, pcjr); + mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, pcjr_read, NULL, NULL, pcjr_write, NULL, NULL, NULL, 0, pcjr); io_sethandler(0x03d0, 0x0010, pcjr_in, NULL, NULL, pcjr_out, NULL, NULL, pcjr); return pcjr; } diff --git a/src/vid_s3.c b/src/vid_s3.c index d13da8a..eeff4c6 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -5,6 +5,7 @@ #include "io.h" #include "mem.h" #include "pci.h" +#include "rom.h" #include "video.h" #include "vid_s3.h" #include "vid_svga.h" @@ -16,6 +17,8 @@ typedef struct s3_t mem_mapping_t linear_mapping; mem_mapping_t mmio_mapping; + rom_t bios_rom; + svga_t svga; sdac_ramdac_t ramdac; @@ -25,8 +28,12 @@ typedef struct s3_t int bpp; uint8_t id, id_ext; + + int packed_mmio; uint32_t linear_base, linear_size; + + uint8_t pci_regs[256]; float (*getclock)(int clock, void *p); void *getclock_p; @@ -238,7 +245,7 @@ uint8_t s3_in(uint16_t addr, void *p) case 0x3d4: return svga->crtcreg; case 0x3d5: -// pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc); +// pclog("Read CRTC R%02X %04X:%04X\n", svga->crtcreg, CS, pc); switch (svga->crtcreg) { case 0x2d: return 0x88; /*Extended chip ID*/ @@ -322,6 +329,14 @@ void s3_updatemapping(s3_t *s3) // video_write_a000_w = video_write_a000_l = NULL; + if (!(s3->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) + { +// pclog("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&s3->linear_mapping); + mem_mapping_disable(&s3->mmio_mapping); + return; + } // pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ @@ -371,8 +386,11 @@ void s3_updatemapping(s3_t *s3) if (s3->linear_base == 0xa0000) { mem_mapping_disable(&s3->linear_mapping); - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; + if (!(svga->crtc[0x53] & 0x10)) + { + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + } // mem_mapping_set_addr(&s3->linear_mapping, 0xa0000, 0x10000); } else @@ -383,7 +401,10 @@ void s3_updatemapping(s3_t *s3) // pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x10); if (svga->crtc[0x53] & 0x10) /*Memory mapped IO*/ + { + mem_mapping_disable(&svga->mapping); mem_mapping_enable(&s3->mmio_mapping); + } else mem_mapping_disable(&s3->mmio_mapping); } @@ -412,6 +433,7 @@ 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: @@ -795,12 +817,109 @@ uint8_t s3_accel_in(uint16_t port, void *p) return 0; } +#define WRITE8(addr, var, val) switch ((addr) & 3) \ + { \ + case 0: var = (var & 0xffffff00) | (val); break; \ + case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ + case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ + case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ + } + 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 (s3->packed_mmio) + { + int addr_lo = addr & 1; + switch (addr & 0xfffe) + { + case 0x8100: addr = 0x82e8; break; /*ALT_CURXY*/ + case 0x8102: addr = 0x86e8; break; + + case 0x8104: addr = 0x82ea; break; /*ALT_CURXY2*/ + case 0x8106: addr = 0x86ea; break; + + case 0x8108: addr = 0x8ae8; break; /*ALT_STEP*/ + case 0x810a: addr = 0x8ee8; break; + + case 0x810c: addr = 0x8aea; break; /*ALT_STEP2*/ + case 0x810e: addr = 0x8eea; break; + + case 0x8110: addr = 0x92e8; break; /*ALT_ERR*/ + case 0x8112: addr = 0x92ee; break; + + case 0x8118: addr = 0x9ae8; break; /*ALT_CMD*/ + case 0x811a: addr = 0x9aea; break; + + case 0x811c: addr = 0x9ee8; break; /*SHORT_STROKE*/ + + case 0x8120: case 0x8122: /*BKGD_COLOR*/ + WRITE8(addr, s3->accel.bkgd_color, val); + return; + + case 0x8124: case 0x8126: /*FRGD_COLOR*/ + WRITE8(addr, s3->accel.frgd_color, val); + return; + + case 0x8128: case 0x812a: /*WRT_MASK*/ + WRITE8(addr, s3->accel.wrt_mask, val); + return; + + case 0x812c: case 0x812e: /*RD_MASK*/ + WRITE8(addr, s3->accel.rd_mask, val); + return; + + case 0x8130: case 0x8132: /*COLOR_CMP*/ + WRITE8(addr, s3->accel.color_cmp, val); + return; + + case 0x8134: addr = 0xb6e8; break; /*ALT_MIX*/ + case 0x8136: addr = 0xbae8; break; + + case 0x8138: /*SCISSORS_T*/ + WRITE8(addr & 1, s3->accel.multifunc[1], val); + return; + case 0x813a: /*SCISSORS_L*/ + WRITE8(addr & 1, s3->accel.multifunc[2], val); + return; + case 0x813c: /*SCISSORS_B*/ + WRITE8(addr & 1, s3->accel.multifunc[3], val); + return; + case 0x813e: /*SCISSORS_R*/ + WRITE8(addr & 1, s3->accel.multifunc[4], val); + return; + + case 0x8140: /*PIX_CNTL*/ + WRITE8(addr & 1, s3->accel.multifunc[0xa], val); + return; + case 0x8142: /*MULT_MISC2*/ + WRITE8(addr & 1, s3->accel.multifunc[0xd], val); + return; + case 0x8144: /*MULT_MISC*/ + WRITE8(addr & 1, s3->accel.multifunc[0xe], val); + return; + case 0x8146: /*READ_SEL*/ + WRITE8(addr & 1, s3->accel.multifunc[0xf], val); + return; + + case 0x8148: /*ALT_PCNT*/ + WRITE8(addr & 1, s3->accel.multifunc[0], val); + return; + case 0x814a: addr = 0x96e8; break; + case 0x814c: addr = 0x96ea; break; + + case 0x8168: addr = 0xeae8; break; + case 0x816a: addr = 0xeaea; break; + } + addr |= addr_lo; + } + + if (addr & 0x8000) - s3_accel_out(addr & 0xffff, val, p); + { + s3_accel_out(addr & 0xffff, val, p); + } else { if (s3->accel.cmd & 0x100) @@ -819,8 +938,8 @@ void s3_accel_write_w(uint32_t addr, uint16_t val, void *p) // pclog("Write S3 accel w %08X %04X\n", addr, val); if (addr & 0x8000) { - s3_accel_out( addr & 0xffff, val, p); - s3_accel_out((addr & 0xffff) + 1, val >> 8, p); + s3_accel_write(addr, val, p); + s3_accel_write(addr + 1, val >> 8, p); } else { @@ -844,10 +963,10 @@ void s3_accel_write_l(uint32_t addr, uint32_t val, void *p) // pclog("Write S3 accel l %08X %08X\n", addr, val); if (addr & 0x8000) { - 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); + s3_accel_write(addr, val, p); + s3_accel_write(addr + 1, val >> 8, p); + s3_accel_write(addr + 2, val >> 16, p); + s3_accel_write(addr + 3, val >> 24, p); } else { @@ -1531,78 +1650,37 @@ void s3_hwcursor_draw(svga_t *svga, int displine) } -uint8_t s3_pci_read(int func, int addr, void *p) +static void s3_io_remove(s3_t *s3) { - 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 0x03: return 0x88; - - case 0x04: return 0x03; /*Respond to IO and memory accesses*/ - - case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ - - case 0x08: return 0; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ - - case 0x0a: return 0x01; /*Supports VGA interface*/ - case 0x0b: return 0x03; - - case 0x10: return 0x00; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return svga->crtc[0x5a] & 0x80; - case 0x13: return svga->crtc[0x59]; - - case 0x30: return 0x01; /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return 0x0C; - case 0x33: return 0x00; - } - return 0; -} - -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: - svga->crtc[0x5a] = val & 0x80; - s3_updatemapping(s3); - break; - case 0x13: - svga->crtc[0x59] = val; - s3_updatemapping(s3); - break; - } -} - -static void *s3_init() -{ - s3_t *s3 = malloc(sizeof(s3_t)); - svga_t *svga = &s3->svga; - memset(s3, 0, sizeof(s3_t)); + io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - mem_mapping_add(&s3->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &s3->svga); - mem_mapping_add(&s3->mmio_mapping, 0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, s3); - mem_mapping_disable(&s3->mmio_mapping); + io_removehandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xa2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xa6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xaae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xaee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); +} - 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); +static void s3_io_set(s3_t *s3) +{ + s3_io_remove(s3); io_sethandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - - 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); @@ -1624,31 +1702,149 @@ static void *s3_init() 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); +} + + +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 0x03: return 0x88; + + case PCI_REG_COMMAND: + return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + + case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ + + case 0x08: return 0; /*Revision ID*/ + case 0x09: return 0; /*Programming interface*/ + + case 0x0a: return 0x01; /*Supports VGA interface*/ + case 0x0b: return 0x03; + + case 0x10: return 0x00; /*Linear frame buffer address*/ + case 0x11: return 0x00; + case 0x12: return svga->crtc[0x5a] & 0x80; + case 0x13: return svga->crtc[0x59]; + + case 0x30: return s3->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ + case 0x31: return 0x00; + case 0x32: return s3->pci_regs[0x32]; + case 0x33: return s3->pci_regs[0x33]; + } + return 0; +} + +void s3_pci_write(int func, int addr, uint8_t val, void *p) +{ + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; + pclog("s3_pci_write: addr=%02x val=%02x\n", addr, val); + switch (addr) + { + case PCI_REG_COMMAND: + s3->pci_regs[PCI_REG_COMMAND] = val & 0x27; + if (val & PCI_COMMAND_IO) + s3_io_set(s3); + else + s3_io_remove(s3); + s3_updatemapping(s3); + break; + + case 0x12: + svga->crtc[0x5a] = val & 0x80; + s3_updatemapping(s3); + break; + case 0x13: + svga->crtc[0x59] = val; + s3_updatemapping(s3); + break; + + case 0x30: case 0x32: case 0x33: + s3->pci_regs[addr] = val; + if (s3->pci_regs[0x30] & 0x01) + { + uint32_t addr = (s3->pci_regs[0x32] << 16) | (s3->pci_regs[0x33] << 24); + pclog("S3 bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&s3->bios_rom.mapping, addr, 0x8000); + } + else + { + pclog("S3 bios_rom disabled\n"); + mem_mapping_disable(&s3->bios_rom.mapping); + } + return; + } +} + +static void *s3_init(char *bios_fn) +{ + s3_t *s3 = malloc(sizeof(s3_t)); + svga_t *svga = &s3->svga; + memset(s3, 0, sizeof(s3_t)); + + rom_init(&s3->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (PCI) + mem_mapping_disable(&s3->bios_rom.mapping); + + mem_mapping_add(&s3->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &s3->svga); + mem_mapping_add(&s3->mmio_mapping, 0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, NULL, 0, s3); + mem_mapping_disable(&s3->mmio_mapping); + + 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); + + svga->crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5); + svga->crtc[0x37] = 1 | (7 << 5); + + s3_io_set(s3); pci_add(s3_pci_read, s3_pci_write, s3); + + s3->pci_regs[0x04] = 7; + + s3->pci_regs[0x30] = 0x00; + s3->pci_regs[0x32] = 0x0c; + s3->pci_regs[0x33] = 0x00; return s3; } void *s3_bahamas64_init() { - s3_t *s3 = s3_init(); + s3_t *s3 = s3_init("roms/bahamas64.bin"); s3->id = 0xc1; /*Vision864P*/ - s3->id_ext = 0xc1; /*Trio64*/ - + s3->id_ext = 0xc1; + s3->packed_mmio = 0; + s3->getclock = sdac_getclock; s3->getclock_p = &s3->ramdac; return s3; } +int s3_bahamas64_available() +{ + return rom_present("roms/bahamas64.bin"); +} + void *s3_9fx_init() { - s3_t *s3 = s3_init(); + s3_t *s3 = s3_init("roms/s3_764.bin"); - s3->id = 0xe1; - s3->id_ext = 0x11; /*Trio64*/ + s3->id = 0xe1; /*Trio64*/ + s3->id_ext = 0x11; + s3->packed_mmio = 1; s3->getclock = s3_trio64_getclock; s3->getclock_p = s3; @@ -1656,6 +1852,12 @@ void *s3_9fx_init() return s3; } +int s3_9fx_available() +{ + return rom_present("roms/s3_764.bin"); +} + + void s3_close(void *p) { s3_t *s3 = (s3_t *)p; @@ -1692,7 +1894,7 @@ device_t s3_bahamas64_device = 0, s3_bahamas64_init, s3_close, - NULL, + s3_bahamas64_available, s3_speed_changed, s3_force_redraw, s3_add_status_info @@ -1704,7 +1906,7 @@ device_t s3_9fx_device = 0, s3_9fx_init, s3_close, - NULL, + s3_9fx_available, s3_speed_changed, s3_force_redraw, s3_add_status_info diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 337bd7d..407ee09 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -7,6 +7,7 @@ #include "io.h" #include "mem.h" #include "pci.h" +#include "rom.h" #include "video.h" #include "vid_s3_virge.h" #include "vid_svga.h" @@ -15,8 +16,11 @@ typedef struct virge_t { - mem_mapping_t linear_mapping; - mem_mapping_t mmio_mapping; + mem_mapping_t linear_mapping; + mem_mapping_t mmio_mapping; + mem_mapping_t new_mmio_mapping; + + rom_t bios_rom; svga_t svga; @@ -30,18 +34,97 @@ typedef struct virge_t uint32_t linear_base, linear_size; uint8_t pci_regs[256]; + + struct + { + uint32_t src_base; + uint32_t dest_base; + int clip_l, clip_r, clip_t, clip_b; + int dest_str, src_str; + uint32_t mono_pat_0; + uint32_t mono_pat_1; + uint32_t pat_bg_clr; + uint32_t pat_fg_clr; + uint32_t src_bg_clr; + uint32_t src_fg_clr; + uint32_t cmd_set; + int r_width, r_height; + int rsrc_x, rsrc_y; + int rdest_x, rdest_y; + + int lxend0, lxend1; + int32_t ldx; + uint32_t lxstart, lystart; + int lycnt; + int line_dir; + + int src_x, src_y; + int dest_x, dest_y; + int w, h; + uint8_t rop; + + int data_left_count; + uint32_t data_left; + + uint32_t pattern_8[8*8]; + uint32_t pattern_16[8*8]; + uint32_t pattern_32[8*8]; + } s3d; } virge_t; -void s3_virge_updatemapping(virge_t *virge); +static 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); +static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat); -void s3_virge_out(uint16_t addr, uint8_t val, void *p) +static uint8_t s3_virge_mmio_read(uint32_t addr, void *p); +static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p); +static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p); +static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p); +static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p); +static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p); + +static uint8_t s3_virge_new_mmio_read(uint32_t addr, void *p); +static uint16_t s3_virge_new_mmio_read_w(uint32_t addr, void *p); +static uint32_t s3_virge_new_mmio_read_l(uint32_t addr, void *p); +static void s3_virge_new_mmio_write(uint32_t addr, uint8_t val, void *p); +static void s3_virge_new_mmio_write_w(uint32_t addr, uint16_t val, void *p); +static void s3_virge_new_mmio_write_l(uint32_t addr, uint32_t val, void *p); + +enum +{ + CMD_SET_AE = 1, + CMD_SET_HC = (1 << 1), + + CMD_SET_FORMAT_MASK = (7 << 2), + CMD_SET_FORMAT_8 = (0 << 2), + CMD_SET_FORMAT_16 = (1 << 2), + CMD_SET_FORMAT_24 = (2 << 2), + + CMD_SET_MS = (1 << 6), + CMD_SET_IDS = (1 << 7), + CMD_SET_MP = (1 << 8), + CMD_SET_TP = (1 << 9), + + CMD_SET_ITA_MASK = (3 << 10), + CMD_SET_ITA_BYTE = (0 << 10), + CMD_SET_ITA_WORD = (1 << 10), + CMD_SET_ITA_DWORD = (2 << 10), + + CMD_SET_XP = (1 << 25), + CMD_SET_YP = (1 << 26), + + CMD_SET_COMMAND_MASK = (15 << 27) +}; + +enum +{ + CMD_SET_COMMAND_BITBLT = (0 << 27), + CMD_SET_COMMAND_RECTFILL = (2 << 27), + CMD_SET_COMMAND_LINE = (3 << 27), + CMD_SET_COMMAND_NOP = (15 << 27) +}; + +static void s3_virge_out(uint16_t addr, uint8_t val, void *p) { virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; @@ -49,7 +132,7 @@ void s3_virge_out(uint16_t addr, uint8_t val, void *p) 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) @@ -76,7 +159,7 @@ void s3_virge_out(uint16_t addr, uint8_t val, void *p) svga->crtcreg = val & 0x7f; return; case 0x3d5: -// if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val); + //pclog("Write CRTC R%02X %02X\n", svga->crtcreg, val); if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) @@ -132,7 +215,8 @@ void s3_virge_out(uint16_t addr, uint8_t val, void *p) case 0x45: svga->hwcursor.ena = val & 1; break; - case 0x48: + case 0x46: case 0x47: case 0x48: case 0x49: + case 0x4c: case 0x4d: case 0x4e: case 0x4f: 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; @@ -151,8 +235,8 @@ void s3_virge_out(uint16_t addr, uint8_t val, void *p) { case 3: svga->bpp = 15; break; case 5: svga->bpp = 16; break; - case 7: svga->bpp = 24; break; - case 13: svga->bpp = 32; break; +// case 7: svga->bpp = 24; break; + case 13: svga->bpp = 24; break; default: svga->bpp = 8; break; } break; @@ -172,7 +256,7 @@ void s3_virge_out(uint16_t addr, uint8_t val, void *p) svga_out(addr, val, svga); } -uint8_t s3_virge_in(uint16_t addr, void *p) +static uint8_t s3_virge_in(uint16_t addr, void *p) { virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; @@ -195,7 +279,7 @@ uint8_t s3_virge_in(uint16_t addr, void *p) case 0x3D4: return svga->crtcreg; case 0x3D5: -// pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc); +// pclog("Read CRTC R%02X %04X:%04X (%02x)\n", svga->crtcreg, CS, pc, svga->crtc[svga->crtcreg]); switch (svga->crtcreg) { case 0x2d: return virge->virge_id_high; /*Extended chip ID*/ @@ -204,6 +288,7 @@ uint8_t s3_virge_in(uint16_t addr, void *p) 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 0x36: return (svga->crtc[0x36] & 0xfc) | 2; /*PCI bus*/ 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; @@ -213,7 +298,7 @@ uint8_t s3_virge_in(uint16_t addr, void *p) return svga_in(addr, svga); } -void s3_virge_recalctimings(svga_t *svga) +static void s3_virge_recalctimings(svga_t *svga) { virge_t *virge = (virge_t *)svga->p; // pclog("recalctimings\n"); @@ -252,20 +337,41 @@ void s3_virge_recalctimings(svga_t *svga) 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) +// pclog("svga->rowoffset = %i bpp=%i\n", svga->rowoffset, svga->bpp); + if (svga->bpp == 15 || svga->bpp == 16) + { + svga->htotal >>= 1; + svga->hdisp >>= 1; + } + if (svga->bpp == 24) + { + svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ + } + +/* if (svga->bpp == 32) { 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; } -void s3_virge_updatemapping(virge_t *virge) +static void s3_virge_updatemapping(virge_t *virge) { svga_t *svga = &virge->svga; - + + if (!(virge->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) + { +// pclog("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&virge->linear_mapping); + mem_mapping_disable(&virge->mmio_mapping); + mem_mapping_disable(&virge->new_mmio_mapping); + return; + } + pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ { @@ -287,10 +393,11 @@ void s3_virge_updatemapping(virge_t *virge) break; } + virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); + pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ { - virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); switch (svga->crtc[0x58] & 3) { case 0: /*64k*/ @@ -315,13 +422,13 @@ void s3_virge_updatemapping(virge_t *virge) mem_mapping_disable(&virge->linear_mapping); } else - mem_mapping_set_addr(&svga->mapping, virge->linear_base, virge->linear_size); + mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); } else mem_mapping_disable(&virge->linear_mapping); pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18); - if ((svga->crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/ + if (svga->crtc[0x53] & 0x10) /*Old MMIO*/ { if (svga->crtc[0x53] & 0x20) mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000); @@ -330,47 +437,707 @@ void s3_virge_updatemapping(virge_t *virge) } else mem_mapping_disable(&virge->mmio_mapping); + + if (svga->crtc[0x53] & 0x08) /*New MMIO*/ + mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000); + else + mem_mapping_disable(&virge->new_mmio_mapping); + } -uint8_t s3_virge_mmio_read(uint32_t addr, void *p) +static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) { - pclog("MMIO readb %08X\n", addr); +// pclog("MMIO readb %08X\n", addr); return 0xff; } -uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p) +static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p) { - pclog("MMIO readw %08X\n", addr); +// pclog("MMIO readw %08X\n", addr); return 0xffff; } -uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) +static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) { - pclog("MMIO readl %08X\n", addr); +// pclog("MMIO readl %08X\n", addr); return 0xffffffff; } -void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) +static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) { - pclog("MMIO writeb %08X %02X\n", addr, val); +// pclog("MMIO writeb %08X %02X\n", addr, val); } -void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) +static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) { - pclog("MMIO writew %08X %04X\n", addr, val); +// pclog("MMIO writew %08X %04X\n", addr, val); } -void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) +static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) { - pclog("MMIO writel %08X %08X\n", addr, val); +// pclog("MMIO writel %08X %08X\n", addr, val); +} + +static uint8_t s3_virge_new_mmio_read(uint32_t addr, void *p) +{ +// pclog("New MMIO readb %08X\n", addr); + switch (addr & 0xffff) + { + case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: + case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: + case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: + case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf: + case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3: + case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7: + case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb: + case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf: + case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3: + case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7: + case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: + case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: + return s3_virge_in(addr & 0x3ff, p); + } + return 0xff; +} +static uint16_t s3_virge_new_mmio_read_w(uint32_t addr, void *p) +{ +// pclog("New MMIO readw %08X\n", addr); + switch (addr & 0xfffe) + { + default: + return s3_virge_new_mmio_read(addr, p) | (s3_virge_new_mmio_read(addr + 1, p) << 8); + } + return 0xffff; +} +static uint32_t s3_virge_new_mmio_read_l(uint32_t addr, void *p) +{ + virge_t *virge = (virge_t *)p; + uint32_t ret = 0xffffffff; +// pclog("New MMIO readl %08X\n", addr); + switch (addr & 0xfffc) + { + case 0x8504: + ret = (0x1f << 8) | (1 << 13); + break; + case 0xa4d4: + ret = virge->s3d.src_base; + break; + case 0xa4d8: + ret = virge->s3d.dest_base; + break; + case 0xa4dc: + ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r; + break; + case 0xa4e0: + ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b; + break; + case 0xa4e4: + ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str; + break; + case 0xa4e8: + ret = virge->s3d.mono_pat_0; + break; + case 0xa4ec: + ret = virge->s3d.mono_pat_1; + break; + case 0xa4f0: + ret = virge->s3d.pat_bg_clr; + break; + case 0xa4f4: + ret = virge->s3d.pat_fg_clr; + break; + case 0xa4f8: + ret = virge->s3d.src_bg_clr; + break; + case 0xa4fc: + ret = virge->s3d.src_fg_clr; + break; + case 0xa500: + ret = virge->s3d.cmd_set; + break; + case 0xa504: + ret = (virge->s3d.r_width << 16) | virge->s3d.r_height; + break; + case 0xa508: + ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y; + break; + case 0xa50c: + ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; + break; + + default: + return s3_virge_new_mmio_read_w(addr, p) | (s3_virge_new_mmio_read_w(addr + 2, p) << 16); + } + return ret; +} +static void s3_virge_new_mmio_write(uint32_t addr, uint8_t val, void *p) +{ + virge_t *virge = (virge_t *)p; + svga_t *svga = &virge->svga; + +// pclog("New MMIO writeb %08X %02X\n", addr, val); + + if ((addr & 0xfffc) < 0x8000) + s3_virge_bitblt(virge, 8, val); + else switch (addr & 0xffff) + { + case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: + case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: + case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: + case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf: + case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3: + case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7: + case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb: + case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf: + case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3: + case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7: + case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: + case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: + s3_virge_out(addr & 0x3ff, val, p); + break; + } + + +} +static void s3_virge_new_mmio_write_w(uint32_t addr, uint16_t val, void *p) +{ + virge_t *virge = (virge_t *)p; +// pclog("New MMIO writew %08X %04X\n", addr, val); + if ((addr & 0xfffc) < 0x8000) + { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); + else + s3_virge_bitblt(virge, 16, val); + } + else switch (addr & 0xfffe) + { + case 0x83d4: + s3_virge_new_mmio_write(addr, val, p); + s3_virge_new_mmio_write(addr + 1, val >> 8, p); + break; + } +} +static void s3_virge_new_mmio_write_l(uint32_t addr, uint32_t val, void *p) +{ + virge_t *virge = (virge_t *)p; + +// if ((addr & 0xfffc) >= 0x8000) +// pclog("New MMIO writel %08X %08X\n", addr, val); + + if ((addr & 0xfffc) < 0x8000) + { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); + else + s3_virge_bitblt(virge, 32, val); + } + else switch (addr & 0xfffc) + { + case 0xa000: case 0xa004: case 0xa008: case 0xa00c: + case 0xa010: case 0xa014: case 0xa018: case 0xa01c: + case 0xa020: case 0xa024: case 0xa028: case 0xa02c: + case 0xa030: case 0xa034: case 0xa038: case 0xa03c: + case 0xa040: case 0xa044: case 0xa048: case 0xa04c: + case 0xa050: case 0xa054: case 0xa058: case 0xa05c: + case 0xa060: case 0xa064: case 0xa068: case 0xa06c: + case 0xa070: case 0xa074: case 0xa078: case 0xa07c: + case 0xa080: case 0xa084: case 0xa088: case 0xa08c: + case 0xa090: case 0xa094: case 0xa098: case 0xa09c: + case 0xa0a0: case 0xa0a4: case 0xa0a8: case 0xa0ac: + case 0xa0b0: case 0xa0b4: case 0xa0b8: case 0xa0bc: + case 0xa0c0: case 0xa0c4: case 0xa0c8: case 0xa0cc: + case 0xa0d0: case 0xa0d4: case 0xa0d8: case 0xa0dc: + case 0xa0e0: case 0xa0e4: case 0xa0e8: case 0xa0ec: + case 0xa0f0: case 0xa0f4: case 0xa0f8: case 0xa0fc: + case 0xa100: case 0xa104: case 0xa108: case 0xa10c: + case 0xa110: case 0xa114: case 0xa118: case 0xa11c: + case 0xa120: case 0xa124: case 0xa128: case 0xa12c: + case 0xa130: case 0xa134: case 0xa138: case 0xa13c: + case 0xa140: case 0xa144: case 0xa148: case 0xa14c: + case 0xa150: case 0xa154: case 0xa158: case 0xa15c: + case 0xa160: case 0xa164: case 0xa168: case 0xa16c: + case 0xa170: case 0xa174: case 0xa178: case 0xa17c: + case 0xa180: case 0xa184: case 0xa188: case 0xa18c: + case 0xa190: case 0xa194: case 0xa198: case 0xa19c: + case 0xa1a0: case 0xa1a4: case 0xa1a8: case 0xa1ac: + case 0xa1b0: case 0xa1b4: case 0xa1b8: case 0xa1bc: + case 0xa1c0: case 0xa1c4: case 0xa1c8: case 0xa1cc: + case 0xa1d0: case 0xa1d4: case 0xa1d8: case 0xa1dc: + case 0xa1e0: case 0xa1e4: case 0xa1e8: case 0xa1ec: + case 0xa1f0: case 0xa1f4: case 0xa1f8: case 0xa1fc: + { + int x = addr & 4; + int y = (addr >> 3) & 7; + virge->s3d.pattern_8[y*8 + x] = val & 0xff; + virge->s3d.pattern_8[y*8 + x + 1] = val >> 8; + virge->s3d.pattern_8[y*8 + x + 2] = val >> 16; + virge->s3d.pattern_8[y*8 + x + 3] = val >> 24; + + x = (addr >> 1) & 6; + y = (addr >> 4) & 7; + virge->s3d.pattern_16[y*8 + x] = val & 0xffff; + virge->s3d.pattern_16[y*8 + x + 1] = val >> 16; + + x = (addr >> 2) & 7; + y = (addr >> 5) & 7; + virge->s3d.pattern_32[y*8 + x] = val & 0xffffff; + } + break; + + + case 0xa4d4: case 0xa8d4: + virge->s3d.src_base = val & 0x3ffff8; + break; + case 0xa4d8: case 0xa8d8: + virge->s3d.dest_base = val & 0x3ffff8; + break; + case 0xa4dc: case 0xa8dc: + virge->s3d.clip_l = (val >> 16) & 0x7ff; + virge->s3d.clip_r = val & 0x7ff; + break; + case 0xa4e0: case 0xa8e0: + virge->s3d.clip_t = (val >> 16) & 0x7ff; + virge->s3d.clip_b = val & 0x7ff; + break; + case 0xa4e4: case 0xa8e4: + virge->s3d.dest_str = (val >> 16) & 0xff8; + virge->s3d.src_str = val & 0xff8; + break; + case 0xa4e8: + virge->s3d.mono_pat_0 = val; + break; + case 0xa4ec: + virge->s3d.mono_pat_1 = val; + break; + case 0xa4f0: + virge->s3d.pat_bg_clr = val; + break; + case 0xa4f4: case 0xa8f4: + virge->s3d.pat_fg_clr = val; + break; + case 0xa4f8: + virge->s3d.src_bg_clr = val; + break; + case 0xa4fc: + virge->s3d.src_fg_clr = val; + break; + case 0xa500: case 0xa900: + virge->s3d.cmd_set = val; + if (!(val & CMD_SET_AE)) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xa504: + virge->s3d.r_width = (val >> 16) & 0x7ff; + virge->s3d.r_height = val & 0x7ff; + break; + case 0xa508: + virge->s3d.rsrc_x = (val >> 16) & 0x7ff; + virge->s3d.rsrc_y = val & 0x7ff; + break; + case 0xa50c: + virge->s3d.rdest_x = (val >> 16) & 0x7ff; + virge->s3d.rdest_y = val & 0x7ff; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xa96c: + virge->s3d.lxend0 = (val >> 16) & 0x7ff; + virge->s3d.lxend1 = val & 0x7ff; + break; + case 0xa970: + virge->s3d.ldx = (int32_t)val; + break; + case 0xa974: + virge->s3d.lxstart = val; + break; + case 0xa978: + virge->s3d.lystart = val & 0x7ff; + break; + case 0xa97c: + virge->s3d.lycnt = val & 0x7ff; + virge->s3d.line_dir = val >> 31; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; + } +} + +#define READ(addr, val) \ + do \ + { \ + switch (bpp) \ + { \ + case 0: /*8 bpp*/ \ + val = vram[addr & 0x3fffff]; \ + break; \ + case 1: /*16 bpp*/ \ + val = *(uint16_t *)&vram[addr & 0x3fffff]; \ + break; \ + case 2: /*24 bpp*/ \ + val = (*(uint32_t *)&vram[addr & 0x3fffff]) & 0xffffff; \ + break; \ + } \ + } while (0) + +#define CLIP(x, y) \ + do \ + { \ + if ((virge->s3d.cmd_set & CMD_SET_HC) && \ + (x < virge->s3d.clip_l || \ + x > virge->s3d.clip_r || \ + y < virge->s3d.clip_t || \ + y > virge->s3d.clip_b)) \ + update = 0; \ + } while (0) + +#define MIX() \ + do \ + { \ + int c; \ + for (c = 0; c < 24; c++) \ + { \ + int d = (dest & (1 << c)) ? 1 : 0; \ + if (source & (1 << c)) d |= 2; \ + if (pattern & (1 << c)) d |= 4; \ + if (virge->s3d.rop & (1 << d)) out |= (1 << c); \ + } \ + } while (0) + +#define WRITE(addr, val) \ + do \ + { \ + switch (bpp) \ + { \ + case 0: /*8 bpp*/ \ + vram[addr & 0x3fffff] = val; \ + virge->svga.changedvram[(addr & 0x3fffff) >> 10] = changeframecount; \ + break; \ + case 1: /*16 bpp*/ \ + *(uint16_t *)&vram[addr & 0x3fffff] = val; \ + virge->svga.changedvram[(addr & 0x3fffff) >> 10] = changeframecount; \ + break; \ + case 2: /*24 bpp*/ \ + *(uint32_t *)&vram[addr & 0x3fffff] = (val & 0xffffff) | \ + (vram[(addr + 3) & 0x3fffff] << 24); \ + virge->svga.changedvram[(addr & 0x3fffff) >> 10] = changeframecount; \ + break; \ + } \ + } while (0) + +static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) +{ + int cpu_input = (count != -1); + uint8_t *vram = virge->svga.vram; + uint32_t mono_pattern[64]; + int count_mask; + int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1; + int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1; + int bpp; + int x_mul; + int cpu_dat_shift; + uint32_t *pattern_data; + + switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) + { + case CMD_SET_FORMAT_8: + bpp = 0; + x_mul = 1; + cpu_dat_shift = 8; + pattern_data = virge->s3d.pattern_8; + break; + case CMD_SET_FORMAT_16: + bpp = 1; + x_mul = 2; + cpu_dat_shift = 16; + pattern_data = virge->s3d.pattern_16; + break; + case CMD_SET_FORMAT_24: + default: + bpp = 2; + x_mul = 3; + cpu_dat_shift = 24; + pattern_data = virge->s3d.pattern_32; + break; + } + if (virge->s3d.cmd_set & CMD_SET_MP) + pattern_data = mono_pattern; + + switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK) + { + case CMD_SET_ITA_BYTE: + count_mask = ~0x7; + break; + case CMD_SET_ITA_WORD: + count_mask = ~0xf; + break; + case CMD_SET_ITA_DWORD: + default: + count_mask = ~0x1f; + break; + } + if (virge->s3d.cmd_set & CMD_SET_MP) + { + int x, y; + for (y = 0; y < 4; y++) + { + for (x = 0; x < 8; x++) + { + if (virge->s3d.mono_pat_0 & (1 << (x + y*8))) + mono_pattern[y*8 + x] = virge->s3d.pat_fg_clr; + else + mono_pattern[y*8 + x] = virge->s3d.pat_bg_clr; + if (virge->s3d.mono_pat_1 & (1 << (x + y*8))) + mono_pattern[(y+4)*8 + x] = virge->s3d.pat_fg_clr; + else + mono_pattern[(y+4)*8 + x] = virge->s3d.pat_bg_clr; + } + } + } + switch (virge->s3d.cmd_set & CMD_SET_COMMAND_MASK) + { + case CMD_SET_COMMAND_NOP: + break; + + case CMD_SET_COMMAND_BITBLT: + if (count == -1) + { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.src_y = virge->s3d.rsrc_y; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.dest_y = virge->s3d.rdest_y; + virge->s3d.w = virge->s3d.r_width; + virge->s3d.h = virge->s3d.r_height; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + virge->s3d.data_left_count = 0; + + /* pclog("BitBlt start %i,%i %i,%i %02X\n", virge->s3d.dest_x, + virge->s3d.dest_y, + virge->s3d.w, + virge->s3d.h, + virge->s3d.rop);*/ + + if (virge->s3d.cmd_set & CMD_SET_IDS) + return; + } + if (!virge->s3d.h) + return; + while (count) + { + uint32_t src_addr = virge->s3d.src_base + (virge->s3d.src_x * x_mul) + (virge->s3d.src_y * virge->s3d.src_str); + uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); + uint32_t source, dest, pattern; + uint32_t out = 0; + int update = 1; + + switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) + { + case 0: + case CMD_SET_MS: + READ(src_addr, source); + break; + case CMD_SET_IDS: + if (virge->s3d.data_left_count) + { + /*Handle shifting for 24-bit data*/ + source = virge->s3d.data_left; + source |= ((cpu_dat << virge->s3d.data_left_count) & ~0xff000000); + cpu_dat >>= (cpu_dat_shift - virge->s3d.data_left_count); + count -= (cpu_dat_shift - virge->s3d.data_left_count); + virge->s3d.data_left_count = 0; + if (count < cpu_dat_shift) + { + virge->s3d.data_left = cpu_dat; + virge->s3d.data_left_count = count; + count = 0; + } + } + else + { + source = cpu_dat; + cpu_dat >>= cpu_dat_shift; + count -= cpu_dat_shift; + if (count < cpu_dat_shift) + { + virge->s3d.data_left = cpu_dat; + virge->s3d.data_left_count = count; + count = 0; + } + } + break; + case CMD_SET_IDS | CMD_SET_MS: + source = (cpu_dat & (1 << 31)) ? virge->s3d.src_fg_clr : virge->s3d.src_bg_clr; + if ((virge->s3d.cmd_set & CMD_SET_TP) && !(cpu_dat & (1 << 31))) + update = 0; + cpu_dat <<= 1; + count--; + break; + } + + CLIP(virge->s3d.dest_x, virge->s3d.dest_y); + + if (update) + { + READ(dest_addr, dest); + pattern = pattern_data[(virge->s3d.dest_y & 7)*8 + (virge->s3d.dest_x & 7)]; + MIX(); + + WRITE(dest_addr, out); + } + + virge->s3d.src_x += x_inc; + virge->s3d.dest_x += x_inc; + if (!virge->s3d.w) + { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.w = virge->s3d.r_width; + + virge->s3d.src_y += y_inc; + virge->s3d.dest_y += y_inc; + virge->s3d.h--; + + switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) + { + case CMD_SET_IDS: + cpu_dat >>= (count - (count & count_mask)); + count &= count_mask; + virge->s3d.data_left_count = 0; + break; + + case CMD_SET_IDS | CMD_SET_MS: + cpu_dat <<= (count - (count & count_mask)); + count &= count_mask; + break; + } + if (!virge->s3d.h) + { + return; + } + } + else + virge->s3d.w--; + } + break; + + case CMD_SET_COMMAND_RECTFILL: + /*No source, pattern = pat_fg_clr*/ + if (count == -1) + { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.src_y = virge->s3d.rsrc_y; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.dest_y = virge->s3d.rdest_y; + virge->s3d.w = virge->s3d.r_width; + virge->s3d.h = virge->s3d.r_height; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + +/* pclog("RctFll start %i,%i %i,%i %02X\n", virge->s3d.dest_x, + virge->s3d.dest_y, + virge->s3d.w, + virge->s3d.h, + virge->s3d.rop);*/ + } + + while (count) + { + uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); + uint32_t source = 0, dest, pattern = virge->s3d.pat_fg_clr; + uint32_t out = 0; + int update = 1; + + CLIP(virge->s3d.dest_x, virge->s3d.dest_y); + + if (update) + { + READ(dest_addr, dest); + + MIX(); + + WRITE(dest_addr, out); + } + + virge->s3d.src_x += x_inc; + virge->s3d.dest_x += x_inc; + if (!virge->s3d.w) + { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.w = virge->s3d.r_width; + + virge->s3d.src_y += y_inc; + virge->s3d.dest_y += y_inc; + virge->s3d.h--; + if (!virge->s3d.h) + { + return; + } + } + else + virge->s3d.w--; + count--; + } + break; + + case CMD_SET_COMMAND_LINE: + if (count == -1) + { + virge->s3d.dest_x = virge->s3d.lxstart; + virge->s3d.dest_y = virge->s3d.lystart; + virge->s3d.h = virge->s3d.lycnt; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + if (virge->s3d.ldx >= 0) + virge->s3d.dest_x -= virge->s3d.ldx / 2; + else + virge->s3d.dest_x += virge->s3d.ldx / 2; + //virge->s3d.dest_dest_x = virge->s3d.dest_x + virge->s3d.ldx; + } + while (virge->s3d.h) + { + int x = virge->s3d.dest_x >> 20; + int new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20; + + do + { + uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); + uint32_t source = 0, dest, pattern; + uint32_t out = 0; + int update = 1; + + CLIP(x, virge->s3d.dest_y); + + if (update) + { + READ(dest_addr, dest); + pattern = virge->s3d.pat_fg_clr; + + MIX(); + + WRITE(dest_addr, out); + } + + if (x < new_x) + x++; + else if (x > new_x) + x--; + } while (x != new_x); + + virge->s3d.dest_x += virge->s3d.ldx; + virge->s3d.dest_y--; + virge->s3d.h--; + } + break; + + default: + fatal("s3_virge_bitblt : blit command %i %08x\n", (virge->s3d.cmd_set >> 27) & 0xf, virge->s3d.cmd_set); + } } - -void s3_virge_hwcursor_draw(svga_t *svga, int displine) +static 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; - 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] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; @@ -394,72 +1161,150 @@ void s3_virge_hwcursor_draw(svga_t *svga, int displine) } } - -uint8_t s3_virge_pci_read(int func, int addr, void *p) +static 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); + uint8_t ret = 0; +// pclog("S3 PCI read %08X ", addr); switch (addr) { - case 0x00: return 0x33; /*'S3'*/ - case 0x01: return 0x53; + case 0x00: ret = 0x33; break; /*'S3'*/ + case 0x01: ret = 0x53; break; - 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*/ - - case 0x0a: return 0x00; /*Supports VGA interface*/ - case 0x0b: return 0x03; - - case 0x10: return 0x00; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return 0x00; - case 0x13: return svga->crtc[0x59] & 0xfc; + case 0x02: ret = virge->virge_id_low; break; + case 0x03: ret = virge->virge_id_high; break; - case 0x30: return 0x01; /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return 0x0C; - case 0x33: return 0x00; + case 0x04: ret = virge->pci_regs[0x04] & 0x27; break; + + case 0x07: ret = virge->pci_regs[0x07] & 0x36; break; + + case 0x08: ret = 0; break; /*Revision ID*/ + case 0x09: ret = 0; break; /*Programming interface*/ + + case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ + case 0x0b: ret = 0x03; /*output = 3; */break; + + case 0x0d: ret = virge->pci_regs[0x0d] & 0xf8; break; + + case 0x10: ret = 0x00; break;/*Linear frame buffer address*/ + case 0x11: ret = 0x00; break; + case 0x12: ret = 0x00; break; + case 0x13: ret = svga->crtc[0x59] & 0xfc; break; + + case 0x30: ret = virge->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ + case 0x31: ret = 0x00; break; + case 0x32: ret = virge->pci_regs[0x32]; break; + case 0x33: ret = virge->pci_regs[0x33]; break; + + case 0x3c: ret = virge->pci_regs[0x3c]; break; + + case 0x3d: ret = 0x01; break; /*INTA*/ + + case 0x3e: ret = 0x04; break; + case 0x3f: ret = 0xff; break; } - return virge->pci_regs[addr]; +// pclog("%02X\n", ret); + return ret; } -void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) +static 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; - +// pclog("S3 PCI write %08X %02X %04X:%08X\n", addr, val, CS, pc); switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x3d: case 0x3e: case 0x3f: - break; + return; + + case PCI_REG_COMMAND: + if (val & PCI_COMMAND_IO) + { + io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + } + else + io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; + return; + case 0x07: + virge->pci_regs[0x07] = val & 0x3e; + return; + case 0x0d: + virge->pci_regs[0x0d] = val & 0xf8; + return; case 0x13: svga->crtc[0x59] = val & 0xfc; s3_virge_updatemapping(virge); - break; + return; + + case 0x30: case 0x32: case 0x33: + virge->pci_regs[addr] = val; + if (virge->pci_regs[0x30] & 0x01) + { + uint32_t addr = (virge->pci_regs[0x32] << 16) | (virge->pci_regs[0x33] << 24); + pclog("Virge bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&virge->bios_rom.mapping, addr, 0x8000); + mem_mapping_enable(&virge->bios_rom.mapping); + } + else + { + pclog("Virge bios_rom disabled\n"); + mem_mapping_disable(&virge->bios_rom.mapping); + } + return; + case 0x3c: + virge->pci_regs[0x3c] = val; + return; } - virge->pci_regs[addr] = val; } -void *s3_virge_init() +static void *s3_virge_init() { 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); - mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, virge); - mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &virge->svga); + rom_init(&virge->bios_rom, "roms/s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (PCI) + mem_mapping_disable(&virge->bios_rom.mapping); + + mem_mapping_add(&virge->mmio_mapping, 0, 0, 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, + 0, + virge); + mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_new_mmio_read, + s3_virge_new_mmio_read_w, + s3_virge_new_mmio_read_l, + s3_virge_new_mmio_write, + s3_virge_new_mmio_write_w, + s3_virge_new_mmio_write_l, + NULL, + 0, + virge); + mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, + svga_readw_linear, + svga_readl_linear, + svga_write_linear, + svga_writew_linear, + svga_writel_linear, + NULL, + 0, + &virge->svga); io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); @@ -467,6 +1312,7 @@ void *s3_virge_init() virge->pci_regs[5] = 0; virge->pci_regs[6] = 0; virge->pci_regs[7] = 2; + virge->pci_regs[0x32] = 0x0c; virge->pci_regs[0x3d] = 1; virge->pci_regs[0x3e] = 4; virge->pci_regs[0x3f] = 0xff; @@ -476,15 +1322,17 @@ void *s3_virge_init() virge->virge_rev = 0; virge->virge_id = 0xe1; - virge->svga.crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5); - virge->svga.crtc[0x37] = 1 | (7 << 5); + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4); + virge->svga.crtc[0x37] = 1;// | (7 << 5); + virge->svga.crtc[0x53] = 1 << 3; + virge->svga.crtc[0x59] = 0x70; pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); return virge; } -void s3_virge_close(void *p) +static void s3_virge_close(void *p) { virge_t *virge = (virge_t *)p; @@ -493,21 +1341,26 @@ void s3_virge_close(void *p) free(virge); } -void s3_virge_speed_changed(void *p) +static int s3_virge_available() +{ + return rom_present("roms/s3virge.bin"); +} + +static void s3_virge_speed_changed(void *p) { virge_t *virge = (virge_t *)p; svga_recalctimings(&virge->svga); } -void s3_virge_force_redraw(void *p) +static void s3_virge_force_redraw(void *p) { virge_t *virge = (virge_t *)p; virge->svga.fullchange = changeframecount; } -int s3_virge_add_status_info(char *s, int max_len, void *p) +static int s3_virge_add_status_info(char *s, int max_len, void *p) { virge_t *virge = (virge_t *)p; @@ -520,7 +1373,7 @@ device_t s3_virge_device = DEVICE_NOT_WORKING, s3_virge_init, s3_virge_close, - NULL, + s3_virge_available, s3_virge_speed_changed, s3_virge_force_redraw, s3_virge_add_status_info diff --git a/src/vid_svga.c b/src/vid_svga.c index 5193abc..d73ff15 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -641,7 +641,7 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->hwcursor_draw = hwcursor_draw; // _svga_recalctimings(svga); - mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga); + mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, 0, svga); timer_add(svga_poll, &svga->vidtime, TIMER_ALWAYS_ENABLED, svga); vramp = svga->vram; diff --git a/src/vid_tandy.c b/src/vid_tandy.c index c7883fa..d7ed474 100644 --- a/src/vid_tandy.c +++ b/src/vid_tandy.c @@ -667,7 +667,7 @@ void *tandy_init() 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_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, tandy); + mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, NULL, 0, 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; diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index 152c2fd..1aeba17 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -4,6 +4,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -15,6 +16,8 @@ typedef struct tgui_t mem_mapping_t linear_mapping; mem_mapping_t accel_mapping; + rom_t bios_rom; + svga_t svga; struct @@ -462,37 +465,20 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) } } -void *tgui8900d_init() -{ - tgui_t *tgui = malloc(sizeof(tgui_t)); - memset(tgui, 0, sizeof(tgui_t)); - - svga_init(&tgui->svga, tgui, 1 << 20, /*1mb - chip supports 2mb, but drivers are buggy*/ - tgui_recalctimings, - tgui_in, tgui_out, - NULL); - - mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &tgui->svga); - mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, tgui); - mem_mapping_disable(&tgui->linear_mapping); - mem_mapping_disable(&tgui->accel_mapping); - - io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - - return tgui; -} void *tgui9440_init() { tgui_t *tgui = malloc(sizeof(tgui_t)); memset(tgui, 0, sizeof(tgui_t)); + rom_init(&tgui->bios_rom, "roms/9440.vbi", 0xc0000, 0x8000, 0x7fff, 0, 0); + svga_init(&tgui->svga, tgui, 1 << 21, /*2mb*/ tgui_recalctimings, tgui_in, tgui_out, tgui_hwcursor_draw); - mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &tgui->svga); - mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, tgui); + mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &tgui->svga); + mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, 0, tgui); mem_mapping_disable(&tgui->accel_mapping); io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); @@ -503,6 +489,11 @@ void *tgui9440_init() return tgui; } +static int tgui9440_available() +{ + return rom_present("roms/9440.vbi"); +} + void tgui_close(void *p) { tgui_t *tgui = (tgui_t *)p; @@ -1127,7 +1118,7 @@ device_t tgui9440_device = 0, tgui9440_init, tgui_close, - NULL, + tgui9440_available, tgui_speed_changed, tgui_force_redraw, tgui_add_status_info diff --git a/src/vid_tvga.c b/src/vid_tvga.c index 813c32d..a6c91e7 100644 --- a/src/vid_tvga.c +++ b/src/vid_tvga.c @@ -4,6 +4,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -17,6 +18,8 @@ typedef struct tvga_t svga_t svga; tkd8001_ramdac_t ramdac; + + rom_t bios_rom; uint8_t tvga_3d8, tvga_3d9; int oldmode; @@ -48,7 +51,10 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) break; case 0xd: if (tvga->oldmode) - tvga->oldctrl2 = val; + { + tvga->oldctrl2 = val; + svga->vrammask = (val & 0x10) ? 0xfffff : 0x3ffff; + } else tvga->newctrl2 = val; break; @@ -92,7 +98,7 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; -// if (svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = %02X\n", svga->crtcreg, val); +// if (svga->crtcreg != 0xC && svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = %02X %04X:%04X\n", svga->crtcreg, val, CS, pc); if (old != val) { if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) @@ -240,6 +246,8 @@ void *tvga8900d_init() { tvga_t *tvga = malloc(sizeof(tvga_t)); memset(tvga, 0, sizeof(tvga_t)); + + rom_init(&tvga->bios_rom, "roms/trident.bin", 0xc0000, 0x8000, 0x7fff, 0, 0); svga_init(&tvga->svga, tvga, 1 << 20, /*1mb - chip supports 2mb, but drivers are buggy*/ tvga_recalctimings, @@ -251,6 +259,11 @@ void *tvga8900d_init() return tvga; } +static int tvga8900d_available() +{ + return rom_present("roms/trident.bin"); +} + void tvga_close(void *p) { tvga_t *tvga = (tvga_t *)p; @@ -287,7 +300,7 @@ device_t tvga8900d_device = 0, tvga8900d_init, tvga_close, - NULL, + tvga8900d_available, tvga_speed_changed, tvga_force_redraw, tvga_add_status_info diff --git a/src/vid_vga.c b/src/vid_vga.c index 9ec2777..830fc21 100644 --- a/src/vid_vga.c +++ b/src/vid_vga.c @@ -4,6 +4,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "video.h" #include "vid_svga.h" #include "vid_vga.h" @@ -11,6 +12,8 @@ typedef struct vga_t { svga_t svga; + + rom_t bios_rom; } vga_t; void vga_out(uint16_t addr, uint8_t val, void *p) @@ -78,6 +81,8 @@ void *vga_init() vga_t *vga = malloc(sizeof(vga_t)); memset(vga, 0, sizeof(vga_t)); + rom_init(&vga->bios_rom, "roms/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0, 0); + svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ NULL, vga_in, vga_out, @@ -91,6 +96,11 @@ void *vga_init() return vga; } +static int vga_available() +{ + return rom_present("roms/ibm_vga.bin"); +} + void vga_close(void *p) { vga_t *vga = (vga_t *)p; @@ -127,7 +137,7 @@ device_t vga_device = DEVICE_NOT_WORKING, vga_init, vga_close, - NULL, + vga_available, vga_speed_changed, vga_force_redraw, vga_add_status_info diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index b8d5434..7156b06 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -734,9 +734,9 @@ void voodoo_init() voodoo_make_dither(); pci_add(voodoo_pci_read, voodoo_pci_write, NULL); - mem_mapping_add(&voodoo.mmio_mapping, 0, 0, NULL, NULL, voodoo_readl, NULL, NULL, voodoo_writel, NULL); - mem_mapping_add(&voodoo.fb_mapping, 0, 0, NULL, voodoo_fb_readw, voodoo_fb_readl, NULL, voodoo_fb_writew, voodoo_fb_writel, NULL); - mem_mapping_add(&voodoo.tex_mapping, 0, 0, NULL, NULL, NULL, NULL, voodoo_tex_writew, voodoo_tex_writel, NULL); + mem_mapping_add(&voodoo.mmio_mapping, 0, 0, NULL, NULL, voodoo_readl, NULL, NULL, voodoo_writel, NULL, 0, NULL); + mem_mapping_add(&voodoo.fb_mapping, 0, 0, NULL, voodoo_fb_readw, voodoo_fb_readl, NULL, voodoo_fb_writew, voodoo_fb_writel, NULL, 0, NULL); + mem_mapping_add(&voodoo.tex_mapping, 0, 0, NULL, NULL, NULL, NULL, voodoo_tex_writew, voodoo_tex_writel, NULL, 0, NULL); voodoo.fb_mem = malloc(2 * 1024 * 1024); voodoo.tex_mem = malloc(2 * 1024 * 1024); diff --git a/src/video.c b/src/video.c index bb8ec69..7601493 100644 --- a/src/video.c +++ b/src/video.c @@ -8,6 +8,7 @@ #include "vid_svga.h" #include "io.h" #include "cpu.h" +#include "rom.h" #include "timer.h" #include "vid_ati18800.h" @@ -229,11 +230,15 @@ void video_init() return; case ROM_PC2086: - case ROM_PC3086: - device_add(¶dise_pvga1a_device); + device_add(¶dise_pvga1a_pc2086_device); return; + + case ROM_PC3086: + device_add(¶dise_pvga1a_pc3086_device); + return; + case ROM_MEGAPC: - device_add(¶dise_wd90c11_device); + device_add(¶dise_wd90c11_megapc_device); return; case ROM_ACER386: diff --git a/src/win.c b/src/win.c index 03f6900..7db963b 100644 --- a/src/win.c +++ b/src/win.c @@ -386,18 +386,14 @@ int WINAPI WinMain (HINSTANCE hThisInstance, } } - d = gfxcard; + for (c = 0; c < 18; c++) - { - gfxcard = c; - gfx_present[c] = mem_load_video_bios(); - } - gfxcard = d; - c = mem_load_video_bios(); - if (!c) + gfx_present[c] = video_card_available(video_old_to_new(c)); + + if (!video_card_available(video_old_to_new(gfxcard))) { if (romset!=-1) MessageBox(hwnd,"Configured video BIOS not available.\nDefaulting to available romset.","PCem error",MB_OK); - for (c=0;c<18;c++) + for (c = 17; c >= 0; c--) { if (gfx_present[c]) { @@ -783,7 +779,6 @@ BOOL CALLBACK configdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara sound_card_current = temp_sound_card_current; mem_resize(); - mem_load_video_bios(); loadbios(); resetpchard(); }