From: Toni Wilen Date: Sat, 29 Aug 2020 16:58:00 +0000 (+0300) Subject: PCem v16 merge. Modifications. X-Git-Tag: 4900~326 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=12fadbb3d40819ce0300870dabb29657a012bd76;p=francis%2Fwinuae.git PCem v16 merge. Modifications. --- diff --git a/pcem/386_dynarec.cpp b/pcem/386_dynarec.cpp index b7ab1bfd..dc87772c 100644 --- a/pcem/386_dynarec.cpp +++ b/pcem/386_dynarec.cpp @@ -391,7 +391,7 @@ void exec386_dynarec(int cycs) if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) { - void (*code)() = (void *)&block->data[BLOCK_START]; + void (*code)() = (void(*)(void))&block->data[BLOCK_START]; // if (output) pclog("Run block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%08x %04x %08x %08x %016llx %08x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, get_phys(cs+pc), block->phys, block->page_mask, block->endpc); diff --git a/pcem/808x.cpp b/pcem/808x.cpp index d81ee335..99eba41f 100644 --- a/pcem/808x.cpp +++ b/pcem/808x.cpp @@ -327,7 +327,6 @@ reg = If mod=11, (depending on data size, 16 bits/8 bits, 32 bits=extend 16 bit */ uint32_t easeg; -uint32_t rmdat; static uint16_t zero=0; uint16_t *mod1add[2][8]; @@ -476,6 +475,8 @@ void makeznptable() int indump = 0; +#ifndef UAE + void dumpregs() { int c,d=0,e=0; @@ -595,6 +596,8 @@ void dumpregs() indump = 0; } +#endif + int x86_was_reset = 0; void resetx86() { diff --git a/pcem/cpu.cpp b/pcem/cpu.cpp index 7490db11..6dbd3406 100644 --- a/pcem/cpu.cpp +++ b/pcem/cpu.cpp @@ -13,6 +13,9 @@ uint32_t cpu_features; static int cpu_turbo_speed, cpu_nonturbo_speed; static int cpu_turbo = 1; +#ifdef UAE +int cpu_multiplier; +#endif int isa_cycles; int has_vlb; @@ -189,6 +192,15 @@ void cpu_set() cpu_s = &models[model].cpu[cpu_manufacturer].cpus[cpu]; + int rspeed = cpu_s->rspeed; + cpu_multi = cpu_s->multi; +#ifdef UAE + if (cpu_multiplier > 0) { + rspeed = rspeed + (int32_t)(rspeed * (int64_t)cpu_multiplier / 1000); + cpu_multi += cpu_multiplier / 1000; + } +#endif + CPUID = cpu_s->cpuid_model; cpuspeed = cpu_s->speed; is8086 = (cpu_s->cpu_type > CPU_8088); @@ -199,8 +211,7 @@ void cpu_set() cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC); if (cpu_s->multi) - cpu_busspeed = cpu_s->rspeed / cpu_s->multi; - cpu_multi = cpu_s->multi; + cpu_busspeed = rspeed / cpu_s->multi; ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; has_vlb = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type <= CPU_Cx5x86); @@ -241,10 +252,16 @@ void cpu_set() pclog("hasfpu - %i\n",hasfpu); pclog("is486 - %i %i\n",is486,cpu_s->cpu_type); +#ifdef UAE + x86_setopcodes(ops_386, ops_386_0f, NULL, NULL); +#else x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); +#endif x86_opcodes_REPE = ops_REPE; x86_opcodes_REPNE = ops_REPNE; x86_opcodes_3DNOW = ops_3DNOW; + +#ifndef UAE x86_dynarec_opcodes_REPE = dynarec_ops_REPE; x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; @@ -288,6 +305,7 @@ void cpu_set() x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32; } codegen_timing_set(&codegen_timing_486); +#endif if (hasfpu) { @@ -340,7 +358,11 @@ void cpu_set() break; case CPU_286: +#ifdef UAE + x86_setopcodes(ops_286, ops_286_0f, NULL, NULL); +#else x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); +#endif timing_rr = 2; /*register dest - register src*/ timing_rm = 7; /*register dest - memory src*/ timing_mr = 7; /*memory dest - register src*/ @@ -601,7 +623,9 @@ void cpu_set() timing_jmp_pm_gate = 37; timing_misaligned = 3; break; - + +#ifndef UAE + case CPU_Cx5x86: timing_rr = 1; /*register dest - register src*/ timing_rm = 1; /*register dest - memory src*/ @@ -1005,6 +1029,8 @@ void cpu_set() codegen_timing_set(&codegen_timing_k6); break; +#endif + default: fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); } diff --git a/pcem/ibm.h b/pcem/ibm.h index da0f39fe..f984d4a7 100644 --- a/pcem/ibm.h +++ b/pcem/ibm.h @@ -19,16 +19,30 @@ #define readflash_get(offset, drive) ((readflash&(1<<((offset)+(drive)))) != 0) /*Memory*/ -uint8_t *ram; +#ifdef UAE +extern uint8_t *ram; +extern uint32_t rammask; +#else +uint8_t *ram; uint32_t rammask; +#endif +#ifdef UAE +extern int readlookup[256], readlookupp[256]; +extern uintptr_t *readlookup2; +extern int readlnext; +extern int writelookup[256], writelookupp[256]; +extern uintptr_t *writelookup2; +extern int writelnext; +#else int readlookup[256],readlookupp[256]; uintptr_t *readlookup2; int readlnext; int writelookup[256],writelookupp[256]; uintptr_t *writelookup2; int writelnext; +#endif extern int mmu_perm; @@ -104,7 +118,11 @@ typedef struct PIT void (*set_out_funcs[3])(int new_out, int old_out); } PIT; +#ifdef UAE +extern PIT pit, pit2; +#else PIT pit, pit2; +#endif void setpitclock(float clock); float pit_timer0_freq(); @@ -133,7 +151,11 @@ typedef struct dma_t uint16_t io_addr; } dma_t; +#ifdef UAE +extern dma_t dma[8]; +#else dma_t dma[8]; +#endif /*PPI*/ typedef struct PPI @@ -142,8 +164,11 @@ typedef struct PPI uint8_t pa,pb; } PPI; +#ifdef UAE +extern PPI ppi; +#else PPI ppi; - +#endif /*PIC*/ typedef struct PIC @@ -155,16 +180,25 @@ typedef struct PIC uint8_t level_sensitive; } PIC; +#ifdef UAE +extern PIC pic, pic2; +#else PIC pic,pic2; +#endif extern int pic_intpending; +#ifdef UAE +extern char discfns[2][256]; +extern int driveempty[2]; +#else char discfns[2][256]; int driveempty[2]; +#endif #define PCJR (romset == ROM_IBMPCJR) -int GAMEBLASTER, GUS, SSI2001, voodoo_enabled; +extern int GAMEBLASTER, GUS, SSI2001, voodoo_enabled; extern int AMSTRAD, AT, is386, PCI, TANDY, MCA; enum @@ -266,8 +300,13 @@ enum extern int romspresent[ROM_MAX]; +#ifdef UAE +extern int hasfpu; +extern int romset; +#else int hasfpu; int romset; +#endif enum { @@ -319,13 +358,25 @@ enum extern int gfx_present[GFX_MAX]; +#ifdef UAE +extern int gfxcard; +#else int gfxcard; +#endif +#ifdef UAE +extern int cpuspeed; +#else int cpuspeed; +#endif /*Video*/ +#ifdef UAE +extern int readflash; +#else int readflash; +#endif extern int egareads,egawrites; extern int vid_resize; extern int vid_api; @@ -335,13 +386,17 @@ extern int changeframecount; /*Sound*/ +#ifdef UAE +extern int ppispeakon; +extern int gated, speakval, speakon; +#else int ppispeakon; +int gated, speakval, speakon; +#endif extern uint64_t CGACONST; extern uint64_t MDACONST; extern uint64_t VGACONST1,VGACONST2; extern uint64_t RTCCONST; -int gated,speakval,speakon; - /*Sound Blaster*/ #define SADLIB 1 /*No DSP*/ @@ -365,11 +420,18 @@ typedef struct int tracks; } PcemHDC; +#ifdef UAE +extern PcemHDC hdc[7]; +#else PcemHDC hdc[7]; +#endif /*Keyboard*/ +#ifdef UAE +extern int keybsenddelay; +#else int keybsenddelay; - +#endif /*CD-ROM*/ extern int cdrom_drive; diff --git a/pcem/io.h b/pcem/io.h index 84792374..7ebadc15 100644 --- a/pcem/io.h +++ b/pcem/io.h @@ -17,3 +17,22 @@ void io_removehandler(uint16_t base, int size, void (*outw)(uint16_t addr, uint16_t val, void *priv), void (*outl)(uint16_t addr, uint32_t val, void *priv), void *priv); + +#ifdef UAE +void io_sethandlerx(uint16_t base, int size, + uint8_t(*inb)(uint16_t addr, void *priv), + uint16_t(*inw)(uint16_t addr, void *priv), + uint32_t(*inl)(uint16_t addr, void *priv), + void (*outb)(uint16_t addr, uint8_t val, void *priv), + void (*outw)(uint16_t addr, uint16_t val, void *priv), + void (*outl)(uint16_t addr, uint32_t val, void *priv), + void *priv); +void io_removehandlerx(uint16_t base, int size, + uint8_t(*inb)(uint16_t addr, void *priv), + uint16_t(*inw)(uint16_t addr, void *priv), + uint32_t(*inl)(uint16_t addr, void *priv), + void (*outb)(uint16_t addr, uint8_t val, void *priv), + void (*outw)(uint16_t addr, uint16_t val, void *priv), + void (*outl)(uint16_t addr, uint32_t val, void *priv), + void *priv); +#endif \ No newline at end of file diff --git a/pcem/keyboard_at.cpp b/pcem/keyboard_at.cpp index b2fd23b3..64534ddf 100644 --- a/pcem/keyboard_at.cpp +++ b/pcem/keyboard_at.cpp @@ -14,6 +14,11 @@ #include "keyboard.h" #include "keyboard_at.h" +#ifdef UAE +extern bool ps2_mouse_supported; +extern uint8_t x86_get_jumpers(void); +#endif + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 @@ -282,8 +287,13 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) keyboard_at.wantirq = 1; if (!(val & 1) && keyboard_at.wantirq) keyboard_at.wantirq = 0; +#ifdef UAE + if (ps2_mouse_supported) +#endif mouse_scan = !(val & 0x20); +#ifndef UAE // A2386SX sets this bit but if translation is allowed, keyboard stops working. Purpose unknown. keyboard_at.translate = val & 0x40; +#endif } break; @@ -311,10 +321,16 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) break; case 0xd3: /*Write to mouse output buffer*/ +#ifdef UAE + if (ps2_mouse_supported) +#endif keyboard_at_adddata_mouse(val); break; case 0xd4: /*Write to mouse*/ +#ifdef UAE + if (ps2_mouse_supported) +#endif if (keyboard_at.mouse_write) { keyboard_at.mouse_write(val, keyboard_at.mouse_p); @@ -417,8 +433,10 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) case 0xf2: /*Read ID*/ keyboard_at_adddata_keyboard(0xfa); +#ifndef UAE // A2286/A2386 does not want these codes keyboard_at_adddata_keyboard(0xab); keyboard_at_adddata_keyboard(0x83); +#endif break; case 0xf3: /*Set typematic rate/delay*/ @@ -507,11 +525,20 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) break; case 0xa8: /*Enable mouse port*/ +#ifdef UAE + if (ps2_mouse_supported) { +#endif mouse_scan = 1; keyboard_at.mem[0] &= ~0x20; +#ifdef UAE + } +#endif break; case 0xa9: /*Test mouse port*/ +#ifdef UAE + if (ps2_mouse_supported) +#endif keyboard_at_adddata(0x00); /*no error*/ break; @@ -549,6 +576,10 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) case 0xae: /*Enable keyboard*/ keyboard_at.mem[0] &= ~0x10; +#ifdef UAE + if (!keyboard_at.initialised) + keyboard_at_adddata(0x00); // A2286 BIOS requires data in output buffer after keyboard enable +#endif break; case 0xb0: /* T3100e: Turbo on */ @@ -616,7 +647,11 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) if (romset == ROM_T3100E) keyboard_at.input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; +#ifdef UAE + keyboard_at_adddata(x86_get_jumpers()); +#else keyboard_at_adddata(keyboard_at.input_port | 4); +#endif keyboard_at.input_port = ((keyboard_at.input_port + 1) & 3) | (keyboard_at.input_port & 0xfc); break; @@ -644,10 +679,16 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) break; case 0xd3: /*Write mouse output buffer*/ +#ifdef UAE + if (ps2_mouse_supported) +#endif keyboard_at.want60 = 1; break; case 0xd4: /*Write to mouse*/ +#ifdef UAE + if (ps2_mouse_supported) +#endif keyboard_at.want60 = 1; break; @@ -762,6 +803,13 @@ static void at_refresh(void *p) timer_advance_u64(&keyboard_at.refresh_timer, PS2_REFRESH_TIME); } +// C++ FIX +static void keyboard_at_poll_2(void *p) +{ + keyboard_at_poll(); +} +// END C++ + void keyboard_at_init() { //return; @@ -776,7 +824,7 @@ void keyboard_at_init() keyboard_set_scancode_set(SCANCODE_SET_2); keyboard_at.scancode_set = SCANCODE_SET_2; - timer_add(&keyboard_at.send_delay_timer, keyboard_at_poll, NULL, 1); + timer_add(&keyboard_at.send_delay_timer, keyboard_at_poll_2, NULL, 1); } void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p) diff --git a/pcem/mem.cpp b/pcem/mem.cpp index 89bbff8d..43d2d958 100644 --- a/pcem/mem.cpp +++ b/pcem/mem.cpp @@ -1413,30 +1413,50 @@ void mem_set_704kb() void mem_init() { - readlookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); - writelookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); - page_lookup = malloc((1 << 20) * sizeof(page_t *)); + readlookup2 = (uintptr_t*)malloc(1024 * 1024 * sizeof(uintptr_t)); + writelookup2 = (uintptr_t *)malloc(1024 * 1024 * sizeof(uintptr_t)); + page_lookup = (page_t**)malloc((1 << 20) * sizeof(page_t *)); memset(ff_array, 0xff, sizeof(ff_array)); } +#ifdef UAE +void mem_free() +{ + free(ram); + ram = NULL; + free(readlookup2); + readlookup2 = NULL; + free(writelookup2); + writelookup2 = NULL; + free(pages); + pages = NULL; + free(page_lookup); + page_lookup = NULL; + free(byte_dirty_mask); + byte_dirty_mask = NULL; + free(byte_code_present_mask); + byte_code_present_mask = NULL; +} +#endif + void mem_alloc() { int c; free(ram); - ram = malloc(mem_size * 1024); + ram = (uint8_t*)malloc(mem_size * 1024); memset(ram, 0, mem_size * 1024); free(byte_dirty_mask); - byte_dirty_mask = malloc((mem_size * 1024) / 8); + byte_dirty_mask = (uint64_t*)malloc((mem_size * 1024) / 8); memset(byte_dirty_mask, 0, (mem_size * 1024) / 8); free(byte_code_present_mask); - byte_code_present_mask = malloc((mem_size * 1024) / 8); + byte_code_present_mask = (uint64_t*)malloc((mem_size * 1024) / 8); memset(byte_code_present_mask, 0, (mem_size * 1024) / 8); free(pages); - pages = malloc((((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); + pages = (page_t*)malloc((((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); memset(pages, 0, (((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); for (c = 0; c < (((mem_size + 384) * 1024) >> 12); c++) { diff --git a/pcem/mem.h b/pcem/mem.h index 41fe23f3..3c6a0f5e 100644 --- a/pcem/mem.h +++ b/pcem/mem.h @@ -66,6 +66,33 @@ void mem_mapping_enable(mem_mapping_t *mapping); void mem_set_mem_state(uint32_t base, uint32_t size, int state); +#ifdef UAE +void mem_mapping_addx(mem_mapping_t *mapping, + uint32_t base, + uint32_t size, + uint8_t(*read_b)(uint32_t addr, void *p), + uint16_t(*read_w)(uint32_t addr, void *p), + uint32_t(*read_l)(uint32_t addr, void *p), + 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_handlerx(mem_mapping_t *mapping, + uint8_t(*read_b)(uint32_t addr, void *p), + uint16_t(*read_w)(uint32_t addr, void *p), + uint32_t(*read_l)(uint32_t addr, void *p), + 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)); +void mem_mapping_set_addrx(mem_mapping_t *mapping, uint32_t base, uint32_t size); +void mem_mapping_disablex(mem_mapping_t *mapping); +void mem_mapping_enablex(mem_mapping_t *mapping); +void mem_mapping_set_px(mem_mapping_t *mapping, void *p); + +#endif + #define MEM_READ_ANY 0x00 #define MEM_READ_INTERNAL 0x10 #define MEM_READ_EXTERNAL 0x20 @@ -106,8 +133,8 @@ void mem_write_nulll(uint32_t addr, uint32_t val, void *p); FILE *romfopen(char *fn, char *mode); -mem_mapping_t bios_mapping[8]; -mem_mapping_t bios_high_mapping[8]; +extern mem_mapping_t bios_mapping[8]; +extern mem_mapping_t bios_high_mapping[8]; extern mem_mapping_t ram_high_mapping; extern mem_mapping_t ram_remapped_mapping; @@ -222,6 +249,9 @@ void mem_add_bios(); void mem_init(); void mem_alloc(); +#ifdef UAE +void mem_free(); +#endif void mem_set_704kb(); diff --git a/pcem/mouse_ps2.cpp b/pcem/mouse_ps2.cpp index b1c219df..4df12310 100644 --- a/pcem/mouse_ps2.cpp +++ b/pcem/mouse_ps2.cpp @@ -243,7 +243,7 @@ void *mouse_ps2_init() void *mouse_intellimouse_init() { - mouse_ps2_t *mouse = mouse_ps2_init(); + mouse_ps2_t *mouse = (mouse_ps2_t*)mouse_ps2_init(); mouse->is_intellimouse = 1; diff --git a/pcem/nvr.cpp b/pcem/nvr.cpp index ccb7f9f0..4fdda9ba 100644 --- a/pcem/nvr.cpp +++ b/pcem/nvr.cpp @@ -17,7 +17,7 @@ int oldromset; int nvrmask=63; -uint8_t nvrram[128]; +uint8_t nvrram[128+64]; int nvraddr; int nvr_dosave = 0; @@ -31,6 +31,7 @@ typedef struct nvr_t int onesec_cnt; } nvr_t; +#ifndef UAE FILE *nvrfopen(char *fn, char *mode) { char s[512]; @@ -61,6 +62,7 @@ FILE *nvrfopen(char *fn, char *mode) return NULL; } } +#endif void getnvrtime() { @@ -227,6 +229,14 @@ static void writenvr(uint16_t addr, uint8_t val, void *p) else { nvraddr=val&nvrmask; + +#ifdef UAE + // A2386SX extra 64 byte bank + extern int x86_cmos_bank; + if (nvraddr >= 64 && x86_cmos_bank) + nvraddr += 64; +#endif + /*PS/2 BIOSes will disable NMIs and expect the watchdog timer to still be able to fire them. I suspect the watchdog is exempt from NMI masking. Currently NMIs are always enabled for PS/2 machines - this would mean that other peripherals @@ -273,10 +283,12 @@ uint8_t readnvr(uint16_t addr, void *p) void loadnvr() { - FILE *f; - nvrmask=63; oldromset=romset; + +#ifndef UAE + FILE *f; + switch (romset) { case ROM_PC1512: f = nvrfopen("pc1512.nvr", "rb"); break; @@ -371,14 +383,17 @@ void loadnvr() return; } fread(nvrram,128,1,f); + fclose(f); +#endif if (enable_sync) time_internal_sync(nvrram); else time_internal_set_nvrram(nvrram); /* Update the internal clock state based on the NVR registers. */ - fclose(f); nvrram[RTC_REGA] = 6; nvrram[RTC_REGB] = RTC_2412; } + +#ifndef UAE void savenvr() { FILE *f; @@ -465,6 +480,7 @@ void savenvr() fwrite(nvrram,128,1,f); fclose(f); } +#endif static void *nvr_init() { diff --git a/pcem/nvr.h b/pcem/nvr.h index c545f848..70a144b1 100644 --- a/pcem/nvr.h +++ b/pcem/nvr.h @@ -11,6 +11,6 @@ void savenvr(); FILE *nvrfopen(char *fn, char *mode); -extern uint8_t nvrram[128]; +extern uint8_t nvrram[128+64]; extern int nvrmask; extern int oldromset; diff --git a/pcem/pic.cpp b/pcem/pic.cpp index e6bf6791..79124296 100644 --- a/pcem/pic.cpp +++ b/pcem/pic.cpp @@ -4,6 +4,10 @@ #include "pit.h" #include "video.h" +#ifdef UAE +void x86_ack_keyboard(void); +#endif + int intclear; int keywaiting=0; int pic_intpending; @@ -120,7 +124,12 @@ void pic_write(uint16_t addr, uint8_t val, void *priv) // printf("Clear ints - %02X %02X\n",pic.ins,val); if ((val&0xE0)==0x60) { -// pclog("Specific EOI - %02X %i\n",pic.ins,1<<(val&7)); +// pclog("Specific EOI - %02X %i\n",pic.ins,1<<(val&7)); +#ifdef UAE + if ((pic.ins & (1 << 1)) && ((val & 7) == 1)) { + x86_ack_keyboard(); + } +#endif pic.ins&=~(1<<(val&7)); pic_update_mask(&pic.mask2, pic.ins); if (val == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2) @@ -141,6 +150,12 @@ void pic_write(uint16_t addr, uint8_t val, void *priv) if (c == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2) pic.pend |= (1 << 2); +#ifdef UAE + if (c == 1) { + x86_ack_keyboard(); + } +#endif + if (c==1 && keywaiting) { intclear&=~1; diff --git a/pcem/plat-keyboard.h b/pcem/plat-keyboard.h index ad027f99..9dbe0a84 100644 --- a/pcem/plat-keyboard.h +++ b/pcem/plat-keyboard.h @@ -1,14 +1,15 @@ #ifdef __cplusplus extern "C" { #endif - #include +#ifndef UAE +#include void keyboard_init(); void keyboard_close(); void keyboard_poll_host(); extern uint8_t pcem_key[272]; extern int rawinputkey[272]; - +#endif #ifndef __unix #define KEY_LCONTROL 0x1d #define KEY_RCONTROL (0x1d | 0x80) diff --git a/pcem/plat-mouse.h b/pcem/plat-mouse.h index e9323027..6520458c 100644 --- a/pcem/plat-mouse.h +++ b/pcem/plat-mouse.h @@ -1,6 +1,7 @@ #ifdef __cplusplus extern "C" { #endif +#ifndef UAE void mouse_init(); void mouse_close(); @@ -8,6 +9,10 @@ extern "C" { void mouse_poll_host(); void mouse_get_mickeys(int *x, int *y, int *z); extern int mousecapture; +#endif #ifdef __cplusplus } #endif +#ifdef UAE +extern int mouse_buttons; +#endif diff --git a/pcem/serial.h b/pcem/serial.h index 85ae2592..4818423f 100644 --- a/pcem/serial.h +++ b/pcem/serial.h @@ -8,9 +8,7 @@ void serial1_remove(); void serial2_remove(); void serial_reset(); -struct SERIAL; - -typedef struct +typedef struct SERIAL { uint8_t lsr,thr,mctrl,rcr,iir,ier,lcr,msr; uint8_t dlab1,dlab2; @@ -22,7 +20,7 @@ typedef struct int irq; uint16_t addr; - void (*rcr_callback)(struct SERIAL *serial, void *p); + void (*rcr_callback)(SERIAL *serial, void *p); void *rcr_callback_p; uint8_t fifo[256]; int fifo_read, fifo_write; diff --git a/pcem/sound.h b/pcem/sound.h index 9d532e9a..7c5bc984 100644 --- a/pcem/sound.h +++ b/pcem/sound.h @@ -34,4 +34,8 @@ void sound_update_buf_length(); extern int sound_gain; extern int SOUNDBUFLEN; +#ifdef UAE +#define MAXSOUNDBUFLEN 8192 +#else #define MAXSOUNDBUFLEN (48000 / 10) +#endif diff --git a/pcem/sound_cms.cpp b/pcem/sound_cms.cpp index c649a625..470227dc 100644 --- a/pcem/sound_cms.cpp +++ b/pcem/sound_cms.cpp @@ -176,7 +176,7 @@ uint8_t cms_read(uint16_t addr, void *p) void *cms_init() { - cms_t *cms = malloc(sizeof(cms_t)); + cms_t *cms = (cms_t*)malloc(sizeof(cms_t)); memset(cms, 0, sizeof(cms_t)); pclog("cms_init\n"); diff --git a/pcem/sound_dbopl.cpp b/pcem/sound_dbopl.cpp index fd9f6c7e..0af43a11 100644 --- a/pcem/sound_dbopl.cpp +++ b/pcem/sound_dbopl.cpp @@ -141,11 +141,16 @@ uint8_t opl_read(int nr, uint16_t addr) return opl[nr].is_opl3 ? 0 : 0xff; } +#ifdef UAE +static Bit32s buffer_32[8192 * 2]; +#endif + void opl2_update(int nr, int16_t *buffer, int samples) { int c; +#ifndef UAE Bit32s buffer_32[samples]; - +#endif opl[nr].chip.GenerateBlock2(samples, buffer_32); for (c = 0; c < samples; c++) @@ -155,7 +160,9 @@ void opl2_update(int nr, int16_t *buffer, int samples) void opl3_update(int nr, int16_t *buffer, int samples) { int c; +#ifndef UAE Bit32s buffer_32[samples*2]; +#endif if (opl[nr].opl_emu) { diff --git a/pcem/sound_sb.cpp b/pcem/sound_sb.cpp index 2c308c5e..961884a8 100644 --- a/pcem/sound_sb.cpp +++ b/pcem/sound_sb.cpp @@ -849,7 +849,7 @@ void *sb_1_init() 2x0 to 2x3 -> CMS chip 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip*/ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = (sb_t*)malloc(sizeof(sb_t)); uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); @@ -871,7 +871,7 @@ void *sb_15_init() 2x0 to 2x3 -> CMS chip 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip*/ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = (sb_t *)malloc(sizeof(sb_t)); uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); @@ -888,12 +888,13 @@ void *sb_15_init() return sb; } +#ifndef UAE void *sb_mcv_init() { /*sb1/2 port mappings, 210h to 260h in 10h steps 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip*/ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = (sb_t *)malloc(sizeof(sb_t)); memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); @@ -908,6 +909,8 @@ void *sb_mcv_init() sb->pos_regs[1] = 0x50; return sb; } +#endif + void *sb_2_init() { /*sb2 port mappings. 220h or 240h. @@ -923,7 +926,7 @@ void *sb_2_init() test this. It shouldn't exist on SB 1.0 as the CMS chips are always present there. Syndicate requires this mirror for music to play.*/ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = (sb_t *)malloc(sizeof(sb_t)); uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); @@ -960,7 +963,7 @@ void *sb_pro_v1_init() 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface.*/ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = (sb_t *)malloc(sizeof(sb_t)); uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); @@ -989,7 +992,7 @@ void *sb_pro_v2_init() 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface.*/ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = (sb_t *)malloc(sizeof(sb_t)); memset(sb, 0, sizeof(sb_t)); uint16_t addr = device_get_config_int("addr"); @@ -1010,6 +1013,7 @@ void *sb_pro_v2_init() return sb; } +#ifndef UAE void *sb_pro_mcv_init() { /*sbpro port mappings. 220h or 240h. @@ -1017,7 +1021,7 @@ void *sb_pro_mcv_init() 2x4 to 2x5 -> Mixer interface 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices)*/ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = (sb_t *)malloc(sizeof(sb_t)); memset(sb, 0, sizeof(sb_t)); sb->opl_emu = device_get_config_int("opl_emu"); @@ -1034,10 +1038,11 @@ void *sb_pro_mcv_init() return sb; } +#endif void *sb_16_init() { - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = (sb_t *)malloc(sizeof(sb_t)); memset(sb, 0, sizeof(sb_t)); uint16_t addr = device_get_config_int("addr"); @@ -1058,6 +1063,8 @@ void *sb_16_init() return sb; } +#ifndef UAE + int sb_awe32_available() { return rom_present("awe32.raw"); @@ -1088,6 +1095,8 @@ void *sb_awe32_init() return sb; } +#endif + void sb_close(void *p) { sb_t *sb = (sb_t *)p; @@ -1108,6 +1117,8 @@ void sb_close(void *p) free(sb); } +#ifndef UAE + void sb_awe32_close(void *p) { sb_t *sb = (sb_t *)p; @@ -1117,6 +1128,8 @@ void sb_awe32_close(void *p) sb_close(sb); } +#endif + void sb_speed_changed(void *p) { sb_t *sb = (sb_t *)p; @@ -1131,6 +1144,8 @@ void sb_add_status_info(char *s, int max_len, void *p) sb_dsp_add_status_info(s, max_len, &sb->dsp); } +#ifndef UAE + static device_config_t sb_config[] = { { @@ -1846,3 +1861,5 @@ device_t sb_awe32_device = sb_add_status_info, sb_awe32_config }; + +#endif diff --git a/pcem/sound_sb_dsp.cpp b/pcem/sound_sb_dsp.cpp index ce88db91..61626515 100644 --- a/pcem/sound_sb_dsp.cpp +++ b/pcem/sound_sb_dsp.cpp @@ -7,6 +7,9 @@ #include #include #include +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288 +#endif #include "ibm.h" @@ -16,7 +19,9 @@ #include "io.h" #include "pic.h" #include "sound.h" +#ifndef UAE #include "sound_azt2316a.h" +#endif #include "sound_sb_dsp.h" #include "timer.h" #include "x86.h" @@ -696,6 +701,7 @@ void sb_exec_command(sb_dsp_t *dsp) case 0x05: break; case 0x09: /*AZTECH mode set*/ +#ifndef UAE if (IS_AZTECH(dsp)) { if (dsp->sb_data[0] == 0x00) @@ -712,6 +718,7 @@ void sb_exec_command(sb_dsp_t *dsp) pclog("AZT2316A: UNKNOWN MODE!\n"); // sequences 0x02->0xFF, 0x04->0xFF seen } break; +#endif case 0x38: /*TODO: AZTECH MIDI-related? */ break; // default: diff --git a/pcem/timer.cpp b/pcem/timer.cpp index 565e51da..3a0ce658 100644 --- a/pcem/timer.cpp +++ b/pcem/timer.cpp @@ -88,7 +88,9 @@ static void timer_remove_head() pc_timer_t *timer = timer_head; // pclog("timer_remove_head %p %p\n", timer_head, timer_head->next); timer_head = timer->next; - timer_head->prev = NULL; + if (timer_head) { + timer_head->prev = NULL; + } timer->next = timer->prev = NULL; timer->enabled = 0; } diff --git a/pcem/vid_cl5429.cpp b/pcem/vid_cl5429.cpp index 76c54fe3..3040a80e 100644 --- a/pcem/vid_cl5429.cpp +++ b/pcem/vid_cl5429.cpp @@ -22,11 +22,15 @@ enum CL_TYPE_GD5428, CL_TYPE_GD5429, CL_TYPE_GD5430, - CL_TYPE_GD5434 + CL_TYPE_GD5434, + CL_TYPE_GD5436, + CL_TYPE_GD5446, + CL_TYPE_GD5446B }; #define BLIT_DEPTH_8 0 #define BLIT_DEPTH_16 1 +#define BLIT_DEPTH_24 2 #define BLIT_DEPTH_32 3 #define CL_GD5428_SYSTEM_BUS_MCA 5 @@ -64,7 +68,8 @@ typedef struct gd5429_t uint16_t dst_pitch, src_pitch; uint32_t dst_addr, src_addr; uint8_t mask, mode, rop; - + uint8_t status, extensions; + uint32_t dst_addr_backup, src_addr_backup; uint16_t width_backup, height_internal; int x_count, y_count; @@ -74,8 +79,32 @@ typedef struct gd5429_t uint16_t mem_word_save; } blt; + struct + { + int mode; + uint16_t stride; + uint16_t r1sz; + uint16_t r1adjust; + uint16_t r2sz; + uint16_t r2adjust; + uint16_t r2sdz; + uint16_t wvs; + uint16_t wve; + uint16_t hzoom; + uint16_t vzoom; + uint8_t occlusion; + uint8_t colorkeycomparemask; + uint8_t colorkeycompare; + int region1size; + int region2size; + int colorkeymode; + uint32_t ck; + } overlay; + uint8_t hidden_dac_reg; + int hidden_dac_index; int dac_3c6_count; + uint32_t hwcursor_pal[2]; uint8_t pci_regs[256]; uint8_t int_line; @@ -91,6 +120,9 @@ typedef struct gd5429_t uint8_t sr10_read, sr11_read; uint8_t latch_ext[4]; + + int vblank_irq; + int vportsync; int vidsys_ena; } gd5429_t; @@ -116,11 +148,349 @@ uint8_t gd5429_read_linear(uint32_t addr, void *p); static void ibm_gd5428_mapping_update(gd5429_t *gd5429); + +static int s3_vga_vsync_enabled(gd5429_t *gd5429) +{ + if (!(gd5429->svga.crtc[0x11] & 0x20) && (gd5429->svga.crtc[0x11] & 0x10) && (gd5429->type < !PCI || (gd5429->svga.gdcreg[0x17] & 4))) + return 1; + return 0; +} + +static void gd5429_update_irqs(gd5429_t *gd5429) +{ + if (gd5429->vblank_irq > 0 && s3_vga_vsync_enabled(gd5429)) + pci_set_irq(NULL, PCI_INTA); + else + pci_clear_irq(NULL, PCI_INTA); +} + +static void gd5429_vblank_start(svga_t *svga) +{ + gd5429_t *gd5429 = (gd5429_t*)svga->p; + if (gd5429->vblank_irq >= 0) { + gd5429->vblank_irq = 1; + gd5429_update_irqs(gd5429); + } +} + +#define CLAMP(x) do \ + { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } \ + while (0) + +#define DECODE_YCbCr() \ + do \ + { \ + int c; \ + \ + for (c = 0; c < 2; c++) \ + { \ + uint8_t y1, y2; \ + int8_t Cr, Cb; \ + int dR, dG, dB; \ + \ + y1 = src[0]; \ + Cr = src[1] - 0x80; \ + y2 = src[2]; \ + Cb = src[3] - 0x80; \ + src += 4; \ + \ + dR = (359*Cr) >> 8; \ + dG = (88*Cb + 183*Cr) >> 8; \ + dB = (453*Cb) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write+1] = y2 + dR; \ + CLAMP(r[x_write+1]); \ + g[x_write+1] = y2 - dG; \ + CLAMP(g[x_write+1]); \ + b[x_write+1] = y2 + dB; \ + CLAMP(b[x_write+1]); \ + \ + x_write = (x_write + 2) & 7; \ + } \ + } while (0) + +/*Both YUV formats are untested*/ +#define DECODE_YUV211() \ + do \ + { \ + uint8_t y1, y2, y3, y4; \ + int8_t U, V; \ + int dR, dG, dB; \ + \ + U = src[0] - 0x80; \ + y1 = (298 * (src[1] - 16)) >> 8; \ + y2 = (298 * (src[2] - 16)) >> 8; \ + V = src[3] - 0x80; \ + y3 = (298 * (src[4] - 16)) >> 8; \ + y4 = (298 * (src[5] - 16)) >> 8; \ + src += 6; \ + \ + dR = (309*V) >> 8; \ + dG = (100*U + 208*V) >> 8; \ + dB = (516*U) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write+1] = y2 + dR; \ + CLAMP(r[x_write+1]); \ + g[x_write+1] = y2 - dG; \ + CLAMP(g[x_write+1]); \ + b[x_write+1] = y2 + dB; \ + CLAMP(b[x_write+1]); \ + \ + r[x_write+2] = y3 + dR; \ + CLAMP(r[x_write+2]); \ + g[x_write+2] = y3 - dG; \ + CLAMP(g[x_write+2]); \ + b[x_write+2] = y3 + dB; \ + CLAMP(b[x_write+2]); \ + \ + r[x_write+3] = y4 + dR; \ + CLAMP(r[x_write+3]); \ + g[x_write+3] = y4 - dG; \ + CLAMP(g[x_write+3]); \ + b[x_write+3] = y4 + dB; \ + CLAMP(b[x_write+3]); \ + \ + x_write = (x_write + 4) & 7; \ + } while (0) + +#define DECODE_YUV422() \ + do \ + { \ + int c; \ + \ + for (c = 0; c < 2; c++) \ + { \ + uint8_t y1, y2; \ + int8_t U, V; \ + int dR, dG, dB; \ + \ + U = src[0] - 0x80; \ + y1 = (298 * (src[1] - 16)) >> 8; \ + V = src[2] - 0x80; \ + y2 = (298 * (src[3] - 16)) >> 8; \ + src += 4; \ + \ + dR = (309*V) >> 8; \ + dG = (100*U + 208*V) >> 8; \ + dB = (516*U) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write+1] = y2 + dR; \ + CLAMP(r[x_write+1]); \ + g[x_write+1] = y2 - dG; \ + CLAMP(g[x_write+1]); \ + b[x_write+1] = y2 + dB; \ + CLAMP(b[x_write+1]); \ + \ + x_write = (x_write + 2) & 7; \ + } \ + } while (0) + +#define DECODE_RGB555() \ + do \ + { \ + int c; \ + \ + for (c = 0; c < 4; c++) \ + { \ + uint16_t dat; \ + \ + dat = *(uint16_t *)src; \ + src += 2; \ + \ + r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ + g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \ + b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) + +#define DECODE_RGB565() \ + do \ + { \ + int c; \ + \ + for (c = 0; c < 4; c++) \ + { \ + uint16_t dat; \ + \ + dat = *(uint16_t *)src; \ + src += 2; \ + \ + r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ + g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \ + b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) + +#define DECODE_CLUT() \ + do \ + { \ + int c; \ + \ + for (c = 0; c < 4; c++) \ + { \ + uint8_t dat; \ + \ + dat = *(uint8_t *)src; \ + src++; \ + \ + r[x_write + c] = svga->pallook[dat] >> 0; \ + g[x_write + c] = svga->pallook[dat] >> 8; \ + b[x_write + c] = svga->pallook[dat] >> 16; \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) + + + +#define OVERLAY_SAMPLE() \ + do \ + { \ + switch (gd5429->overlay.mode) \ + { \ + case 0: \ + DECODE_YUV422(); \ + break; \ + case 2: \ + DECODE_CLUT(); \ + break; \ + case 3: \ + DECODE_YUV211(); \ + break; \ + case 4: \ + DECODE_RGB555(); \ + break; \ + case 5: \ + DECODE_RGB565(); \ + break; \ + } \ + } while (0) + + +// 5446 overlay +static void gd5429_overlay_draw(svga_t *svga, int displine) +{ + gd5429_t *gd5429 = (gd5429_t*)svga->p; + int h_acc = svga->overlay_latch.h_acc; + int r[8], g[8], b[8], ck[8]; + int x_read = 4, x_write = 4; + int x; + uint32_t *p; + uint8_t *src = &svga->vram[svga->overlay_latch.addr & svga->vram_mask]; + int bpp = svga->bpp; + int bytesperpix = (bpp + 7) / 8; + uint8_t *src2 = &svga->vram[(svga->ma - (svga->hdisp * bytesperpix)) & svga->vram_display_mask]; + int w = gd5429->overlay.r2sdz; + + if (gd5429->overlay.mode == 2) { + w *= 4; + } else { + w *= 2; + } + + p = &((uint32_t *)buffer32->line[displine])[gd5429->overlay.region1size + 32]; + src2 += gd5429->overlay.region1size * bytesperpix; + + OVERLAY_SAMPLE(); + + for (x = 0; x < gd5429->overlay.region2size && x + gd5429->overlay.region1size < svga->video_res_x; x++) + { + if (gd5429->overlay.occlusion) { + int occl = 1; + int ckval = gd5429->overlay.ck; + if (bytesperpix == 1) { + if (*src2 == ckval) { + occl = 0; + } + } else if (bytesperpix == 2) { + if (*((uint16_t*)src2) == ckval) { + occl = 0; + } + } else { + occl = 0; + } + if (!occl) { + *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); + } + src2 += bytesperpix; + } else { + *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); + } + + h_acc += gd5429->overlay.hzoom; + if (h_acc >= 256) + { + if ((x_read ^ (x_read + 1)) & ~3) + OVERLAY_SAMPLE(); + x_read = (x_read + 1) & 7; + + h_acc -= 256; + } + } + + svga->overlay_latch.v_acc += gd5429->overlay.vzoom; + if (svga->overlay_latch.v_acc >= 256) + { + svga->overlay_latch.v_acc -= 256; + svga->overlay_latch.addr += svga->overlay.pitch; + } +} + +static void gd5429_update_overlay(gd5429_t *gd5429) +{ + svga_t *svga = &gd5429->svga; + int bpp = svga->bpp; + + svga->overlay.ysize = gd5429->overlay.wve - gd5429->overlay.wvs + 1; + gd5429->overlay.region1size = 32 * gd5429->overlay.r1sz / bpp + (gd5429->overlay.r1adjust * 8 / bpp); + gd5429->overlay.region2size = 32 * gd5429->overlay.r2sz / bpp + (gd5429->overlay.r2adjust * 8 / bpp); + + gd5429->overlay.occlusion = (svga->crtc[0x3e] & 0x80) != 0 && svga->bpp <= 16; + + // mask and chroma key ignored. + if (gd5429->overlay.colorkeymode == 0) { + gd5429->overlay.ck = gd5429->overlay.colorkeycompare; + } else if (gd5429->overlay.colorkeymode == 1) { + gd5429->overlay.ck = gd5429->overlay.colorkeycompare | (gd5429->overlay.colorkeycomparemask << 8); + } else { + gd5429->overlay.occlusion = 0; + } +} + void gd5429_out(uint16_t addr, uint8_t val, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; uint8_t old; + + int hidden_dac_index = -1; + uint32_t pal_temp0; + PALETTE pal_temp1; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -177,9 +547,12 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) break; case 0x07: - svga->set_reset_disabled = svga->seqregs[7] & 1; + if (gd5429->type >= CL_TYPE_GD5429) + svga->set_reset_disabled = svga->seqregs[7] & 1; + case 0x0f: case 0x17: - if (gd5429->type >= CL_TYPE_GD5429) + //UAE + //if (gd5429->type >= CL_TYPE_GD5429) gd5429_recalc_mapping(gd5429); break; } @@ -198,9 +571,18 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) } gd5429->dac_3c6_count = 0; break; - case 0x3c7: case 0x3c8: case 0x3c9: + case 0x3c7: case 0x3c8: gd5429->dac_3c6_count = 0; break; + case 0x3c9: + gd5429->dac_3c6_count = 0; + // Hidden CLUT entries 256 - 258 + if (svga->dac_pos == 2 && (svga->seqregs[0x12] & 2)) { + hidden_dac_index = svga->dac_write; + pal_temp0 = svga->pallook[hidden_dac_index]; + memcpy(&pal_temp1, &svga->vgapal[hidden_dac_index], sizeof(PALETTE)); + } + break; case 0x3cf: // pclog("Write GDC %02x %02x\n", svga->gdcaddr, val); @@ -233,6 +615,7 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) no wrapping to detect memory size - albeit with odd/even mode enabled. This may be a quirk of address mapping. So change wrapping mode based on odd/even mode for now*/ +#if 0 if (gd5429->type == CL_TYPE_GD5426 || gd5429->type == CL_TYPE_GD5428) { if (val & 2) /*Odd/Even*/ @@ -240,7 +623,7 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) else svga->decode_mask = svga->vram_mask; } - +#endif svga->gdcreg[6] = val; return; } @@ -259,6 +642,15 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) svga->writemode = svga->gdcreg[5] & 3; break; + case 0x0c: + gd5429->overlay.colorkeycompare = val; + gd5429_update_overlay(gd5429); + break; + case 0x0d: + gd5429->overlay.colorkeycomparemask = val; + gd5429_update_overlay(gd5429); + break; + case 0x10: gd5429_mmio_write(0xb8001, val, gd5429); break; @@ -330,12 +722,16 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) gd5429_mmio_write(0xb8018, val, gd5429); break; + case 0x31: + gd5429_mmio_write(0xb8040, val, gd5429); + break; + case 0x32: gd5429_mmio_write(0xb801a, val, gd5429); break; - case 0x31: - gd5429_mmio_write(0xb8040, val, gd5429); + case 0x33: + gd5429_mmio_write(0xb801b, val, gd5429); break; case 0x34: @@ -360,7 +756,7 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) break; case 0x3D4: - svga->crtcreg = val & 0x3f; + svga->crtcreg = val & svga->crtcreg_mask; return; case 0x3D5: if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) @@ -370,8 +766,103 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; + if (svga->crtcreg == 0x11) { + if (!(val & 0x10)) + gd5429->vblank_irq = -1; + else if (gd5429->vblank_irq < 0) + gd5429->vblank_irq = 0; + gd5429_update_irqs(gd5429); + } + if (old != val) { + // overlay registers + switch (svga->crtcreg) + { + case 0x1d: + if (((old >> 3) & 7) != ((val >> 3) & 7)) { + gd5429->overlay.colorkeymode = (val >> 3) & 7; + gd5429_update_overlay(gd5429); + } + break; + case 0x31: + gd5429->overlay.hzoom = val == 0 ? 256 : val; + gd5429_update_overlay(gd5429); + break; + case 0x32: + gd5429->overlay.vzoom = val == 0 ? 256 : val; + gd5429_update_overlay(gd5429); + break; + case 0x33: + gd5429->overlay.r1sz &= ~0xff; + gd5429->overlay.r1sz |= val; + gd5429_update_overlay(gd5429); + break; + case 0x34: + gd5429->overlay.r2sz &= ~0xff; + gd5429->overlay.r2sz |= val; + gd5429_update_overlay(gd5429); + break; + case 0x35: + gd5429->overlay.r2sdz &= ~0xff; + gd5429->overlay.r2sdz |= val; + gd5429_update_overlay(gd5429); + break; + case 0x36: + gd5429->overlay.r1sz &= 0xff; + gd5429->overlay.r1sz |= (val << 8) & 0x300; + gd5429->overlay.r2sz &= 0xff; + gd5429->overlay.r2sz |= (val << 6) & 0x300; + gd5429->overlay.r2sdz &= 0xff; + gd5429->overlay.r2sdz |= (val << 4) & 0x300; + gd5429_update_overlay(gd5429); + break; + case 0x37: + gd5429->overlay.wvs &= ~0xff; + gd5429->overlay.wvs |= val; + svga->overlay.y = gd5429->overlay.wvs; + break; + case 0x38: + gd5429->overlay.wve &= ~0xff; + gd5429->overlay.wve |= val; + gd5429_update_overlay(gd5429); + break; + case 0x39: + gd5429->overlay.wvs &= 0xff; + gd5429->overlay.wvs |= (val << 8) & 0x300; + gd5429->overlay.wve &= 0xff; + gd5429->overlay.wve |= (val << 6) & 0x300; + gd5429_update_overlay(gd5429); + break; + case 0x3a: + svga->overlay.addr &= ~0xff; + svga->overlay.addr |= val; + gd5429_update_overlay(gd5429); + break; + case 0x3b: + svga->overlay.addr &= ~0xff00; + svga->overlay.addr |= val << 8; + gd5429_update_overlay(gd5429); + break; + case 0x3c: + svga->overlay.addr &= ~0x0f0000; + svga->overlay.addr |= (val << 16) & 0x0f0000; + svga->overlay.pitch &= ~(1 << 11); + svga->overlay.pitch |= ((val >> 5) & 1) << 11; + gd5429_update_overlay(gd5429); + break; + case 0x3d: + svga->overlay.pitch &= ~(0xff << 3); + svga->overlay.pitch |= val << 3; + gd5429_update_overlay(gd5429); + break; + case 0x3e: + gd5429->overlay.mode = (val >> 1) & 7; + svga->overlay.ena = (val & 1) != 0; + gd5429_update_overlay(gd5429); + break; + } + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { svga->fullchange = changeframecount; @@ -381,12 +872,24 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) break; } svga_out(addr, val, svga); + + if (hidden_dac_index >= 0) { + if ((hidden_dac_index & 15) == 0) { + gd5429->hwcursor_pal[0] = svga->pallook[hidden_dac_index]; + } else if ((hidden_dac_index & 15) == 15) { + gd5429->hwcursor_pal[1] = svga->pallook[hidden_dac_index]; + } + // restore overwritten palette entry + svga->pallook[hidden_dac_index] = pal_temp0; + memcpy(&svga->vgapal[hidden_dac_index], &pal_temp1, sizeof(PALETTE)); + } } uint8_t gd5429_in(uint16_t addr, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; + uint8_t ret; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -395,6 +898,11 @@ uint8_t gd5429_in(uint16_t addr, void *p) switch (addr) { + case 0x3c2: + ret = svga_in(addr, svga); + ret |= gd5429->vblank_irq > 0 ? 0x80 : 0x00; + return ret; + case 0x3c3: if (MCA) return gd5429->vidsys_ena; @@ -469,7 +977,11 @@ uint8_t gd5429_in(uint16_t addr, void *p) case 0x3cf: if (svga->gdcaddr > 8) { - return svga->gdcreg[svga->gdcaddr & 0x3f]; + uint8_t addr = svga->gdcaddr & 0x3f; + if (addr == 0x31) + return gd5429->blt.status; + else + return svga->gdcreg[addr]; } break; @@ -493,12 +1005,21 @@ uint8_t gd5429_in(uint16_t addr, void *p) return 0xa0; /*GD5430*/ case CL_TYPE_GD5434: return 0xa8; /*GD5434*/ + case CL_TYPE_GD5446: + case CL_TYPE_GD5446B: + return 0xb8; /*GD5446*/ } break; case 0x28: /*Class ID*/ if (gd5429->type == CL_TYPE_GD5430) return 0xff; /*Standard CL-GD5430*/ break; + case 0x3f: + // Fake video port vsync toggle + if (gd5429->type >= CL_TYPE_GD5446) { + gd5429->vportsync = !gd5429->vportsync; + } + return gd5429->vportsync ? 0x80 : 0x00; } return svga->crtc[svga->crtcreg]; } @@ -523,6 +1044,10 @@ void gd5429_recalc_banking(gd5429_t *gd5429) } else gd5429->bank[1] = gd5429->bank[0] + 0x8000; + + if (svga->seqregs[7] & 0xf0) { + gd5429_recalc_mapping(gd5429); + } } void gd5429_recalc_mapping(gd5429_t *gd5429) @@ -532,9 +1057,9 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) if ((PCI && gd5429->type >= CL_TYPE_GD5430 && !(gd5429->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) || (MCA && (!(gd5429->pos_regs[2] & 0x01) || !gd5429->vidsys_ena))) { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&gd5429->linear_mapping); - mem_mapping_disable(&gd5429->mmio_mapping); + mem_mapping_disablex(&svga->mapping); + mem_mapping_disablex(&gd5429->linear_mapping); + mem_mapping_disablex(&gd5429->mmio_mapping); return; } @@ -543,36 +1068,40 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) // pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_disable(&gd5429->linear_mapping); + mem_mapping_disablex(&gd5429->linear_mapping); switch (svga->gdcreg[6] & 0x0C) { case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; break; case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; break; case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + mem_mapping_set_addrx(&svga->mapping, 0xb0000, 0x08000); svga->banked_mask = 0x7fff; break; case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + mem_mapping_set_addrx(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; gd5429->mmio_vram_overlap = 1; break; } if (gd5429->type >= CL_TYPE_GD5429 && svga->seqregs[0x17] & 0x04) - mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); + mem_mapping_set_addrx(&gd5429->mmio_mapping, 0xb8000, 0x00100); else - mem_mapping_disable(&gd5429->mmio_mapping); + mem_mapping_disablex(&gd5429->mmio_mapping); } else { - uint32_t base, size; + uint32_t base, size, offset, max; + if (svga->gdcreg[0xb] & 0x20) + offset = (svga->gdcreg[0x09] & 0xff) << 14; + else + offset = svga->gdcreg[0x09] << 12; if (gd5429->type <= CL_TYPE_GD5429 || (!PCI && !has_vlb)) { base = (svga->seqregs[7] & 0xf0) << 16; @@ -580,23 +1109,32 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) size = 1 * 1024 * 1024; else size = 2 * 1024 * 1024; + max = 2 * 1024 * 1024; } else if (PCI) { base = gd5429->lfb_base; size = 4 * 1024 * 1024; + max = 4 * 1024 * 1024; } else /*VLB*/ { base = 128*1024*1024; size = 4 * 1024 * 1024; + max = 4 * 1024 * 1024; } - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&gd5429->linear_mapping, base, size); + if (svga->seqregs[15] & 0x80) { + svga->decode_mask = max - 1; + } else { + svga->decode_mask = max / 2 - 1; + } + base += offset; + mem_mapping_disablex(&svga->mapping); + mem_mapping_set_addrx(&gd5429->linear_mapping, base, size); if (gd5429->type >= CL_TYPE_GD5429 && svga->seqregs[0x17] & 0x04) - mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); + mem_mapping_set_addrx(&gd5429->mmio_mapping, 0xb8000, 0x00100); else - mem_mapping_disable(&gd5429->mmio_mapping); + mem_mapping_disablex(&gd5429->mmio_mapping); } } @@ -683,6 +1221,7 @@ void gd5429_recalctimings(svga_t *svga) void gd5429_hwcursor_draw(svga_t *svga, int displine) { + gd5429_t *gd5429 = (gd5429_t *)svga->p; int x; uint8_t dat[2]; int xx; @@ -703,8 +1242,8 @@ void gd5429_hwcursor_draw(svga_t *svga, int displine) if (offset >= svga->hwcursor_latch.x) { if (dat[1] & 0x80) - ((uint32_t *)buffer32->line[displine])[offset + 32] = 0; - if (dat[0] & 0x80) + ((uint32_t *)buffer32->line[displine])[offset + 32] = gd5429->hwcursor_pal[(dat[0] & 0x80) ? 1 : 0]; + else if (dat[0] & 0x80) ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; } @@ -727,8 +1266,8 @@ void gd5429_hwcursor_draw(svga_t *svga, int displine) if (offset >= svga->hwcursor_latch.x) { if (dat[1] & 0x80) - ((uint32_t *)buffer32->line[displine])[offset + 32] = 0; - if (dat[0] & 0x80) + ((uint32_t *)buffer32->line[displine])[offset + 32] = gd5429->hwcursor_pal[(dat[0] & 0x80) ? 1 : 0]; + else if (dat[0] & 0x80) ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; } @@ -834,12 +1373,15 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) uint8_t vala, valb, valc, vald, wm = svga->writemask; int writemask2 = svga->seqregs[2]; +#if 0 cycles -= video_timing_write_b; cycles_lost += video_timing_write_b; egawrites++; // if (svga_output) pclog("Write LFB %08X %02X ", addr, val); +#endif + if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) @@ -861,11 +1403,13 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) { addr <<= 2; } + addr &= svga->decode_mask; if (addr >= svga->vram_max) return; addr &= svga->vram_mask; // if (svga_output) pclog("%08X\n", addr); + svga->changedvram[addr >> 12] = changeframecount; switch (svga->writemode) @@ -1181,10 +1725,12 @@ uint8_t gd5429_read_linear(uint32_t addr, void *p) int readplane = svga->readplane; uint32_t latch_addr; +#if 0 cycles -= video_timing_read_b; cycles_lost += video_timing_read_b; egareads++; +#endif if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) latch_addr = (addr << 3) & svga->decode_mask; @@ -1209,7 +1755,7 @@ uint8_t gd5429_read_linear(uint32_t addr, void *p) else addr<<=2; - addr &= svga->decode_mask; +// addr &= svga->decode_mask; if (latch_addr >= svga->vram_max) { @@ -1233,10 +1779,12 @@ uint8_t gd5429_read_linear(uint32_t addr, void *p) } } +#if 0 if (addr >= svga->vram_max) return 0xff; addr &= svga->vram_mask; +#endif if (svga->readmode) { @@ -1332,6 +1880,8 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; int blt_mask = gd5429->blt.mask & 7; + int fg_col = gd5429->blt.fg_col; + int bg_col = gd5429->blt.bg_col; int x_max = 0; switch (gd5429->blt.depth) @@ -1343,6 +1893,10 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) x_max = 16; blt_mask *= 2; break; + case BLIT_DEPTH_24: + x_max = 24; + blt_mask *= 3; + break; case BLIT_DEPTH_32: x_max = 32; blt_mask *= 4; @@ -1352,6 +1906,12 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) // pclog("gd5429_start_blit %i\n", count); if (count == -1) { + if (gd5429->blt.status & 4) + gd5429->blt.status &= ~(8 | 2 | 1); + if (!(gd5429->blt.status & 2)) + return; + gd5429->blt.status |= 8 | 1; + gd5429->blt.dst_addr_backup = gd5429->blt.dst_addr; gd5429->blt.src_addr_backup = gd5429->blt.src_addr; gd5429->blt.width_backup = gd5429->blt.width; @@ -1361,20 +1921,21 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429->blt.y_count = gd5429->blt.src_addr & 7; else gd5429->blt.y_count = 0; -// pclog("gd5429_start_blit : size %i, %i %i\n", gd5429->blt.width, gd5429->blt.height, gd5429->blt.x_count); - +// pclog("gd5429_start_blit : size %i, %i %i %02x %02x %02x %02x\n", +// gd5429->blt.width, gd5429->blt.height, gd5429->blt.x_count, gd5429->blt.rop, gd5429->blt.mode, gd5429->blt.extensions, gd5429->blt.mask); + if (gd5429->blt.mode & 0x04) { // pclog("blt.mode & 0x04\n"); if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_set_handler(&svga->mapping, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l); - mem_mapping_set_p(&svga->mapping, gd5429); + mem_mapping_set_handlerx(&svga->mapping, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l); + mem_mapping_set_px(&svga->mapping, gd5429); } else { - mem_mapping_set_handler(&gd5429->linear_mapping, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l); - mem_mapping_set_p(&gd5429->linear_mapping, gd5429); + mem_mapping_set_handlerx(&gd5429->linear_mapping, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l); + mem_mapping_set_px(&gd5429->linear_mapping, gd5429); } gd5429_recalc_mapping(gd5429); return; @@ -1382,14 +1943,16 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) else { if (!(svga->seqregs[7] & 0xf0)) - mem_mapping_set_handler(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); + mem_mapping_set_handlerx(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); else - mem_mapping_set_handler(&gd5429->linear_mapping, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear); + mem_mapping_set_handlerx(&gd5429->linear_mapping, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear); gd5429_recalc_mapping(gd5429); } } - else if (gd5429->blt.height_internal == 0xffff) - return; + else if (gd5429->blt.height_internal == 0xffff) { + gd5429->blt.status &= 0x80; + return; + } while (count) { @@ -1399,6 +1962,8 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) if (gd5429->blt.depth == BLIT_DEPTH_32) shift = (gd5429->blt.x_count & 3) * 8; + else if (gd5429->blt.depth == BLIT_DEPTH_24) + shift = (gd5429->blt.x_count % 3) * 8; else if (gd5429->blt.depth == BLIT_DEPTH_8) shift = 0; else @@ -1413,20 +1978,28 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) switch (gd5429->blt.depth) { case BLIT_DEPTH_8: - src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + src = mask ? fg_col : bg_col; cpu_dat <<= 1; count--; break; case BLIT_DEPTH_16: - src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + src = mask ? (fg_col >> shift) : (bg_col >> shift); if (gd5429->blt.x_count & 1) { cpu_dat <<= 1; count--; } break; + case BLIT_DEPTH_24: + src = mask ? (fg_col >> shift) : (bg_col >> shift); + if ((gd5429->blt.x_count % 3) == 2) + { + cpu_dat <<= 1; + count--; + } + break; case BLIT_DEPTH_32: - src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + src = mask ? (fg_col >> shift) : (bg_col >> shift); if ((gd5429->blt.x_count & 3) == 3) { cpu_dat <<= 1; @@ -1461,6 +2034,9 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) case BLIT_DEPTH_16: src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~3)) + (gd5429->blt.y_count << 4) + (gd5429->blt.x_count & 15)]; break; + case BLIT_DEPTH_24: + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~3)) + (gd5429->blt.y_count << 5) + (gd5429->blt.x_count & 31)]; + break; case BLIT_DEPTH_32: src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~3)) + (gd5429->blt.y_count << 5) + (gd5429->blt.x_count & 31)]; break; @@ -1468,38 +2044,66 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) mask = 1; break; case 0x80: - switch (gd5429->blt.depth) - { + if (gd5429->blt.extensions & 4) { + // Solid color fill + src = fg_col >> shift; + mask = 1; + } else { + switch (gd5429->blt.depth) + { case BLIT_DEPTH_8: - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); - src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; - break; + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); + if (gd5429->blt.extensions & 2) + mask = mask == 0; + src = mask ? fg_col : bg_col; + break; case BLIT_DEPTH_16: - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 1)); - src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); - break; + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 1)); + if (gd5429->blt.extensions & 2) + mask = mask == 0; + src = mask ? (fg_col >> shift) : (bg_col >> shift); + break; + case BLIT_DEPTH_24: + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count / 3)); + if (gd5429->blt.extensions & 2) + mask = mask == 0; + src = mask ? (fg_col >> shift) : (bg_col >> shift); + break; case BLIT_DEPTH_32: - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 2)); - src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); - break; - } + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 2)); + if (gd5429->blt.extensions & 2) + mask = mask == 0; + src = mask ? (fg_col >> shift) : (bg_col >> shift); + break; + } + } break; - case 0xc0: - switch (gd5429->blt.depth) - { + case 0xc0: + if (gd5429->blt.extensions & 4) { + // Solid color fill + src = fg_col >> shift; + mask = 1; + } else { + switch (gd5429->blt.depth) + { case BLIT_DEPTH_8: - mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> gd5429->blt.x_count); - src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; - break; + mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> gd5429->blt.x_count); + src = mask ? fg_col : bg_col; + break; case BLIT_DEPTH_16: - mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 1)); - src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); - break; + mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 1)); + src = mask ? (fg_col >> shift) : (bg_col >> shift); + break; + case BLIT_DEPTH_24: + mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count / 3)); + src = mask ? (fg_col >> shift) : (bg_col >> shift); + break; case BLIT_DEPTH_32: - mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 2)); - src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); - break; - } + mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 2)); + src = mask ? (fg_col >> shift) : (bg_col >> shift); + break; + } + } break; } count--; @@ -1507,7 +2111,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) dst = svga->vram[gd5429->blt.dst_addr & svga->vram_mask]; svga->changedvram[(gd5429->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount; -// pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst); + //pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X\n", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst); switch (gd5429->blt.rop) { case 0x00: dst = 0; break; @@ -1525,14 +2129,13 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) case 0xad: dst = src | ~dst; break; case 0xd0: dst = ~src; break; case 0xd6: dst = ~src | dst; break; - case 0xda: dst = ~(src & dst); break; + case 0xda: dst = ~(src & dst); break; } - //pclog("%02X %02X\n", dst, mask); - - if (gd5429->type <= CL_TYPE_GD5428) + + if (0 && gd5429->type <= CL_TYPE_GD5428) { if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && - (!(gd5429->blt.mode & 0x08) || (dst & gd5429->blt.trans_mask) != gd5429->blt.trans_col)) + (!(gd5429->blt.mode & 0x08) || (dst & ~gd5429->blt.trans_mask) != (gd5429->blt.trans_col & ~gd5429->blt.trans_mask))) svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; } else @@ -1583,13 +2186,14 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) if (gd5429->blt.mode & 0x04) { if (!(svga->seqregs[7] & 0xf0)) - mem_mapping_set_handler(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); + mem_mapping_set_handlerx(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); else - mem_mapping_set_handler(&gd5429->linear_mapping, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear); -// 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_set_handlerx(&gd5429->linear_mapping, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear); +// mem_mapping_set_handlerx(&gd5429->svga.mapping, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL); +// mem_mapping_set_px(&gd5429->svga.mapping, gd5429); gd5429_recalc_mapping(gd5429); } + gd5429->blt.status &= 0x80; return; } @@ -1665,7 +2269,10 @@ static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) break; case 0x0b: gd5429->blt.height = (gd5429->blt.height & 0x00ff) | (val << 8); - gd5429->blt.height &= 0x03ff; + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.height &= 0x07ff; + else + gd5429->blt.height &= 0x03ff; break; case 0x0c: gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0xff00) | val; @@ -1692,6 +2299,10 @@ static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) gd5429->blt.dst_addr &= 0x3fffff; else gd5429->blt.dst_addr &= 0x1fffff; + if (gd5429->blt.status & 0x80) { + gd5429->blt.status |= 2; + gd5429_start_blit(0, -1, gd5429); + } break; case 0x14: @@ -1722,10 +2333,23 @@ static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) case 0x1a: gd5429->blt.rop = val; break; - + + case 0x1b: // blt mode extensions + if (gd5429->type >= CL_TYPE_GD5436) { + gd5429->blt.extensions = val & 7; + } + break; + + case 0x1c: // transparent blt key color byte 0 + case 0x1d: // transparent blt key color byte 0 + break; + case 0x40: - if (val & 0x02) - gd5429_start_blit(0, -1, gd5429); + gd5429->blt.status &= ~(2 | 4 | 0x80); + if (gd5429->type < CL_TYPE_GD5436) + val &= 0x7f; + gd5429->blt.status |= val & (2 | 4 | 0x80); + gd5429_start_blit(0, -1, gd5429); break; } } @@ -1767,7 +2391,7 @@ static uint8_t gd5429_mmio_read(uint32_t addr, void *p) switch (addr & 0xff) { case 0x40: /*BLT status*/ - return 0; + return gd5429->blt.status; } return 0xff; /*All other registers read-only*/ } @@ -1801,10 +2425,20 @@ void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p) gd5429_t *gd5429 = (gd5429_t *)p; // pclog("gd5429_blt_write_w %08X %08X\n", addr, val); - if (!gd5429->blt.mem_word_sel) - gd5429->blt.mem_word_save = val; - else - gd5429_start_blit(gd5429->blt.mem_word_save | (val << 16), 32, p); + if (!gd5429->blt.mem_word_sel) { + gd5429->blt.mem_word_save = val; + } else { + uint32_t v = gd5429->blt.mem_word_save | (val << 16); + if ((gd5429->blt.mode & 0x84) == 0x84) + { + gd5429_start_blit(v & 0xff, 8, p); + gd5429_start_blit((v >> 8) & 0xff, 8, p); + gd5429_start_blit((v >> 16) & 0xff, 8, p); + gd5429_start_blit((v >> 24) & 0xff, 8, p); + } else { + gd5429_start_blit(v, 32, p); + } + } gd5429->blt.mem_word_sel = !gd5429->blt.mem_word_sel; } @@ -1844,10 +2478,10 @@ static void ibm_gd5428_mapping_update(gd5429_t *gd5429) if ((gd5429->pos_regs[2] & 0x01) && gd5429->vidsys_ena) { // pclog(" GD5429 enable registers\n"); - io_sethandler(0x03c0, 0x0003, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - io_sethandler(0x03c4, 0x001c, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandlerx(0x03c0, 0x0003, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandlerx(0x03c4, 0x001c, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); if (!(gd5429->svga.miscout & 1)) - io_sethandler(0x03a0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandlerx(0x03a0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); gd5429->svga.override = 0; if (mb_vga) svga_set_override(mb_vga, 1); @@ -1874,13 +2508,13 @@ void ibm_gd5428_mca_write(int port, uint8_t val, void *p) if ((port & 7) == 2) { - mem_mapping_disable(&gd5429->bios_rom.mapping); + mem_mapping_disablex(&gd5429->bios_rom.mapping); io_removehandler(0x03c3, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); if (gd5429->pos_regs[2] & 0x01) { // pclog("Enable BIOS mapping\n"); mem_mapping_enable(&gd5429->bios_rom.mapping); - io_sethandler(0x03c3, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandlerx(0x03c3, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); } // else // pclog("Disable BIOS mapping\n"); @@ -1915,6 +2549,9 @@ static uint8_t cl_pci_read(int func, int addr, void *p) return 0xa0; case CL_TYPE_GD5434: return 0xa8; + case CL_TYPE_GD5446: + case CL_TYPE_GD5446B: + return 0xb8; } return 0xff; case 0x03: return 0x00; @@ -1957,12 +2594,14 @@ static void cl_pci_write(int func, int addr, uint8_t val, void *p) gd5429->pci_regs[PCI_REG_COMMAND] = val & 0x23; io_removehandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); if (val & PCI_COMMAND_IO) - io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandlerx(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); gd5429_recalc_mapping(gd5429); break; case 0x13: gd5429->lfb_base = val << 24; + if (gd5429->type == CL_TYPE_GD5446B) + gd5429->lfb_base &= 0xfe000000; gd5429_recalc_mapping(gd5429); break; @@ -1971,10 +2610,10 @@ static void cl_pci_write(int func, int addr, uint8_t val, void *p) if (gd5429->pci_regs[0x30] & 0x01) { uint32_t addr = (gd5429->pci_regs[0x32] << 16) | (gd5429->pci_regs[0x33] << 24); - mem_mapping_set_addr(&gd5429->bios_rom.mapping, addr, 0x8000); + mem_mapping_set_addrx(&gd5429->bios_rom.mapping, addr, 0x8000); } else - mem_mapping_disable(&gd5429->bios_rom.mapping); + mem_mapping_disablex(&gd5429->bios_rom.mapping); return; case 0x3c: @@ -1985,7 +2624,7 @@ static void cl_pci_write(int func, int addr, uint8_t val, void *p) static void *cl_init(int type, char *fn, int pci_card, uint32_t force_vram_size) { - gd5429_t *gd5429 = malloc(sizeof(gd5429_t)); + gd5429_t *gd5429 = (gd5429_t*)malloc(sizeof(gd5429_t)); svga_t *svga = &gd5429->svga; int vram_size; memset(gd5429, 0, sizeof(gd5429_t)); @@ -2008,24 +2647,28 @@ static void *cl_init(int type, char *fn, int pci_card, uint32_t force_vram_size) gd5429_recalctimings, gd5429_in, gd5429_out, gd5429_hwcursor_draw, - NULL); + gd5429_overlay_draw); + + gd5429->svga.vblank_start = gd5429_vblank_start; - mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); - mem_mapping_set_p(&gd5429->svga.mapping, gd5429); + mem_mapping_set_handlerx(&gd5429->svga.mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); + mem_mapping_set_px(&gd5429->svga.mapping, gd5429); - mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, gd5429_mmio_readw, gd5429_mmio_readl, gd5429_mmio_write, gd5429_mmio_writew, gd5429_mmio_writel, NULL, 0, gd5429); - mem_mapping_add(&gd5429->linear_mapping, 0, 0, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, gd5429); + mem_mapping_addx(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, gd5429_mmio_readw, gd5429_mmio_readl, gd5429_mmio_write, gd5429_mmio_writew, gd5429_mmio_writel, NULL, 0, gd5429); + mem_mapping_addx(&gd5429->linear_mapping, 0, 0, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, gd5429); - io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandlerx(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); if (type == CL_TYPE_AVGA2) { - io_sethandler(0x0102, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - io_sethandler(0x46e8, 0x0002, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandlerx(0x0102, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandlerx(0x46e8, 0x0002, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); svga->decode_mask = svga->vram_mask; } svga->hwcursor.yoff = 32; svga->hwcursor.xoff = 0; + gd5429->hidden_dac_index = -1; + gd5429->overlay.colorkeycompare = 0xff; gd5429->bank[1] = 0x8000; @@ -2039,6 +2682,10 @@ static void *cl_init(int type, char *fn, int pci_card, uint32_t force_vram_size) svga->seqregs[0x1d] = 0x30; svga->seqregs[0x1e] = 0x33; + if (type >= CL_TYPE_GD5446) { + svga->crtcreg_mask = 0x7f; + } + if (PCI && type >= CL_TYPE_GD5430) { if (pci_card != -1) @@ -2055,6 +2702,8 @@ static void *cl_init(int type, char *fn, int pci_card, uint32_t force_vram_size) gd5429->pci_regs[0x32] = 0x0c; gd5429->pci_regs[0x33] = 0x00; } + + gd5429->svga.fb_only = -1; return gd5429; } @@ -2072,16 +2721,32 @@ static void *gd5426_ps1_init() { return cl_init(CL_TYPE_GD5426, NULL, -1, 1); } +static void *gd5426_init() +{ + return cl_init(CL_TYPE_GD5426, "Picasso II", -1, 0); +} +static void *gd5426_swapped_init() +{ + gd5429_t *gd5429 = (gd5429_t*)cl_init(CL_TYPE_GD5426, "Picasso II", -1, 0); + gd5429->svga.swaprb = 1; + return gd5429; +} static void *gd5428_init() { - return cl_init(CL_TYPE_GD5428, "Machspeed_VGA_GUI_2100_VLB.vbi", -1, 0); + return cl_init(CL_TYPE_GD5428, "Machspeed_VGA_GUI_2100_VLB.vbi", -1, 0); +} +static void *gd5428_swapped_init() +{ + gd5429_t *gd5429 = (gd5429_t *)cl_init(CL_TYPE_GD5428, "Picasso II", -1, 0); + gd5429->svga.swaprb = 1; + return gd5429; } static void *ibm_gd5428_init() { gd5429_t *gd5429; svga_t *mb_vga = svga_get_pri(); - gd5429 = cl_init(CL_TYPE_GD5428, "SVGA141.ROM", -1, 1); /*Only supports 1MB*/ + gd5429 = (gd5429_t*)cl_init(CL_TYPE_GD5428, "SVGA141.ROM", -1, 1); /*Only supports 1MB*/ gd5429->mb_vga = mb_vga; mca_add(ibm_gd5428_mca_read, ibm_gd5428_mca_write, ibm_gd5428_mca_reset, gd5429); @@ -2092,8 +2757,8 @@ static void *ibm_gd5428_init() gd5429_recalc_mapping(gd5429); io_removehandler(0x03a0, 0x0040, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); gd5429->svga.override = 1; - mem_mapping_disable(&gd5429->bios_rom.mapping); - io_sethandler(0x46e8, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + mem_mapping_disablex(&gd5429->bios_rom.mapping); + io_sethandlerx(0x46e8, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); return gd5429; } @@ -2113,6 +2778,21 @@ static void *gd5434_init() { return cl_init(CL_TYPE_GD5434, "gd5434.bin", -1, 0); } +static void *gd5434_vlb_swapped_init() +{ + gd5429_t *gd5429 = (gd5429_t *)cl_init(CL_TYPE_GD5434, "PicccoSD64", -1, 0); + has_vlb = 1; + gd5429->svga.swaprb = 1; + return gd5429; +} +static void *gd5446_init() +{ + PCI = 1; + gd5429_t *gd5429 = (gd5429_t *)cl_init(CL_TYPE_GD5446, "gd5446.bin", -1, 0); + gd5429->int_line = 1; + return gd5429; +} + static void *gd5434_pb520r_init() { return cl_init(CL_TYPE_GD5434, "pb520r/gd5434.bin", 3, 0); @@ -2179,6 +2859,7 @@ static device_config_t avga2_config[] = .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, + .default_int = 512, .selection = { { @@ -2193,7 +2874,6 @@ static device_config_t avga2_config[] = .description = "" } }, - .default_int = 512 }, { .type = -1 @@ -2206,6 +2886,7 @@ static device_config_t gd5429_config[] = .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, + .default_int = 2, .selection = { { @@ -2220,7 +2901,6 @@ static device_config_t gd5429_config[] = .description = "" } }, - .default_int = 2 }, { .type = -1 @@ -2232,6 +2912,7 @@ static device_config_t gd5434_config[] = .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, + .default_int = 4, .selection = { { @@ -2246,7 +2927,6 @@ static device_config_t gd5434_config[] = .description = "" } }, - .default_int = 4 }, { .type = -1 @@ -2292,6 +2972,32 @@ device_t gd5426_ps1_device = NULL }; +device_t gd5426_device = +{ + "Cirrus Logic GD5426", + 0, + gd5426_init, + gd5429_close, + gd5428_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5429_config +}; + +device_t gd5426_swapped_device = +{ + "Cirrus Logic GD5426", + 0, + gd5426_swapped_init, + gd5429_close, + gd5428_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5429_config +}; + device_t gd5428_device = { "Cirrus Logic GD5428", @@ -2305,6 +3011,20 @@ device_t gd5428_device = gd5429_config }; +device_t gd5428_swapped_device = +{ + "Cirrus Logic GD5428", + 0, + gd5428_swapped_init, + gd5429_close, + gd5428_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5429_config +}; + + device_t ibm_gd5428_device = { "IBM 1MB SVGA Adapter/A (Cirrus Logic GD5428)", @@ -2370,6 +3090,19 @@ device_t gd5434_device = gd5434_config }; +device_t gd5434_vlb_swapped_device = +{ + "Cirrus Logic GD5434", + 0, + gd5434_vlb_swapped_init, + gd5429_close, + gd5434_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5434_config +}; + device_t gd5434_pb520r_device = { "Cirrus Logic GD5434 (PB520r)", @@ -2382,3 +3115,16 @@ device_t gd5434_pb520r_device = gd5429_add_status_info, gd5434_config }; + +device_t gd5446_device = +{ + "Cirrus Logic GD5446", + 0, + gd5446_init, + gd5429_close, + gd5434_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5434_config +}; \ No newline at end of file diff --git a/pcem/vid_cl5429.h b/pcem/vid_cl5429.h index 70b03215..0997b607 100644 --- a/pcem/vid_cl5429.h +++ b/pcem/vid_cl5429.h @@ -2,6 +2,11 @@ extern device_t avga2_device; extern device_t avga2_cbm_sl386sx_device; extern device_t gd5426_ps1_device; extern device_t gd5428_device; +extern device_t gd5426_device; +extern device_t gd5428_swapped_device; +extern device_t gd5426_swapped_device; +extern device_t gd5434_vlb_swapped_device; +extern device_t gd5446_device; extern device_t ibm_gd5428_device; extern device_t gd5429_device; extern device_t gd5429_reply_m25_device; diff --git a/pcem/vid_s3.cpp b/pcem/vid_s3.cpp index 338b39a9..490a73b7 100644 --- a/pcem/vid_s3.cpp +++ b/pcem/vid_s3.cpp @@ -146,7 +146,7 @@ typedef struct s3_t uint32_t hwc_fg_col, hwc_bg_col; int hwc_col_stack_pos; - + volatile int force_busy; } s3_t; @@ -156,7 +156,7 @@ typedef struct s3_t #define INT_FIFO_EMP (1 << 3) #define INT_MASK 0xf -void s3_updatemapping(); +void s3_updatemapping(s3_t*); void s3_accel_write(uint32_t addr, uint8_t val, void *p); void s3_accel_write_w(uint32_t addr, uint16_t val, void *p); @@ -177,12 +177,24 @@ static void s3_wait_fifo_idle(s3_t *s3) } } +static int s3_vga_vsync_enabled(s3_t *s3) +{ + if (!(s3->svga.crtc[0x11] & 0x20) && (s3->svga.crtc[0x11] & 0x10) && (s3->svga.crtc[0x32] & 0x10)) + return 1; + return 0; +} + static void s3_update_irqs(s3_t *s3) { - if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) + int enabled = s3_vga_vsync_enabled(s3); + if ((s3->subsys_cntl & s3->subsys_stat & INT_MASK) || (enabled && (s3->subsys_stat & INT_VSY))) pci_set_irq(s3->card, PCI_INTA); else pci_clear_irq(s3->card, PCI_INTA); + + if ((s3->subsys_stat & INT_VSY) && !(s3->subsys_stat & INT_VSY) && !enabled) { + s3->subsys_stat &= ~INT_VSY; + } } void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); @@ -525,9 +537,11 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xbee8: + case 0xbeea: s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff00) | val; break; case 0xbee9: + case 0xbeeb: s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8); s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; break; @@ -920,9 +934,10 @@ static void fifo_thread(void *param) static void s3_vblank_start(svga_t *svga) { s3_t *s3 = (s3_t *)svga->p; - - s3->subsys_stat |= INT_VSY; - s3_update_irqs(s3); + if ((s3->subsys_cntl & INT_VSY) || s3_vga_vsync_enabled(s3)) { + s3->subsys_stat |= INT_VSY; + s3_update_irqs(s3); + } } static void s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) @@ -1004,11 +1019,18 @@ void s3_out(uint16_t addr, uint8_t val, void *p) svga->crtc[svga->crtcreg] = val; switch (svga->crtcreg) { + case 0x11: + if (!(val & 0x10)) + s3->subsys_stat &= ~INT_VSY; + s3_update_irqs(s3); + break; + case 0x31: s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); break; case 0x32: svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; + s3_update_irqs(s3); break; case 0x50: @@ -1135,6 +1157,7 @@ uint8_t s3_in(uint16_t addr, void *p) { s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; + uint8_t ret; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -1147,6 +1170,12 @@ uint8_t s3_in(uint16_t addr, void *p) return 0xff; break; + /* UAE UPDATE */ + case 0x3c2: + ret = svga_in(addr, svga); + ret |= (s3->subsys_stat & INT_VSY) ? 0x80 : 0x00; + return ret; + case 0x3c5: if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) return svga->seqregs[svga->seqaddr]; @@ -1210,7 +1239,7 @@ void s3_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; - svga->clock = (cpuclock * (float)(1ull << 32)) / s3->getclock(clk_sel, s3->getclock_p); + //svga->clock = (cpuclock * (float)(1ull << 32)) / s3->getclock(clk_sel, s3->getclock_p); switch (svga->crtc[0x67] >> 4) { @@ -1257,9 +1286,9 @@ void s3_updatemapping(s3_t *s3) 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); + mem_mapping_disablex(&svga->mapping); + mem_mapping_disablex(&s3->linear_mapping); + mem_mapping_disablex(&s3->mmio_mapping); return; } @@ -1268,25 +1297,25 @@ void s3_updatemapping(s3_t *s3) if (svga->crtc[0x31] & 0x08) /*Enhanced mode mappings*/ { /*Enhanced mapping forces 64kb at 0xa0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; } else switch (svga->gdcreg[6] & 0xc) /*VGA mapping*/ { case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; break; case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; break; case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + mem_mapping_set_addrx(&svga->mapping, 0xb0000, 0x08000); svga->banked_mask = 0x7fff; break; case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + mem_mapping_set_addrx(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; } @@ -1294,7 +1323,7 @@ void s3_updatemapping(s3_t *s3) // pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ { - mem_mapping_disable(&svga->mapping); + mem_mapping_disablex(&svga->mapping); s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); switch (svga->crtc[0x58] & 3) @@ -1317,28 +1346,28 @@ void s3_updatemapping(s3_t *s3) // pclog("Linear framebuffer at %08X size %08X\n", s3->linear_base, s3->linear_size); if (s3->linear_base == 0xa0000) { - mem_mapping_disable(&s3->linear_mapping); + mem_mapping_disablex(&s3->linear_mapping); if (!(svga->crtc[0x53] & 0x10)) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; } -// mem_mapping_set_addr(&s3->linear_mapping, 0xa0000, 0x10000); +// mem_mapping_set_addrx(&s3->linear_mapping, 0xa0000, 0x10000); } else - mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); + mem_mapping_set_addrx(&s3->linear_mapping, s3->linear_base, s3->linear_size); } else - mem_mapping_disable(&s3->linear_mapping); + mem_mapping_disablex(&s3->linear_mapping); // 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); + mem_mapping_disablex(&svga->mapping); + mem_mapping_enablex(&s3->mmio_mapping); } else - mem_mapping_disable(&s3->mmio_mapping); + mem_mapping_disablex(&s3->mmio_mapping); } static float s3_trio64_getclock(int clock, void *p) @@ -1729,7 +1758,13 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if ((s3->chip == S3_TRIO64) && (s3->accel.cmd & (1 << 11))) cmd |= 8; - + + // Amiga CGX4 driver sets all clipping values to FFF. + if (clip_t == 0xfff) + clip_t = 0; + if (clip_l == 0xfff) + clip_l = 0; + s3->force_busy = 1; //return; // if (!cpu_input) pclog("Start S3 command %i %i, %i %i, %i (clip %i, %i to %i, %i %i)\n", s3->accel.cmd >> 13, s3->accel.cur_x, s3->accel.cur_y, s3->accel.maj_axis_pcnt & 0xfff, s3->accel.multifunc[0] & 0xfff, clip_l, clip_t, clip_r, clip_b, s3->accel.multifunc[0xe] & 0x20); @@ -2522,68 +2557,67 @@ void s3_hwcursor_draw(svga_t *svga, int displine) static void s3_io_remove(s3_t *s3) { - io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); + io_removehandlerx(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - 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, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xb2e8, 0x0004, 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); + io_removehandlerx(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandlerx(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); } 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); + io_sethandlerx(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); if (s3->chip == S3_TRIO64) { - io_sethandler(0x82e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x86e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x82e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x86e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x8ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); } else { - io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); } - io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_sethandlerx(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandlerx(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); } @@ -2658,12 +2692,12 @@ void s3_pci_write(int func, int addr, uint8_t val, void *p) { 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); + mem_mapping_set_addrx(&s3->bios_rom.mapping, addr, 0x8000); } else { // pclog("S3 bios_rom disabled\n"); - mem_mapping_disable(&s3->bios_rom.mapping); + mem_mapping_disablex(&s3->bios_rom.mapping); } return; @@ -2688,7 +2722,7 @@ static int vram_sizes[] = static void *s3_init(char *bios_fn, int chip) { - s3_t *s3 = malloc(sizeof(s3_t)); + s3_t *s3 = (s3_t*)malloc(sizeof(s3_t)); svga_t *svga = &s3->svga; int vram; uint32_t vram_size; @@ -2704,11 +2738,11 @@ static void *s3_init(char *bios_fn, int chip) 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_disablex(&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, MEM_MAPPING_EXTERNAL, &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, MEM_MAPPING_EXTERNAL, s3); - mem_mapping_disable(&s3->mmio_mapping); + mem_mapping_addx(&s3->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &s3->svga); + mem_mapping_addx(&s3->mmio_mapping, 0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, NULL, MEM_MAPPING_EXTERNAL, s3); + mem_mapping_disablex(&s3->mmio_mapping); svga_init(&s3->svga, s3, vram_size, /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/ s3_recalctimings, @@ -2770,6 +2804,7 @@ static void *s3_init(char *bios_fn, int chip) return s3; } +#ifndef UAE void *s3_bahamas64_init() { s3_t *s3 = s3_init("bahamas64.bin", S3_VISION864); @@ -2850,6 +2885,22 @@ int s3_phoenix_trio64_available() return rom_present("86c764x1.bin"); } +#endif + +void *s3_cybervision_init() +{ + s3_t *s3 = (s3_t*)s3_init("86c764x1.bin", S3_TRIO64); + + s3->id = 0xe1; /*Trio64*/ + s3->packed_mmio = 1; + + s3->getclock = s3_trio64_getclock; + s3->getclock_p = s3; + s3->svga.fb_only = -1; + + return s3; +} + void s3_close(void *p) { s3_t *s3 = (s3_t *)p; @@ -2895,6 +2946,8 @@ void s3_add_status_info(char *s, int max_len, void *p) s3->blitter_time = 0; } +#ifndef UAE + static device_config_t s3_bahamas64_config[] = { { @@ -3067,3 +3120,20 @@ device_t s3_phoenix_trio64_device = s3_add_status_info, s3_phoenix_trio64_config }; + +#else + +device_t s3_cybervision_trio64_device = +{ + "CyberVision64", + 0, + s3_cybervision_init, + s3_close, + NULL, + s3_speed_changed, + s3_force_redraw, + s3_add_status_info, + NULL +}; + +#endif diff --git a/pcem/vid_s3.h b/pcem/vid_s3.h index ee040396..aa453fa1 100644 --- a/pcem/vid_s3.h +++ b/pcem/vid_s3.h @@ -1,4 +1,5 @@ -device_t s3_bahamas64_device; -device_t s3_9fx_device; -device_t s3_phoenix_trio32_device; -device_t s3_phoenix_trio64_device; +extern device_t s3_bahamas64_device; +extern device_t s3_9fx_device; +extern device_t s3_phoenix_trio32_device; +extern device_t s3_phoenix_trio64_device; +extern device_t s3_cybervision_trio64_device; diff --git a/pcem/vid_s3_virge.cpp b/pcem/vid_s3_virge.cpp index 33e85fd7..b1cb60aa 100644 --- a/pcem/vid_s3_virge.cpp +++ b/pcem/vid_s3_virge.cpp @@ -488,7 +488,12 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) ret = 0xff; else ret = svga_in(addr, svga); - break; + break; + /* UAE UPDATE */ + case 0x3c2: + ret = svga_in(addr, svga); + ret |= (virge->subsys_stat & INT_VSY) ? 0x80 : 0x00; + break; //case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: // pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); //return sdac_ramdac_in(addr); @@ -536,6 +541,9 @@ static void s3_virge_recalctimings(svga_t *svga) { virge_t *virge = (virge_t *)svga->p; + svga->hdisp = svga->crtc[1]; + svga->hdisp++; + if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; if (svga->crtc[0x5d] & 0x02) svga->hdisp += 0x100; if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400; @@ -545,6 +553,26 @@ static void s3_virge_recalctimings(svga_t *svga) if (svga->crtc[0x5e] & 0x40) svga->split += 0x400; svga->interlace = svga->crtc[0x42] & 0x20; + if (!svga->scrblank) // && svga->attr_palette_enable) + { + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ + { + if (svga->seqregs[1] & 8) /*40 column*/ + { + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + } else + { + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + } + svga->hdisp_old = svga->hdisp; + } else + { + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->hdisp_old = svga->hdisp; + } + } + + if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ { svga->ma_latch |= (virge->ma_ext << 16); @@ -654,10 +682,10 @@ static void s3_virge_updatemapping(virge_t *virge) 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); + mem_mapping_disablex(&svga->mapping); + mem_mapping_disablex(&virge->linear_mapping); + mem_mapping_disablex(&virge->mmio_mapping); + mem_mapping_disablex(&virge->new_mmio_mapping); return; } @@ -665,19 +693,19 @@ static void s3_virge_updatemapping(virge_t *virge) switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ { case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; break; case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; break; case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + mem_mapping_set_addrx(&svga->mapping, 0xb0000, 0x08000); svga->banked_mask = 0x7fff; break; case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + mem_mapping_set_addrx(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; } @@ -707,34 +735,36 @@ static void s3_virge_updatemapping(virge_t *virge) pclog("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size); if (virge->linear_base == 0xa0000) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_disable(&virge->linear_mapping); + mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_disablex(&virge->linear_mapping); } else - mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); - svga->fb_only = 1; + mem_mapping_set_addrx(&virge->linear_mapping, virge->linear_base, virge->linear_size); + if (svga->fb_only >= 0) + svga->fb_only = 1; } else { - mem_mapping_disable(&virge->linear_mapping); - svga->fb_only = 0; + mem_mapping_disablex(&virge->linear_mapping); + if (svga->fb_only >= 0) + svga->fb_only = 0; } pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18); if (svga->crtc[0x53] & 0x10) /*Old MMIO*/ { if (svga->crtc[0x53] & 0x20) - mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000); + mem_mapping_set_addrx(&virge->mmio_mapping, 0xb8000, 0x8000); else - mem_mapping_set_addr(&virge->mmio_mapping, 0xa0000, 0x10000); + mem_mapping_set_addrx(&virge->mmio_mapping, 0xa0000, 0x10000); } else - mem_mapping_disable(&virge->mmio_mapping); + mem_mapping_disablex(&virge->mmio_mapping); if (svga->crtc[0x53] & 0x08) /*New MMIO*/ - mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000); + mem_mapping_set_addrx(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000); else - mem_mapping_disable(&virge->new_mmio_mapping); + mem_mapping_disablex(&virge->new_mmio_mapping); } @@ -1368,12 +1398,10 @@ static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) { s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD); } - else switch (addr & 0xfffe) + else { - case 0x83d4: s3_virge_mmio_write(addr, val, p); s3_virge_mmio_write(addr + 1, val >> 8, p); - break; } } static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) @@ -1980,13 +2008,13 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) 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; + mono_pattern[y*8 + (7 - x)] = virge->s3d.pat_fg_clr; else - mono_pattern[y*8 + x] = virge->s3d.pat_bg_clr; + mono_pattern[y*8 + (7 - 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; + mono_pattern[(y+4)*8 + (7 - x)] = virge->s3d.pat_fg_clr; else - mono_pattern[(y+4)*8 + x] = virge->s3d.pat_bg_clr; + mono_pattern[(y+4)*8 + (7 - x)] = virge->s3d.pat_bg_clr; } } } @@ -2006,8 +2034,8 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) 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 %i,%i %02X %x %x\n", +#if 0 + pclog("BitBlt start %i,%i %i,%i %i,%i %02X %x %x %08x\n", virge->s3d.src_x, virge->s3d.src_y, virge->s3d.dest_x, @@ -2016,8 +2044,8 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.h, virge->s3d.rop, virge->s3d.src_base, - virge->s3d.dest_base);*/ - + virge->s3d.dest_base, virge->s3d.cmd_set); +#endif if (virge->s3d.cmd_set & CMD_SET_IDS) return; } @@ -2084,9 +2112,8 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) if (update) { READ(dest_addr, dest); - pattern = pattern_data[(virge->s3d.dest_y & 7)*8 + (virge->s3d.dest_x & 7)]; + pattern = pattern_data[(virge->s3d.dest_y & 7) * 8 + (virge->s3d.dest_x & 7)]; MIX(); - WRITE(dest_addr, out); } @@ -2138,18 +2165,19 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) 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 %08x\n", virge->s3d.dest_x, +#if 0 + pclog("RctFll start %i,%i %i,%i %02X %08x %08x\n", virge->s3d.dest_x, virge->s3d.dest_y, virge->s3d.w, virge->s3d.h, - virge->s3d.rop, virge->s3d.dest_base);*/ + virge->s3d.rop, virge->s3d.dest_base, virge->s3d.cmd_set); +#endif } while (count && virge->s3d.h) { 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 source = virge->s3d.pat_fg_clr, dest, pattern = virge->s3d.pat_fg_clr; uint32_t out = 0; int update = 1; @@ -2241,7 +2269,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) if (update) { READ(dest_addr, dest); - pattern = virge->s3d.pat_fg_clr; + source = pattern = virge->s3d.pat_fg_clr; MIX(); @@ -2290,7 +2318,7 @@ skip_line: if (update) { READ(dest_addr, dest); - pattern = pattern_data[(y & 7)*8 + (x & 7)]; + source = pattern = pattern_data[(y & 7)*8 + (x & 7)]; MIX(); WRITE(dest_addr, out); @@ -3784,11 +3812,11 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) 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); + io_removehandlerx(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + io_sethandlerx(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); + io_removehandlerx(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; s3_virge_updatemapping(virge); return; @@ -3810,13 +3838,13 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) { 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); + mem_mapping_set_addrx(&virge->bios_rom.mapping, addr, 0x8000); + mem_mapping_enablex(&virge->bios_rom.mapping); } else { // pclog("Virge bios_rom disabled\n"); - mem_mapping_disable(&virge->bios_rom.mapping); + mem_mapping_disablex(&virge->bios_rom.mapping); } return; case 0x3c: @@ -3827,7 +3855,7 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) static void *s3_virge_init() { - virge_t *virge = malloc(sizeof(virge_t)); + virge_t *virge = (virge_t*)malloc(sizeof(virge_t)); memset(virge, 0, sizeof(virge_t)); virge->bilinear_enabled = device_get_config_int("bilinear"); @@ -3842,9 +3870,9 @@ static void *s3_virge_init() rom_init(&virge->bios_rom, "s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) - mem_mapping_disable(&virge->bios_rom.mapping); + mem_mapping_disablex(&virge->bios_rom.mapping); - mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, + mem_mapping_addx(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, @@ -3853,7 +3881,7 @@ static void *s3_virge_init() NULL, 0, virge); - mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, + mem_mapping_addx(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, @@ -3862,7 +3890,7 @@ static void *s3_virge_init() NULL, 0, virge); - mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, + mem_mapping_addx(&virge->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, @@ -3872,7 +3900,7 @@ static void *s3_virge_init() 0, &virge->svga); - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + io_sethandlerx(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); virge->pci_regs[4] = 3; virge->pci_regs[5] = 0; @@ -3921,7 +3949,7 @@ static void *s3_virge_init() static void *s3_virge_375_init() { - virge_t *virge = malloc(sizeof(virge_t)); + virge_t *virge = (virge_t*)malloc(sizeof(virge_t)); memset(virge, 0, sizeof(virge_t)); virge->bilinear_enabled = device_get_config_int("bilinear"); @@ -3939,7 +3967,7 @@ static void *s3_virge_375_init() if (PCI) mem_mapping_disable(&virge->bios_rom.mapping); - mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, + mem_mapping_addx(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, @@ -3948,7 +3976,7 @@ static void *s3_virge_375_init() NULL, 0, virge); - mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, + mem_mapping_addx(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, @@ -3957,7 +3985,7 @@ static void *s3_virge_375_init() NULL, 0, virge); - mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, + mem_mapping_addx(&virge->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, @@ -3967,7 +3995,7 @@ static void *s3_virge_375_init() 0, &virge->svga); - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + io_sethandlerx(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); virge->pci_regs[4] = 3; virge->pci_regs[5] = 0; @@ -4000,6 +4028,8 @@ static void *s3_virge_375_init() virge->svga.crtc[0x6c] = 0x01; + virge->svga.fb_only = -1; + virge->is_375 = 1; virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); @@ -4019,10 +4049,12 @@ static void *s3_virge_375_init() static void s3_virge_close(void *p) { virge_t *virge = (virge_t *)p; +#ifndef UAE #ifndef RELEASE_BUILD FILE *f = fopen("vram.dmp", "wb"); fwrite(virge->svga.vram, 4 << 20, 1, f); fclose(f); +#endif #endif thread_kill(virge->render_thread); @@ -4084,6 +4116,7 @@ static void s3_virge_add_status_info(char *s, int max_len, void *p) reg_writes = 0; } +#ifndef UAE static device_config_t s3_virge_config[] = { { @@ -4122,7 +4155,9 @@ static device_config_t s3_virge_config[] = .type = -1 } }; +#endif +#ifndef UAE device_t s3_virge_device = { "Diamond Stealth 3D 2000 (S3 ViRGE)", @@ -4135,6 +4170,7 @@ device_t s3_virge_device = s3_virge_add_status_info, s3_virge_config }; +#endif device_t s3_virge_375_device = { @@ -4146,5 +4182,7 @@ device_t s3_virge_375_device = s3_virge_speed_changed, s3_virge_force_redraw, s3_virge_add_status_info, +#ifndef UAE s3_virge_config +#endif }; diff --git a/pcem/vid_svga.cpp b/pcem/vid_svga.cpp index 314c4d71..6b31e3f6 100644 --- a/pcem/vid_svga.cpp +++ b/pcem/vid_svga.cpp @@ -21,6 +21,11 @@ uint8_t svga_rotate[8][256]; only SVGA device.*/ static svga_t *svga_pri; +void *svga_get_object(void) +{ + return svga_pri; +} + svga_t *svga_get_pri() { return svga_pri; @@ -116,7 +121,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p) case 4: svga->chain2_write = !(val & 4); svga->chain4 = val & 8; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4; + svga->fast = ((svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4) || svga->fb_only < 0; break; } break; @@ -153,6 +158,8 @@ void svga_out(uint16_t addr, uint8_t val, void *p) svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r, svga->vgapal[svga->dac_write].g, svga->vgapal[svga->dac_write].b); else svga->pallook[svga->dac_write] = makecol32((svga->vgapal[svga->dac_write].r & 0x3f) * 4, (svga->vgapal[svga->dac_write].g & 0x3f) * 4, (svga->vgapal[svga->dac_write].b & 0x3f) * 4); + if (svga->swaprb) + svga->pallook[svga->dac_write] = ((svga->pallook[svga->dac_write] >> 16) & 0xff) | ((svga->pallook[svga->dac_write] & 0xff) << 16) | (svga->pallook[svga->dac_write] & 0x00ff00); svga->dac_pos = 0; svga->dac_write = (svga->dac_write + 1) & 255; break; @@ -201,7 +208,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p) case 7: svga->colournocare=val; break; } svga->gdcreg[svga->gdcaddr & 15] = val; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4; + svga->fast = ((svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4) || svga->fb_only < 0;; if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) svga_recalctimings(svga); break; @@ -287,6 +294,8 @@ void svga_set_ramdac_type(svga_t *svga, int type) svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); else svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, (svga->vgapal[c].g & 0x3f) * 4, (svga->vgapal[c].b & 0x3f) * 4); + if (svga->swaprb) + svga->pallook[svga->dac_write] = ((svga->pallook[svga->dac_write] >> 16) & 0xff) | ((svga->pallook[svga->dac_write] & 0xff) << 16) | (svga->pallook[svga->dac_write] & 0x00ff00); } } } @@ -340,81 +349,77 @@ void svga_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; - if (!svga->scrblank && svga->attr_palette_enable) + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ + { + if (svga->seqregs[1] & 8) /*40 column*/ + { + svga->render = svga_render_text_40; + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + } else + { + svga->render = svga_render_text_80; + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + } + svga->hdisp_old = svga->hdisp; + } + else { - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->hdisp_old = svga->hdisp; + + switch (svga->gdcreg[5] & 0x60) + { + case 0x00: /*16 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: case 0x60: /*256+ colours*/ + switch (svga->bpp) { - if (svga->seqregs[1] & 8) /*40 column*/ - { - svga->render = svga_render_text_40; - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; - } - else - { - svga->render = svga_render_text_80; - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; - } - svga->hdisp_old = svga->hdisp; + case 8: + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + break; + case 15: + if (svga->lowres) + svga->render = svga_render_15bpp_lowres; + else + svga->render = svga_render_15bpp_highres; + break; + case 16: + if (svga->lowres) + svga->render = svga_render_16bpp_lowres; + else + svga->render = svga_render_16bpp_highres; + break; + case 24: + if (svga->lowres) + svga->render = svga_render_24bpp_lowres; + else + svga->render = svga_render_24bpp_highres; + break; + case 32: + if (svga->lowres) + svga->render = svga_render_32bpp_lowres; + else + svga->render = svga_render_32bpp_highres; + break; } - else - { - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - svga->hdisp_old = svga->hdisp; - - switch (svga->gdcreg[5] & 0x60) - { - case 0x00: /*16 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: case 0x60: /*256+ colours*/ - switch (svga->bpp) - { - case 8: - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; - case 15: - if (svga->lowres) - svga->render = svga_render_15bpp_lowres; - else - svga->render = svga_render_15bpp_highres; - break; - case 16: - if (svga->lowres) - svga->render = svga_render_16bpp_lowres; - else - svga->render = svga_render_16bpp_highres; - break; - case 24: - if (svga->lowres) - svga->render = svga_render_24bpp_lowres; - else - svga->render = svga_render_24bpp_highres; - break; - case 32: - if (svga->lowres) - svga->render = svga_render_32bpp_lowres; - else - svga->render = svga_render_32bpp_highres; - break; - } - break; - } - } - } + break; + } + } -// pclog("svga_render %08X : %08X %08X %08X %08X %08X %i %i %02X %i %i\n", svga_render, svga_render_text_40, svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8); +//pclog("svga_render %08X : %08X %08X %08X %08X %08X %i %i %02X %i %i\n", svga_render, svga_render_text_40, svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8); svga->linedbl = svga->crtc[9] & 0x80; svga->rowcount = svga->crtc[9] & 31; @@ -442,18 +447,20 @@ void svga_recalctimings(svga_t *svga) svga->dispontime = TIMER_USEC; if (svga->dispofftime < TIMER_USEC) svga->dispofftime = TIMER_USEC; -/* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock); - printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart); - printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]); - pclog("svga->render %08X\n", svga->render);*/ +// pclog("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock); +// pclog("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart); +// pclog("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]); + +// pclog("svga->render %08X\n", svga->render); } extern int cyc_total; -void svga_poll(void *p) +int svga_poll(void *p) { svga_t *svga = (svga_t *)p; int x; + int eod = 0; if (!svga->linepos) { @@ -484,8 +491,9 @@ void svga_poll(void *p) svga->overlay_on = svga->overlay_latch.ysize - svga->overlay_latch.yoff; svga->overlay_oddeven = 1; } - +#ifndef UAE timer_advance_u64(&svga->timer, svga->dispofftime); +#endif // if (output) printf("Display off %f\n",vidtime); svga->cgastat |= 1; svga->linepos = 1; @@ -547,8 +555,9 @@ void svga_poll(void *p) else { // pclog("VC %i ma %05X\n", svga->vc, svga->ma); +#ifndef UAE timer_advance_u64(&svga->timer, svga->dispontime); - +#endif // if (output) printf("Display on %f\n",vidtime); if (svga->dispon) svga->cgastat &= ~1; @@ -586,7 +595,7 @@ void svga_poll(void *p) svga->hsync_divisor = !svga->hsync_divisor; if (svga->hsync_divisor && (svga->crtc[0x17] & 4)) - return; + return 1; svga->vc++; svga->vc &= 2047; @@ -726,12 +735,14 @@ void svga_poll(void *p) // pclog("Latch HWcursor addr %08X\n", svga_hwcursor_latch.addr); // pclog("ADDR %08X\n",hwcursor_addr); + eod = 1; } if (svga->sc == (svga->crtc[10] & 31)) svga->con = 1; } // printf("2 %i\n",svga_vsyncstart); //pclog("svga_poll %i %i %i %i %i %i %i\n", ins, svga->dispofftime, svga->dispontime, svga->vidtime, cyc_total, svga->linepos, svga->vc); + return eod; } int svga_init(svga_t *svga, void *p, int memsize, @@ -756,41 +767,50 @@ int svga_init(svga_t *svga, void *p, int memsize, } svga->readmode = 0; + svga->crtcreg_mask = 0x3f; svga->crtc[0] = 63; svga->crtc[6] = 255; svga->dispontime = 1000ull << 32; svga->dispofftime = 1000ull << 32; svga->bpp = 8; - svga->vram = malloc(memsize); +#ifdef UAE + extern void *pcem_getvram(int); + svga->vram = (uint8_t*)pcem_getvram(memsize); +#else + svga->vram = (uint8_t*)malloc(memsize); +#endif svga->vram_max = memsize; svga->vram_display_mask = memsize - 1; svga->vram_mask = memsize - 1; svga->decode_mask = 0x7fffff; - svga->changedvram = malloc(/*(memsize >> 12) << 1*/0x800000 >> 12); + svga->changedvram = (uint8_t*)malloc(/*(memsize >> 12) << 1*/0x800000 >> 12); svga->recalctimings_ex = recalctimings_ex; svga->video_in = video_in; svga->video_out = video_out; svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; svga->hwcursor.ysize = 64; -// _svga_recalctimings(svga); + svga_recalctimings(svga); - mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, MEM_MAPPING_EXTERNAL, svga); + mem_mapping_addx(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, MEM_MAPPING_EXTERNAL, svga); +#ifndef UAE timer_add(&svga->timer, svga_poll, svga, 1); - +#endif + svga_pri = svga; svga->ramdac_type = RAMDAC_6BIT; - + return 0; } void svga_close(svga_t *svga) { free(svga->changedvram); +#ifndef UAE free(svga->vram); - +#endif svga_pri = NULL; } @@ -800,12 +820,15 @@ void svga_write(uint32_t addr, uint8_t val, void *p) uint8_t vala, valb, valc, vald, wm = svga->writemask; int writemask2 = svga->writemask; +#if 0 egawrites++; cycles -= video_timing_write_b; cycles_lost += video_timing_write_b; if (svga_output) pclog("Writeega %06X ",addr); +#endif + addr &= svga->banked_mask; addr += svga->write_bank; @@ -834,7 +857,7 @@ void svga_write(uint32_t addr, uint8_t val, void *p) addr &= svga->vram_mask; - if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i %02X\n", addr, addr & 1023, addr >> 10, val, writemask2, svga->writemode, svga->chain4, svga->gdcreg[8]); +// if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i %02X\n", addr, addr & 1023, addr >> 10, val, writemask2, svga->writemode, svga->chain4, svga->gdcreg[8]); svga->changedvram[addr >> 12] = changeframecount; switch (svga->writemode) @@ -988,11 +1011,13 @@ uint8_t svga_read(uint32_t addr, void *p) uint32_t latch_addr; int readplane = svga->readplane; +#if 0 cycles -= video_timing_read_b; cycles_lost += video_timing_read_b; egareads++; // pclog("Readega %06X ",addr); +#endif addr &= svga->banked_mask; addr += svga->read_bank; @@ -1064,13 +1089,16 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) uint8_t vala, valb, valc, vald, wm = svga->writemask; int writemask2 = svga->writemask; +#if 0 cycles -= video_timing_write_b; cycles_lost += video_timing_write_b; egawrites++; - + if (svga_output) pclog("Write LFB %08X %02X ", addr, val); - if (!(svga->gdcreg[6] & 1)) +#endif + + if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; if (svga->chain4 || svga->fb_only) { @@ -1093,7 +1121,7 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - if (svga_output) pclog("%08X\n", addr); +// if (svga_output) pclog("%08X\n", addr); svga->changedvram[addr >> 12]=changeframecount; switch (svga->writemode) @@ -1247,11 +1275,13 @@ uint8_t svga_read_linear(uint32_t addr, void *p) int readplane = svga->readplane; uint32_t latch_addr = (addr << 2) & svga->decode_mask; +#if 0 cycles -= video_timing_read_b; cycles_lost += video_timing_read_b; egareads++; - +#endif + if (svga->chain4 || svga->fb_only) { addr &= svga->decode_mask; @@ -1324,8 +1354,8 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) { xsize=wx; ysize=wy+1; - if (xsize<64) xsize=656; - if (ysize<32) ysize=200; + if (xsize<64) xsize=0; + if (ysize<32) ysize=0; if (svga->vertical_linedbl) updatewindowsize(xsize,ysize*2); @@ -1351,18 +1381,21 @@ void svga_writew(uint32_t addr, uint16_t val, void *p) return; } +#if 0 egawrites += 2; cycles -= video_timing_write_w; cycles_lost += video_timing_write_w; if (svga_output) pclog("svga_writew: %05X ", addr); +#endif + addr = (addr & svga->banked_mask) + svga->write_bank; addr &= svga->decode_mask; if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - if (svga_output) pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val); +// if (svga_output) pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val); svga->changedvram[addr >> 12] = changeframecount; *(uint16_t *)&svga->vram[addr] = val; } @@ -1385,13 +1418,13 @@ void svga_writel(uint32_t addr, uint32_t val, void *p) cycles -= video_timing_write_l; cycles_lost += video_timing_write_l; - if (svga_output) pclog("svga_writel: %05X ", addr); +// if (svga_output) pclog("svga_writel: %05X ", addr); addr = (addr & svga->banked_mask) + svga->write_bank; addr &= svga->decode_mask; if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - if (svga_output) pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val); +// if (svga_output) pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val); svga->changedvram[addr >> 12] = changeframecount; *(uint32_t *)&svga->vram[addr] = val; @@ -1404,10 +1437,12 @@ uint16_t svga_readw(uint32_t addr, void *p) if (!svga->fast) return svga_read(addr, p) | (svga_read(addr + 1, p) << 8); +#if 0 egareads += 2; cycles -= video_timing_read_w; cycles_lost += video_timing_read_w; +#endif // pclog("Readw %05X ", addr); addr = (addr & svga->banked_mask) + svga->read_bank; @@ -1426,10 +1461,12 @@ uint32_t svga_readl(uint32_t addr, void *p) if (!svga->fast) return svga_read(addr, p) | (svga_read(addr + 1, p) << 8) | (svga_read(addr + 2, p) << 16) | (svga_read(addr + 3, p) << 24); +#if 0 egareads += 4; cycles -= video_timing_read_l; cycles_lost += video_timing_read_l; +#endif // pclog("Readl %05X ", addr); addr = (addr & svga->banked_mask) + svga->read_bank; @@ -1452,12 +1489,15 @@ void svga_writew_linear(uint32_t addr, uint16_t val, void *p) return; } +#if 0 egawrites += 2; cycles -= video_timing_write_w; cycles_lost += video_timing_write_w; if (svga_output) pclog("Write LFBw %08X %04X\n", addr, val); +#endif + addr &= svga->decode_mask; if (addr >= svga->vram_max) return; @@ -1479,12 +1519,15 @@ void svga_writel_linear(uint32_t addr, uint32_t val, void *p) return; } +#if 0 egawrites += 4; cycles -= video_timing_write_l; cycles_lost += video_timing_write_l; - if (svga_output) pclog("Write LFBl %08X %08X\n", addr, val); + if (svga_output) pclog("Write LFBl %08X %08X\n", addr, val); +#endif + addr &= svga->decode_mask; if (addr >= svga->vram_max) return; @@ -1500,10 +1543,12 @@ uint16_t svga_readw_linear(uint32_t addr, void *p) if (!svga->fast) return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8); +#if 0 egareads += 2; cycles -= video_timing_read_w; cycles_lost += video_timing_read_w; +#endif addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -1519,10 +1564,12 @@ uint32_t svga_readl_linear(uint32_t addr, void *p) if (!svga->fast) return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8) | (svga_read_linear(addr + 2, p) << 16) | (svga_read_linear(addr + 3, p) << 24); +#if 0 egareads += 4; cycles -= video_timing_read_l; cycles_lost += video_timing_read_l; +#endif addr &= svga->decode_mask; if (addr >= svga->vram_max) diff --git a/pcem/vid_svga.h b/pcem/vid_svga.h index 219eb6b3..e67ab42d 100644 --- a/pcem/vid_svga.h +++ b/pcem/vid_svga.h @@ -2,7 +2,7 @@ typedef struct svga_t { mem_mapping_t mapping; - uint8_t crtcreg; + uint8_t crtcreg, crtcreg_mask; uint8_t crtc[128]; uint8_t gdcreg[64]; int gdcaddr; @@ -143,6 +143,8 @@ typedef struct svga_t /*Used to implement CRTC[0x17] bit 2 hsync divisor*/ int hsync_divisor; + + bool swaprb; } svga_t; extern int svga_init(svga_t *svga, void *p, int memsize, diff --git a/pcem/vid_svga_render.cpp b/pcem/vid_svga_render.cpp index 505f362a..8ceddb39 100644 --- a/pcem/vid_svga_render.cpp +++ b/pcem/vid_svga_render.cpp @@ -648,12 +648,19 @@ void svga_render_24bpp_lowres(svga_t *svga) offset = (8 - (svga->scrollcache & 6)) + 24; - for (x = 0; x <= svga->hdisp; x++) - { + if (svga->swaprb) { + fg = svga->vram[svga->ma + 2] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 0] << 16); + svga->ma += 3; + svga->ma &= svga->vram_display_mask; + ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg; + } else { + for (x = 0; x <= svga->hdisp; x++) + { fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 3; + svga->ma += 3; svga->ma &= svga->vram_display_mask; ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg; + } } } } @@ -670,21 +677,32 @@ void svga_render_24bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) - { + if (svga->swaprb) { + uint32_t dat; + for (x = 0; x <= svga->hdisp; x++) + { + dat = svga->vram[svga->ma + 2] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 0] << 16); + p[x] = dat; + svga->ma += 3; + svga->ma &= svga->vram_display_mask; + } + } else { + for (x = 0; x <= svga->hdisp; x += 4) + { uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[x] = dat & 0xffffff; - + dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); p[x + 1] = dat & 0xffffff; - + dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); p[x + 2] = dat & 0xffffff; - + dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); p[x + 3] = dat & 0xffffff; - + svga->ma += 12; + } } svga->ma &= svga->vram_display_mask; } diff --git a/pcem/video.h b/pcem/video.h index 3fc28622..e8a97e50 100644 --- a/pcem/video.h +++ b/pcem/video.h @@ -1,25 +1,26 @@ + typedef struct { int w, h; uint8_t *dat; uint8_t *line[0]; -} BITMAP; +} PCBITMAP; -extern BITMAP *screen; +extern PCBITMAP *screen; -BITMAP *create_bitmap(int w, int h); +PCBITMAP *create_bitmap(int w, int h); typedef struct { uint8_t r, g, b; -} RGB; +} PCRGB; -typedef RGB PALETTE[256]; +typedef PCRGB PALETTE[256]; #define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) #define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) -extern BITMAP *buffer32; +extern PCBITMAP *buffer32; int video_card_available(int card); char *video_card_getname(int card); @@ -104,9 +105,9 @@ void closevideo(); void video_updatetiming(); -void hline(BITMAP *b, int x1, int y, int x2, int col); +void hline(PCBITMAP *b, int x1, int y, int x2, int col); -void destroy_bitmap(BITMAP *b); +void destroy_bitmap(PCBITMAP *b); extern uint32_t cgapal[16]; diff --git a/pcem/x86.h b/pcem/x86.h index 7bcd75b9..5391e4fb 100644 --- a/pcem/x86.h +++ b/pcem/x86.h @@ -59,7 +59,7 @@ typedef union MMX_REG float f[2]; } MMX_REG; -struct +typedef struct { x86reg regs[8]; @@ -118,7 +118,9 @@ struct } CR0; uint16_t flags, eflags; -} cpu_state; +} CPU_STATE; + +extern CPU_STATE cpu_state; #define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) diff --git a/pcem/x86seg.cpp b/pcem/x86seg.cpp index 9999fde6..766d0bc0 100644 --- a/pcem/x86seg.cpp +++ b/pcem/x86seg.cpp @@ -20,7 +20,6 @@ int stimes = 0; int dtimes = 0; int btimes = 0; -int is486=1; uint32_t abrt_error; int cgate16,cgate32; @@ -35,6 +34,7 @@ void taskswitch386(uint16_t seg, uint16_t *segdat); /*NOT PRESENT is INT 0B GPF is INT 0D*/ +#ifndef UAE FILE *pclogf; void x86abort(const char *format, ...) { @@ -57,6 +57,17 @@ void x86abort(const char *format, ...) dumpregs(); exit(-1); } +#else +void x86abort(const char *format, ...) +{ + char buf[256]; + va_list ap; + va_start(ap, format); + vsprintf(buf, format, ap); + va_end(ap); + fatal(buf); +} +#endif static void seg_reset(x86seg *s) { diff --git a/pcem/x87.h b/pcem/x87.h index 2d61c14a..7faf5811 100644 --- a/pcem/x87.h +++ b/pcem/x87.h @@ -3,8 +3,13 @@ #define C2 (1<<10) #define C3 (1<<14) +#ifdef UAE +extern uint32_t x87_pc_off, x87_op_off; +extern uint16_t x87_pc_seg, x87_op_seg; +#else uint32_t x87_pc_off,x87_op_off; uint16_t x87_pc_seg,x87_op_seg; +#endif static inline void x87_set_mmx() { diff --git a/pcem/x87_ops.h b/pcem/x87_ops.h index 73a231e9..9113630a 100644 --- a/pcem/x87_ops.h +++ b/pcem/x87_ops.h @@ -211,7 +211,7 @@ static inline void x87_stmmx(MMX_REG r) static inline uint16_t x87_compare(double a, double b) { -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__ +#if (defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__) && !defined(UAE) uint32_t out; /* Memory barrier, to force GCC to write to the input parameters @@ -245,7 +245,7 @@ static inline uint16_t x87_compare(double a, double b) static inline uint16_t x87_ucompare(double a, double b) { -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__ +#if (defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__) && !defined(UAE) uint32_t out; /* Memory barrier, to force GCC to write to the input parameters