]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
PCem v16 merge. Modifications.
authorToni Wilen <twilen@winuae.net>
Sat, 29 Aug 2020 16:58:00 +0000 (19:58 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 29 Aug 2020 16:58:00 +0000 (19:58 +0300)
34 files changed:
pcem/386_dynarec.cpp
pcem/808x.cpp
pcem/cpu.cpp
pcem/ibm.h
pcem/io.h
pcem/keyboard_at.cpp
pcem/mem.cpp
pcem/mem.h
pcem/mouse_ps2.cpp
pcem/nvr.cpp
pcem/nvr.h
pcem/pic.cpp
pcem/plat-keyboard.h
pcem/plat-mouse.h
pcem/serial.h
pcem/sound.h
pcem/sound_cms.cpp
pcem/sound_dbopl.cpp
pcem/sound_sb.cpp
pcem/sound_sb_dsp.cpp
pcem/timer.cpp
pcem/vid_cl5429.cpp
pcem/vid_cl5429.h
pcem/vid_s3.cpp
pcem/vid_s3.h
pcem/vid_s3_virge.cpp
pcem/vid_svga.cpp
pcem/vid_svga.h
pcem/vid_svga_render.cpp
pcem/video.h
pcem/x86.h
pcem/x86seg.cpp
pcem/x87.h
pcem/x87_ops.h

index b7ab1bfd97814faf97d0004632a82ef97f6b6b05..dc87772ce53b1eb6fd6ab27ffdd2bcba4ac18f62 100644 (file)
@@ -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);
 
index d81ee33517096bb38b14631f6150a9d4bd8e0859..99eba41f522a2f245af86a4258d4c4288d503725 100644 (file)
@@ -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()
 {
index 7490db11abc9d59fefd07b811ea34e87d0df7ed1..6dbd3406bb520087f7c555a1e9d866d37cd52dfd 100644 (file)
@@ -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);
         }
index da0f39fec600db8d6085fd182fb276c047453a1a..f984d4a7b9469c9b0ac0aeb57c16eb6ebd5bb6c9 100644 (file)
 #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;
index 84792374d5c82498208618b16bc05c8f43135775..7ebadc15900db895962cf9648d84432572a68381 100644 (file)
--- 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
index b2fd23b350e36acadf067db20852101df0d9af20..64534ddf981bece699b224d44edfadf16b82100a 100644 (file)
 #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)
index 89bbff8d68ca55c9817898a08120a53e4ac3f75a..43d2d958d8bf9502fed6e5b76fed033c58a48939 100644 (file)
@@ -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++)
         {
index 41fe23f368071467ec03c3a589bc249e091077cb..3c6a0f5e47de8850c7796b67439ade343041dd99 100644 (file)
@@ -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();
 
index b1c219df014a2d253b6aed6e53fe5010b5c64603..4df123105858ba12f9023c5e26b4847ab1acd148 100644 (file)
@@ -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;
                 
index ccb7f9f087c06c6607aa228248260a086fa49b73..4fdda9ba97a291e627684ff57b2c210e63b2eca6 100644 (file)
@@ -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()
 {
index c545f8487f3fc76ba5e270a9360e2ccbfa50d33f..70a144b11a8a20950fdbdc70c7e428f9970f4755 100644 (file)
@@ -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;
index e6bf6791d2d375efe356e4624dfe6932fafd27e7..79124296868a025523f81f584592d6250b447fa9 100644 (file)
@@ -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;
index ad027f994412d97efb4aebd5ae3bbf9f2dc8b5ec..9dbe0a848da968e3f9777189b1b97f16906db4ef 100644 (file)
@@ -1,14 +1,15 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-        #include <stdint.h>
+#ifndef UAE
+#include <stdint.h>
         
         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)
index e9323027df350878036e2eddc2fb2df3bc84155d..6520458c469d140e8ccaf09e296f7d053a5d17cd 100644 (file)
@@ -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
index 85ae2592c15b341f3dcb6a9c1bb184093f2b2efa..4818423fedb4e5c780f47719c80a0826af79c3e2 100644 (file)
@@ -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;
index 9d532e9adbabca66fd1a9ca7eb2ecb457a410ffc..7c5bc984c631f2785c99c2d6dce8517fe5cda4b2 100644 (file)
@@ -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
index c649a6255de95aa9c9f9f9b947acf76cc4fd0cbd..470227dcb03f9f8db75b5b5fb0269440a4ca156a 100644 (file)
@@ -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");
index fd9f6c7e24f76bb2c2d50b6a958b2d6843c0b5cb..0af43a11ac8a647e96878fcf3ead654a9ced1787 100644 (file)
@@ -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)
        {
index 2c308c5e3f86f349095bcc29262a902425141a7e..961884a830e81f0997d237eda728d8849c6a12d5 100644 (file)
@@ -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
index ce88db9134d8d0bc0eb62b46c43c3dfecbb8faaa..61626515febb5b1c879ab69d8dd1015e3678aa98 100644 (file)
@@ -7,6 +7,9 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <math.h>
+#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:
index 565e51daadc80b25759dc0a52724a5122715d45c..3a0ce658b749dd98b180a7843cab1a08dd5e8ae1 100644 (file)
@@ -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;
        }
index 76c54fe3db6569835fbad934e3d23704558e475a..3040a80e1c7e898f304aa35683358fb4011aa606 100644 (file)
@@ -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
index 70b032159a05c5f48d70f88953b9c17680a53305..0997b6073b72d4d81256655f70777eac9bf9377f 100644 (file)
@@ -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;
index 338b39a9a2bbdacbd796756c6c99b69adf7fcf1e..490a73b75098c0981ff51762f0842e84966be235 100644 (file)
@@ -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
index ee040396fd6daf7b8ff0fe722fb7e8ceba4f08c9..aa453fa1fff5493d379b5ff36caa69bc9c980562 100644 (file)
@@ -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;
index 33e85fd7aa7fa434a157e8d71a8a3382a76e0a9b..b1cb60aaf9f5299c40add5e7c345fe707c875e5f 100644 (file)
@@ -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
 };
index 314c4d71c9e64e1b2d0dac11c31404848696320c..6b31e3f6e04a9b376025e54313d47b2f9880b30b 100644 (file)
@@ -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)
index 219eb6b3f5cc57d2221f3699bec58a620e5d15ae..e67ab42d21cefcab6a4d14f11fda1e7f39b114b4 100644 (file)
@@ -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, 
index 505f362a9119184fbd27a538879e9f2d195dbc49..8ceddb39a0af4c225098cbd425712a035abbaa7c 100644 (file)
@@ -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;
         }
index 3fc28622e627562d244197b38aabad9b8f296957..e8a97e50423c007ccd4d11ea597754a1f71d12f0 100644 (file)
@@ -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];
 
index 7bcd75b93fe4f62e3239e10d2ce1b941c15b1dd2..5391e4fbb6fc96c41cc9b235ac58e3931be8ac4d 100644 (file)
@@ -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)
 
index 9999fde67692a8d22e1d9d03778a1cd399735e60..766d0bc0add3b6e403f05c662eb20d9d93331f07 100644 (file)
@@ -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)
 {
index 2d61c14aed9523cddb156f615048cb1c4df43ec8..7faf58118d068f9e0a96c82032bc7a43292da7ee 100644 (file)
@@ -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()
 {
index 73a231e940dc969ebe95dfad17c767e513e4f6a2..9113630a831feb2880179a7fd9dbaddcfbf5efb2 100644 (file)
@@ -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