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);
*/
uint32_t easeg;
-uint32_t rmdat;
static uint16_t zero=0;
uint16_t *mod1add[2][8];
int indump = 0;
+#ifndef UAE
+
void dumpregs()
{
int c,d=0,e=0;
indump = 0;
}
+#endif
+
int x86_was_reset = 0;
void resetx86()
{
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;
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);
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);
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;
x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32;
}
codegen_timing_set(&codegen_timing_486);
+#endif
if (hasfpu)
{
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*/
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*/
codegen_timing_set(&codegen_timing_k6);
break;
+#endif
+
default:
fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type);
}
#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;
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();
uint16_t io_addr;
} dma_t;
+#ifdef UAE
+extern dma_t dma[8];
+#else
dma_t dma[8];
+#endif
/*PPI*/
typedef struct PPI
uint8_t pa,pb;
} PPI;
+#ifdef UAE
+extern PPI ppi;
+#else
PPI ppi;
-
+#endif
/*PIC*/
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
extern int romspresent[ROM_MAX];
+#ifdef UAE
+extern int hasfpu;
+extern int romset;
+#else
int hasfpu;
int romset;
+#endif
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;
/*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*/
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;
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
#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
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;
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);
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*/
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;
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 */
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;
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;
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;
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)
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++)
{
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
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;
void mem_init();
void mem_alloc();
+#ifdef UAE
+void mem_free();
+#endif
void mem_set_704kb();
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;
int oldromset;
int nvrmask=63;
-uint8_t nvrram[128];
+uint8_t nvrram[128+64];
int nvraddr;
int nvr_dosave = 0;
int onesec_cnt;
} nvr_t;
+#ifndef UAE
FILE *nvrfopen(char *fn, char *mode)
{
char s[512];
return NULL;
}
}
+#endif
void getnvrtime()
{
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
void loadnvr()
{
- FILE *f;
-
nvrmask=63;
oldromset=romset;
+
+#ifndef UAE
+ FILE *f;
+
switch (romset)
{
case ROM_PC1512: f = nvrfopen("pc1512.nvr", "rb"); break;
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;
fwrite(nvrram,128,1,f);
fclose(f);
}
+#endif
static void *nvr_init()
{
FILE *nvrfopen(char *fn, char *mode);
-extern uint8_t nvrram[128];
+extern uint8_t nvrram[128+64];
extern int nvrmask;
extern int oldromset;
#include "pit.h"
#include "video.h"
+#ifdef UAE
+void x86_ack_keyboard(void);
+#endif
+
int intclear;
int keywaiting=0;
int pic_intpending;
// 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)
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;
#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)
#ifdef __cplusplus
extern "C" {
#endif
+#ifndef UAE
void mouse_init();
void mouse_close();
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
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;
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;
extern int sound_gain;
extern int SOUNDBUFLEN;
+#ifdef UAE
+#define MAXSOUNDBUFLEN 8192
+#else
#define MAXSOUNDBUFLEN (48000 / 10)
+#endif
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");
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++)
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)
{
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));
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));
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);
sb->pos_regs[1] = 0x50;
return sb;
}
+#endif
+
void *sb_2_init()
{
/*sb2 port mappings. 220h or 240h.
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));
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));
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");
return sb;
}
+#ifndef UAE
void *sb_pro_mcv_init()
{
/*sbpro port mappings. 220h or 240h.
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");
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");
return sb;
}
+#ifndef UAE
+
int sb_awe32_available()
{
return rom_present("awe32.raw");
return sb;
}
+#endif
+
void sb_close(void *p)
{
sb_t *sb = (sb_t *)p;
free(sb);
}
+#ifndef UAE
+
void sb_awe32_close(void *p)
{
sb_t *sb = (sb_t *)p;
sb_close(sb);
}
+#endif
+
void sb_speed_changed(void *p)
{
sb_t *sb = (sb_t *)p;
sb_dsp_add_status_info(s, max_len, &sb->dsp);
}
+#ifndef UAE
+
static device_config_t sb_config[] =
{
{
sb_add_status_info,
sb_awe32_config
};
+
+#endif
#include <stdint.h>
#include <stdio.h>
#include <math.h>
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264338327950288
+#endif
#include "ibm.h"
#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"
case 0x05:
break;
case 0x09: /*AZTECH mode set*/
+#ifndef UAE
if (IS_AZTECH(dsp))
{
if (dsp->sb_data[0] == 0x00)
pclog("AZT2316A: UNKNOWN MODE!\n"); // sequences 0x02->0xFF, 0x04->0xFF seen
}
break;
+#endif
case 0x38: /*TODO: AZTECH MIDI-related? */
break;
// default:
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;
}
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
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;
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;
uint8_t sr10_read, sr11_read;
uint8_t latch_ext[4];
+
+ int vblank_irq;
+ int vportsync;
int vidsys_ena;
} gd5429_t;
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;
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;
}
}
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);
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*/
else
svga->decode_mask = svga->vram_mask;
}
-
+#endif
svga->gdcreg[6] = val;
return;
}
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;
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:
break;
case 0x3D4:
- svga->crtcreg = val & 0x3f;
+ svga->crtcreg = val & svga->crtcreg_mask;
return;
case 0x3D5:
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
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;
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;
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;
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;
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];
}
}
else
gd5429->bank[1] = gd5429->bank[0] + 0x8000;
+
+ if (svga->seqregs[7] & 0xf0) {
+ gd5429_recalc_mapping(gd5429);
+ }
}
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;
}
// 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;
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);
}
}
void gd5429_hwcursor_draw(svga_t *svga, int displine)
{
+ gd5429_t *gd5429 = (gd5429_t *)svga->p;
int x;
uint8_t dat[2];
int xx;
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;
}
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;
}
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)
{
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)
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;
else
addr<<=2;
- addr &= svga->decode_mask;
+// addr &= svga->decode_mask;
if (latch_addr >= svga->vram_max)
{
}
}
+#if 0
if (addr >= svga->vram_max)
return 0xff;
addr &= svga->vram_mask;
+#endif
if (svga->readmode)
{
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)
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;
// 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;
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;
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)
{
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
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;
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;
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--;
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;
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
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;
}
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;
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:
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;
}
}
switch (addr & 0xff)
{
case 0x40: /*BLT status*/
- return 0;
+ return gd5429->blt.status;
}
return 0xff; /*All other registers read-only*/
}
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;
}
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);
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");
return 0xa0;
case CL_TYPE_GD5434:
return 0xa8;
+ case CL_TYPE_GD5446:
+ case CL_TYPE_GD5446B:
+ return 0xb8;
}
return 0xff;
case 0x03: return 0x00;
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;
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:
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));
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;
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)
gd5429->pci_regs[0x32] = 0x0c;
gd5429->pci_regs[0x33] = 0x00;
}
+
+ gd5429->svga.fb_only = -1;
return gd5429;
}
{
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);
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;
}
{
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);
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
+ .default_int = 512,
.selection =
{
{
.description = ""
}
},
- .default_int = 512
},
{
.type = -1
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
+ .default_int = 2,
.selection =
{
{
.description = ""
}
},
- .default_int = 2
},
{
.type = -1
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
+ .default_int = 4,
.selection =
{
{
.description = ""
}
},
- .default_int = 4
},
{
.type = -1
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",
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)",
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)",
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
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;
uint32_t hwc_fg_col, hwc_bg_col;
int hwc_col_stack_pos;
-
+
volatile int force_busy;
} 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);
}
}
+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);
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;
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)
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:
{
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;
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];
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)
{
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;
}
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;
}
// 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)
// 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)
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);
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);
}
{
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;
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;
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,
return s3;
}
+#ifndef UAE
void *s3_bahamas64_init()
{
s3_t *s3 = s3_init("bahamas64.bin", S3_VISION864);
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;
s3->blitter_time = 0;
}
+#ifndef UAE
+
static device_config_t s3_bahamas64_config[] =
{
{
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
-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;
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);
{
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;
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);
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;
}
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;
}
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);
}
{
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)
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;
}
}
}
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,
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;
}
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);
}
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;
if (update)
{
READ(dest_addr, dest);
- pattern = virge->s3d.pat_fg_clr;
+ source = pattern = virge->s3d.pat_fg_clr;
MIX();
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);
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;
{
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:
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");
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,
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,
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,
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;
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");
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,
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,
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,
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;
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);
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);
reg_writes = 0;
}
+#ifndef UAE
static device_config_t s3_virge_config[] =
{
{
.type = -1
}
};
+#endif
+#ifndef UAE
device_t s3_virge_device =
{
"Diamond Stealth 3D 2000 (S3 ViRGE)",
s3_virge_add_status_info,
s3_virge_config
};
+#endif
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
};
only SVGA device.*/
static svga_t *svga_pri;
+void *svga_get_object(void)
+{
+ return svga_pri;
+}
+
svga_t *svga_get_pri()
{
return svga_pri;
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;
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;
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;
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);
}
}
}
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;
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)
{
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;
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;
svga->hsync_divisor = !svga->hsync_divisor;
if (svga->hsync_divisor && (svga->crtc[0x17] & 4))
- return;
+ return 1;
svga->vc++;
svga->vc &= 2047;
// 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,
}
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;
}
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;
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)
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;
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)
{
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)
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;
{
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);
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;
}
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;
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;
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;
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;
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;
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)
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)
{
mem_mapping_t mapping;
- uint8_t crtcreg;
+ uint8_t crtcreg, crtcreg_mask;
uint8_t crtc[128];
uint8_t gdcreg[64];
int gdcaddr;
/*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,
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;
+ }
}
}
}
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;
}
+
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);
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];
float f[2];
} MMX_REG;
-struct
+typedef struct
{
x86reg regs[8];
} 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)
int stimes = 0;
int dtimes = 0;
int btimes = 0;
-int is486=1;
uint32_t abrt_error;
int cgate16,cgate32;
/*NOT PRESENT is INT 0B
GPF is INT 0D*/
+#ifndef UAE
FILE *pclogf;
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)
{
#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()
{
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
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