Now up to date with current dev version.
Changes since v0.7 : - Major CPU reorganisation. This has possibly broken some stuff, though I fixed all the regressions I could find - Lazy flags. This brought 10% speed improvement at one point, but that's probably been lost now - 430 VX chipset emulation - IDT Winchip emulation (currently sans MMX). Timing is probably wrong - Fixed a few FPU bugs - Timer reorganisation - Sound reorganisation - Other general reorganisation - AdLib Gold emulation - Windows Sound System emulation - Pro Audio Spectrum 16 emulation. This currently works with most DOS stuff, but not in Windows - Major improvements to GUS emulation. Has the downside that it now conflicts with SB emulation, so probably best to not enable both simultaneously - New graphics cards : - ATI-18800 (VGA Edge-16) - ATI-28800 (VGA Charger) - ATI Mach64GX (Graphics Pro Turbo). Quite a few features missing, but Windows doesn't seem to use half the features of this card - Cirrus Logic CL-GD5429. Blitter is a bit broken - Oak OTI-067 - S3 Trio64 (Number Nine 9FX) - S3 Virge. Only framebuffer stuff at the minute, Windows won't recognise the card - Trident TGUI-9440 - VGA. Doesn't work yet - Beginnings of 3DFX emulation, however this is in extremely early stages and doesn't do anything useful - Fixed DMA bug stopping floppy drives working in Windows 3.x - Fixed some other stuff probably - Broke some other stuff probably as well
This commit is contained in:
parent
3c253c2cf8
commit
9312de19ac
87 changed files with 4528 additions and 9373 deletions
|
|
@ -3,20 +3,22 @@ CPP = g++.exe
|
|||
CC = gcc.exe
|
||||
WINDRES = windres.exe
|
||||
CFLAGS = -O3 -march=i686 -fomit-frame-pointer
|
||||
OBJ = 286.o 386.o acer386sx.o adlib.o ali1429.o amstrad.o cdrom-ioctl.o cms.o \
|
||||
config.o cpu.o dac.o dma.o ega.o fdc.o gus.o harddisk.o \
|
||||
headland.o ide.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \
|
||||
OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \
|
||||
config.o cpu.o dac.o device.o dma.o ega.o fdc.o harddisk.o \
|
||||
headland.o i430vx.o ide.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \
|
||||
keyboard_olim24.o keyboard_xt.o lpt.o mcr.o mem.o model.o \
|
||||
mouse.o mouse_ps2.o mouse_serial.o neat.o nvr.o olivetti_m24.o \
|
||||
opti.o pc.o pci.o pic.o pit.o \
|
||||
ppi.o psg.o sblaster.o serial.o sound.o soundopenal.o um8881f.o \
|
||||
vid_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o \
|
||||
vid_et4000w32i.o vid_hercules.o vid_icd2061.o vid_mda.o vid_olivetti_m24.o \
|
||||
vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o \
|
||||
vid_pc200.o vid_s3.o vid_sdac_ramdac.o vid_stg_ramdac.o \
|
||||
vid_svga.o vid_tandy.o vid_tkd8001_ramdac.o vid_tvga.o \
|
||||
vid_unk_ramdac.o video.o wd76c10.o win.o win-ddraw.o \
|
||||
win-keyboard.o win-mouse.o win-timer.o win-video.o x86.o \
|
||||
opti.o pc.o pci.o pic.o piix.o pit.o ppi.o serial.o sound.o sound_adlib.o \
|
||||
sound_adlibgold.o sound_cms.o sound_gus.o sound_opl.o sound_pas16.o sound_sb.o \
|
||||
sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_wss.o soundopenal.o timer.o \
|
||||
um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
|
||||
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_ega.o \
|
||||
vid_et4000.o vid_et4000w32.o vid_et4000w32i.o vid_hercules.o vid_icd2061.o \
|
||||
vid_ics2595.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o \
|
||||
vid_pc1512.o vid_pc1640.o vid_pc200.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \
|
||||
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tkd8001_ramdac.o \
|
||||
vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o video.o wd76c10.o \
|
||||
win.o win-ddraw.o win-keyboard.o win-mouse.o win-timer.o win-video.o \
|
||||
x86seg.o x87.o xtide.o pc.res
|
||||
FMOBJ = fmopl.o ymf262.o
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
static int acer_index = 0;
|
||||
static uint8_t acer_regs[256];
|
||||
|
||||
void acer386sx_write(uint16_t addr, uint8_t val)
|
||||
void acer386sx_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (addr & 1)
|
||||
acer_regs[acer_index] = val;
|
||||
|
|
@ -15,7 +15,7 @@ void acer386sx_write(uint16_t addr, uint8_t val)
|
|||
acer_index = val;
|
||||
}
|
||||
|
||||
uint8_t acer386sx_read(uint16_t addr)
|
||||
uint8_t acer386sx_read(uint16_t addr, void *priv)
|
||||
{
|
||||
if (addr & 1)
|
||||
{
|
||||
|
|
@ -29,5 +29,5 @@ uint8_t acer386sx_read(uint16_t addr)
|
|||
|
||||
void acer386sx_init()
|
||||
{
|
||||
io_sethandler(0x0022, 0x0002, acer386sx_read, NULL, NULL, acer386sx_write, NULL, NULL);
|
||||
io_sethandler(0x0022, 0x0002, acer386sx_read, NULL, NULL, acer386sx_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
static int ali1429_index;
|
||||
static uint8_t ali1429_regs[256];
|
||||
|
||||
void ali1429_write(uint16_t port, uint8_t val)
|
||||
void ali1429_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
// return;
|
||||
if (!(port&1)) ali1429_index=val;
|
||||
|
|
@ -31,9 +31,9 @@ void ali1429_write(uint16_t port, uint8_t val)
|
|||
{
|
||||
shadowbios=0;
|
||||
if (!shadowbios_write)
|
||||
mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL );
|
||||
mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL, NULL);
|
||||
else
|
||||
mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml);
|
||||
mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL);
|
||||
flushmmucache();
|
||||
}
|
||||
break;
|
||||
|
|
@ -42,10 +42,10 @@ void ali1429_write(uint16_t port, uint8_t val)
|
|||
shadowbios_write=val&2;
|
||||
switch (val & 3)
|
||||
{
|
||||
case 0: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL ); break;
|
||||
case 1: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL ); break;
|
||||
case 2: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml); break;
|
||||
case 3: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); break;
|
||||
case 0: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL, NULL); break;
|
||||
case 1: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL, NULL); break;
|
||||
case 2: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break;
|
||||
case 3: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break;
|
||||
}
|
||||
|
||||
// if (val==0x43) shadowbios=1;
|
||||
|
|
@ -56,7 +56,7 @@ void ali1429_write(uint16_t port, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t ali1429_read(uint16_t port)
|
||||
uint8_t ali1429_read(uint16_t port, void *priv)
|
||||
{
|
||||
if (!(port&1)) return ali1429_index;
|
||||
if ((ali1429_index >= 0xc0 || ali1429_index == 0x20) && cpu_iscyrix)
|
||||
|
|
@ -72,5 +72,5 @@ void ali1429_reset()
|
|||
|
||||
void ali1429_init()
|
||||
{
|
||||
io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL);
|
||||
io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
static uint8_t amstrad_dead;
|
||||
|
||||
uint8_t amstrad_read(uint16_t port)
|
||||
uint8_t amstrad_read(uint16_t port, void *priv)
|
||||
{
|
||||
pclog("amstrad_read : %04X\n",port);
|
||||
switch (port)
|
||||
|
|
@ -25,7 +25,7 @@ uint8_t amstrad_read(uint16_t port)
|
|||
return 0xff;
|
||||
}
|
||||
|
||||
void amstrad_write(uint16_t port, uint8_t val)
|
||||
void amstrad_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
switch (port)
|
||||
{
|
||||
|
|
@ -37,16 +37,15 @@ void amstrad_write(uint16_t port, uint8_t val)
|
|||
|
||||
static uint8_t mousex,mousey;
|
||||
|
||||
void amstrad_mouse_write(uint16_t addr, uint8_t val)
|
||||
void amstrad_mouse_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("Write mouse %04X %02X %04X:%04X\n", addr, val, CS, pc);
|
||||
if (addr==0x78) mousex=0;
|
||||
else mousey=0;
|
||||
}
|
||||
|
||||
uint8_t amstrad_mouse_read(uint16_t addr)
|
||||
uint8_t amstrad_mouse_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// printf("Read mouse %04X %04X:%04X %02X\n", addr, CS, pc, (addr == 0x78) ? mousex : mousey);
|
||||
if (addr==0x78) return mousex;
|
||||
return mousey;
|
||||
|
|
@ -73,12 +72,12 @@ void amstrad_mouse_poll(int x, int y, int b)
|
|||
|
||||
void amstrad_init()
|
||||
{
|
||||
lpt2_remove();
|
||||
lpt2_remove_ams();
|
||||
|
||||
io_sethandler(0x0078, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL);
|
||||
io_sethandler(0x007a, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL);
|
||||
io_sethandler(0x0379, 0x0002, amstrad_read, NULL, NULL, NULL, NULL, NULL);
|
||||
io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL);
|
||||
io_sethandler(0x0078, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x007a, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0379, 0x0002, amstrad_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL);
|
||||
|
||||
mouse_poll = amstrad_mouse_poll;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ void ioctl_audio_callback(int16_t *output, int len)
|
|||
{
|
||||
RAW_READ_INFO in;
|
||||
DWORD count;
|
||||
int c;
|
||||
|
||||
// return;
|
||||
// pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount());
|
||||
if (ioctl_cd_state != CD_PLAYING)
|
||||
|
|
@ -143,7 +143,6 @@ static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf)
|
|||
|
||||
static void ioctl_pause(void)
|
||||
{
|
||||
long size;
|
||||
if (!cdrom_drive) return;
|
||||
if (ioctl_cd_state == CD_PLAYING)
|
||||
ioctl_cd_state = CD_PAUSED;
|
||||
|
|
@ -154,7 +153,6 @@ static void ioctl_pause(void)
|
|||
|
||||
static void ioctl_resume(void)
|
||||
{
|
||||
long size;
|
||||
if (!cdrom_drive) return;
|
||||
if (ioctl_cd_state == CD_PAUSED)
|
||||
ioctl_cd_state = CD_PLAYING;
|
||||
|
|
@ -165,7 +163,6 @@ static void ioctl_resume(void)
|
|||
|
||||
static void ioctl_stop(void)
|
||||
{
|
||||
long size;
|
||||
if (!cdrom_drive) return;
|
||||
ioctl_cd_state = CD_STOPPED;
|
||||
// ioctl_open(0);
|
||||
|
|
@ -175,7 +172,6 @@ static void ioctl_stop(void)
|
|||
|
||||
static void ioctl_seek(uint32_t pos)
|
||||
{
|
||||
long size;
|
||||
if (!cdrom_drive) return;
|
||||
// ioctl_cd_state = CD_STOPPED;
|
||||
pclog("Seek %08X\n", pos);
|
||||
|
|
@ -229,8 +225,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf)
|
|||
SUB_Q_CHANNEL_DATA sub;
|
||||
long size;
|
||||
int pos=0;
|
||||
int c;
|
||||
uint32_t temp, cdpos;
|
||||
uint32_t cdpos;
|
||||
if (!cdrom_drive) return 0;
|
||||
insub.Format = IOCTL_CDROM_CURRENT_POSITION;
|
||||
ioctl_open(0);
|
||||
|
|
|
|||
28
src/config.c
28
src/config.c
|
|
@ -26,7 +26,7 @@ int get_config_int(char *head, char *name, int def)
|
|||
if (!f)
|
||||
return def;
|
||||
|
||||
pclog("Searching for %s\n", name);
|
||||
// pclog("Searching for %s\n", name);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
|
@ -46,9 +46,9 @@ int get_config_int(char *head, char *name, int def)
|
|||
if (!buffer[c]) continue;
|
||||
name2[d] = 0;
|
||||
|
||||
pclog("Comparing %s and %s\n", name, name2);
|
||||
// pclog("Comparing %s and %s\n", name, name2);
|
||||
if (strcmp(name, name2)) continue;
|
||||
pclog("Found!\n");
|
||||
// pclog("Found!\n");
|
||||
|
||||
while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c])
|
||||
c++;
|
||||
|
|
@ -56,7 +56,7 @@ int get_config_int(char *head, char *name, int def)
|
|||
if (!buffer[c]) continue;
|
||||
|
||||
sscanf(&buffer[c], "%i", &res);
|
||||
pclog("Reading value - %i\n", res);
|
||||
// pclog("Reading value - %i\n", res);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ char *get_config_string(char *head, char *name, char *def)
|
|||
if (!f)
|
||||
return config_return_string;
|
||||
|
||||
pclog("Searching for %s\n", name);
|
||||
// pclog("Searching for %s\n", name);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
|
@ -98,9 +98,9 @@ char *get_config_string(char *head, char *name, char *def)
|
|||
if (!buffer[c]) continue;
|
||||
name2[d] = 0;
|
||||
|
||||
pclog("Comparing %s and %s\n", name, name2);
|
||||
// pclog("Comparing %s and %s\n", name, name2);
|
||||
if (strcmp(name, name2)) continue;
|
||||
pclog("Found!\n");
|
||||
// pclog("Found!\n");
|
||||
|
||||
while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c])
|
||||
c++;
|
||||
|
|
@ -110,11 +110,11 @@ char *get_config_string(char *head, char *name, char *def)
|
|||
strcpy(config_return_string, &buffer[c]);
|
||||
|
||||
c = strlen(config_return_string) - 1;
|
||||
pclog("string len %i\n", c);
|
||||
// pclog("string len %i\n", c);
|
||||
while (config_return_string[c] <= 32 && config_return_string[c])
|
||||
config_return_string[c--] = 0;
|
||||
|
||||
pclog("Reading value - %s\n", config_return_string);
|
||||
// pclog("Reading value - %s\n", config_return_string);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -125,19 +125,19 @@ char *get_config_string(char *head, char *name, char *def)
|
|||
void set_config_int(char *head, char *name, int val)
|
||||
{
|
||||
FILE *f = fopen(config_file, "at");
|
||||
if (!f) pclog("set_config_int - !f\n");
|
||||
// if (!f) pclog("set_config_int - !f\n");
|
||||
fprintf(f, "%s = %i\n", name, val);
|
||||
pclog("Write %s = %i\n", name, val);
|
||||
// pclog("Write %s = %i\n", name, val);
|
||||
fclose(f);
|
||||
pclog("fclose\n");
|
||||
// pclog("fclose\n");
|
||||
}
|
||||
|
||||
void set_config_string(char *head, char *name, char *val)
|
||||
{
|
||||
FILE *f = fopen(config_file, "at");
|
||||
if (!f) pclog("set_config_string - !f\n");
|
||||
// if (!f) pclog("set_config_string - !f\n");
|
||||
fprintf(f, "%s = %s\n", name, val);
|
||||
pclog("Write %s = %s\n", name, val);
|
||||
// pclog("Write %s = %s\n", name, val);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,3 +3,7 @@ int get_config_int(char *head, char *name, int def);
|
|||
char *get_config_string(char *head, char *name, char *def);
|
||||
void set_config_int(char *head, char *name, int val);
|
||||
void set_config_string(char *head, char *name, char *val);
|
||||
|
||||
char *get_filename(char *s);
|
||||
void append_filename(char *dest, char *s1, char *s2, int size);
|
||||
void put_backslash(char *s);
|
||||
|
|
|
|||
88
src/cpu.c
88
src/cpu.c
|
|
@ -2,6 +2,7 @@
|
|||
#include "cpu.h"
|
||||
#include "model.h"
|
||||
#include "io.h"
|
||||
#include "x86_ops.h"
|
||||
|
||||
int cpu = 3, cpu_manufacturer = 0;
|
||||
CPU *cpu_s;
|
||||
|
|
@ -9,6 +10,7 @@ int cpu_multi;
|
|||
int cpu_iscyrix;
|
||||
int cpu_16bitbus;
|
||||
int cpu_busspeed;
|
||||
int cpu_hasrdtsc;
|
||||
|
||||
int timing_rr;
|
||||
int timing_mr, timing_mrl;
|
||||
|
|
@ -32,6 +34,9 @@ int timing_bt, timing_bnt;
|
|||
12 = 133 MHz
|
||||
13 = 150 MHz
|
||||
14 = 160 MHz
|
||||
15 = 166 MHz
|
||||
16 = 180 MHz
|
||||
17 = 200 MHz
|
||||
*/
|
||||
|
||||
CPU cpus_8088[] =
|
||||
|
|
@ -197,6 +202,23 @@ CPU cpus_Cx486[] =
|
|||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_WinChip[] =
|
||||
{
|
||||
/*IDT WinChip*/
|
||||
{"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 0x540, 0x540, 0},
|
||||
{"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 0x540, 0x540, 0},
|
||||
{"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 0x540, 0x540, 0},
|
||||
{"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 0x540, 0x540, 0},
|
||||
{"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 0x540, 0x540, 0},
|
||||
{"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 0x540, 0x540, 0},
|
||||
{"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 0x540, 0x540, 0},
|
||||
{"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 0x540, 0x540, 0},
|
||||
{"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 0x540, 0x540, 0},
|
||||
{"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 0x540, 0x540, 0},
|
||||
{"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 0x540, 0x540, 0},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
void cpu_set_edx()
|
||||
{
|
||||
EDX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset;
|
||||
|
|
@ -216,17 +238,37 @@ void cpu_set()
|
|||
if (cpu_s->multi)
|
||||
cpu_busspeed = cpu_s->rspeed / cpu_s->multi;
|
||||
cpu_multi = cpu_s->multi;
|
||||
cpu_hasrdtsc = 0;
|
||||
|
||||
if (cpu_iscyrix)
|
||||
io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL);
|
||||
io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
|
||||
else
|
||||
io_removehandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL);
|
||||
io_removehandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
|
||||
|
||||
pclog("hasfpu - %i\n",hasfpu);
|
||||
pclog("is486 - %i %i\n",is486,cpu_s->cpu_type);
|
||||
|
||||
|
||||
x86_setopcodes(ops_386, ops_386_0f);
|
||||
|
||||
switch (cpu_s->cpu_type)
|
||||
{
|
||||
case CPU_8088:
|
||||
case CPU_8086:
|
||||
break;
|
||||
|
||||
case CPU_286:
|
||||
x86_setopcodes(ops_286, ops_286_0f);
|
||||
timing_rr = 2; /*register dest - register src*/
|
||||
timing_rm = 7; /*register dest - memory src*/
|
||||
timing_mr = 7; /*memory dest - register src*/
|
||||
timing_mm = 7; /*memory dest - memory src*/
|
||||
timing_rml = 9; /*register dest - memory src long*/
|
||||
timing_mrl = 11; /*memory dest - register src long*/
|
||||
timing_mml = 11; /*memory dest - memory src*/
|
||||
timing_bt = 7-3; /*branch taken*/
|
||||
timing_bnt = 3; /*branch not taken*/
|
||||
break;
|
||||
|
||||
case CPU_386SX:
|
||||
timing_rr = 2; /*register dest - register src*/
|
||||
timing_rm = 6; /*register dest - memory src*/
|
||||
|
|
@ -326,6 +368,22 @@ void cpu_set()
|
|||
timing_bt = 5-1; /*branch taken*/
|
||||
timing_bnt = 1; /*branch not taken*/
|
||||
break;
|
||||
|
||||
case CPU_WINCHIP:
|
||||
timing_rr = 1; /*register dest - register src*/
|
||||
timing_rm = 2; /*register dest - memory src*/
|
||||
timing_mr = 3; /*memory dest - register src*/
|
||||
timing_mm = 3;
|
||||
timing_rml = 2; /*register dest - memory src long*/
|
||||
timing_mrl = 3; /*memory dest - register src long*/
|
||||
timing_mml = 3;
|
||||
timing_bt = 3-1; /*branch taken*/
|
||||
timing_bnt = 1; /*branch not taken*/
|
||||
cpu_hasrdtsc = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -354,6 +412,7 @@ void cpu_CPUID()
|
|||
case CPU_Am486SX:
|
||||
if (!EAX)
|
||||
{
|
||||
EAX = 1;
|
||||
EBX = 0x68747541;
|
||||
ECX = 0x444D4163;
|
||||
EDX = 0x69746E65;
|
||||
|
|
@ -370,6 +429,7 @@ void cpu_CPUID()
|
|||
case CPU_Am486DX:
|
||||
if (!EAX)
|
||||
{
|
||||
EAX = 1;
|
||||
EBX = 0x68747541;
|
||||
ECX = 0x444D4163;
|
||||
EDX = 0x69746E65;
|
||||
|
|
@ -383,19 +443,37 @@ void cpu_CPUID()
|
|||
else
|
||||
EAX = 0;
|
||||
break;
|
||||
|
||||
case CPU_WINCHIP:
|
||||
if (!EAX)
|
||||
{
|
||||
EAX = 1;
|
||||
EBX = 0x746e6543; /*CentaurHauls*/
|
||||
ECX = 0x736c7561;
|
||||
EDX = 0x48727561;
|
||||
}
|
||||
else if (EAX == 1)
|
||||
{
|
||||
EAX = CPUID;
|
||||
EBX = ECX = 0;
|
||||
EDX = 1; /*FPU*/
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int cyrix_addr;
|
||||
|
||||
void cyrix_write(uint16_t addr, uint8_t val)
|
||||
void cyrix_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (!(addr & 1)) cyrix_addr = val;
|
||||
// else pclog("Write Cyrix %02X %02X\n",cyrix_addr,val);
|
||||
}
|
||||
|
||||
uint8_t cyrix_read(uint16_t addr)
|
||||
uint8_t cyrix_read(uint16_t addr, void *priv)
|
||||
{
|
||||
if (addr & 1)
|
||||
{
|
||||
|
|
|
|||
11
src/cpu.h
11
src/cpu.h
|
|
@ -22,9 +22,13 @@ extern int cpu, cpu_manufacturer;
|
|||
#define CPU_Cx486DX 12
|
||||
#define CPU_Cx5x86 13
|
||||
|
||||
/*586 class CPUs*/
|
||||
#define CPU_WINCHIP 14
|
||||
|
||||
#define MANU_INTEL 0
|
||||
#define MANU_AMD 1
|
||||
#define MANU_CYRIX 2
|
||||
#define MANU_IDT 3
|
||||
|
||||
extern int timing_rr;
|
||||
extern int timing_mr, timing_mrl;
|
||||
|
|
@ -55,6 +59,7 @@ extern CPU cpus_486SDLC[];
|
|||
extern CPU cpus_i486[];
|
||||
extern CPU cpus_Am486[];
|
||||
extern CPU cpus_Cx486[];
|
||||
extern CPU cpus_WinChip[];
|
||||
|
||||
extern CPU cpus_pc1512[];
|
||||
extern CPU cpus_ibmat[];
|
||||
|
|
@ -65,7 +70,9 @@ extern int cpu_16bitbus;
|
|||
extern int cpu_busspeed;
|
||||
extern int cpu_multi;
|
||||
|
||||
void cyrix_write(uint16_t addr, uint8_t val);
|
||||
uint8_t cyrix_read(uint16_t addr);
|
||||
extern int cpu_hasrdtsc;
|
||||
|
||||
void cyrix_write(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t cyrix_read(uint16_t addr, void *priv);
|
||||
|
||||
extern int is8086;
|
||||
|
|
|
|||
340
src/dma.c
340
src/dma.c
|
|
@ -1,7 +1,9 @@
|
|||
#include "ibm.h"
|
||||
#include "video.h"
|
||||
#include "io.h"
|
||||
|
||||
#include "dma.h"
|
||||
#include "fdc.h"
|
||||
#include "io.h"
|
||||
#include "video.h"
|
||||
|
||||
extern int ins;
|
||||
int output;
|
||||
|
|
@ -38,10 +40,10 @@ void dma_reset()
|
|||
dma16.m=0;
|
||||
}
|
||||
|
||||
uint8_t dma_read(uint16_t addr)
|
||||
uint8_t dma_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc);
|
||||
// printf("Read DMA %04X %04X:%04X %i %02X\n",addr,CS,pc, pic_intpending, pic.pend);
|
||||
switch (addr&0xF)
|
||||
{
|
||||
case 0:
|
||||
|
|
@ -69,7 +71,8 @@ uint8_t dma_read(uint16_t addr)
|
|||
case 8: /*Status register*/
|
||||
temp=dma.stat;
|
||||
dma.stat=0;
|
||||
return temp|1;
|
||||
// pclog("Read DMA status %02X\n", temp);
|
||||
return temp;
|
||||
case 0xD:
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -77,9 +80,9 @@ uint8_t dma_read(uint16_t addr)
|
|||
return dmaregs[addr&0xF];
|
||||
}
|
||||
|
||||
void dma_write(uint16_t addr, uint8_t val)
|
||||
void dma_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
dmaregs[addr&0xF]=val;
|
||||
switch (addr&0xF)
|
||||
{
|
||||
|
|
@ -122,7 +125,7 @@ void dma_write(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t dma16_read(uint16_t addr)
|
||||
uint8_t dma16_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc);
|
||||
|
|
@ -154,12 +157,12 @@ uint8_t dma16_read(uint16_t addr)
|
|||
case 8: /*Status register*/
|
||||
temp=dma16.stat;
|
||||
dma16.stat=0;
|
||||
return temp|1;
|
||||
return temp;
|
||||
}
|
||||
return dma16regs[addr&0xF];
|
||||
}
|
||||
|
||||
void dma16_write(uint16_t addr, uint8_t val)
|
||||
void dma16_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
addr>>=1;
|
||||
|
|
@ -205,14 +208,14 @@ void dma16_write(uint16_t addr, uint8_t val)
|
|||
}
|
||||
|
||||
uint8_t dmapages[16];
|
||||
static int primed = 0;
|
||||
void dma_page_write(uint16_t addr, uint8_t val)
|
||||
|
||||
void dma_page_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (!(addr&0xF))
|
||||
{
|
||||
// printf("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
/* if (!(addr&0xF))
|
||||
{*/
|
||||
pclog("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
// if (val==0x29 && pc==0xD25) output=1;
|
||||
}
|
||||
// }
|
||||
dmapages[addr&0xF]=val;
|
||||
switch (addr&0xF)
|
||||
{
|
||||
|
|
@ -233,21 +236,21 @@ void dma_page_write(uint16_t addr, uint8_t val)
|
|||
// printf("Page write %04X %02X\n",addr,val);
|
||||
}
|
||||
|
||||
uint8_t dma_page_read(uint16_t addr)
|
||||
uint8_t dma_page_read(uint16_t addr, void *priv)
|
||||
{
|
||||
return dmapages[addr&0xF];
|
||||
}
|
||||
|
||||
void dma_init()
|
||||
{
|
||||
io_sethandler(0x0000, 0x0010, dma_read, NULL, NULL, dma_write, NULL, NULL);
|
||||
io_sethandler(0x0080, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL);
|
||||
io_sethandler(0x0000, 0x0010, dma_read, NULL, NULL, dma_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0080, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void dma16_init()
|
||||
{
|
||||
io_sethandler(0x00C0, 0x0020, dma16_read, NULL, NULL, dma16_write, NULL, NULL);
|
||||
io_sethandler(0x0088, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL);
|
||||
io_sethandler(0x00C0, 0x0020, dma16_read, NULL, NULL, dma16_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0088, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -256,11 +259,11 @@ uint8_t _dma_read(uint32_t addr)
|
|||
switch (addr&0xFFFF8000)
|
||||
{
|
||||
case 0xA0000: case 0xA8000:
|
||||
return video_read_a000(addr);
|
||||
return video_read_a000(addr, NULL);
|
||||
case 0xB0000:
|
||||
return video_read_b000(addr);
|
||||
return video_read_b000(addr, NULL);
|
||||
case 0xB8000:
|
||||
return video_read_b800(addr);
|
||||
return video_read_b800(addr, NULL);
|
||||
}
|
||||
if (isram[addr>>16]) return ram[addr];
|
||||
return 0xff;
|
||||
|
|
@ -271,19 +274,20 @@ void _dma_write(uint32_t addr, uint8_t val)
|
|||
switch (addr&0xFFFF8000)
|
||||
{
|
||||
case 0xA0000: case 0xA8000:
|
||||
video_write_a000(addr,val);
|
||||
video_write_a000(addr,val, NULL);
|
||||
return;
|
||||
case 0xB0000:
|
||||
video_write_b000(addr,val);
|
||||
video_write_b000(addr,val, NULL);
|
||||
return;
|
||||
case 0xB8000:
|
||||
video_write_b800(addr,val);
|
||||
video_write_b800(addr,val, NULL);
|
||||
return;
|
||||
case 0xC0000: case 0xC8000: case 0xD0000: case 0xD8000:
|
||||
case 0xE0000: case 0xE8000: case 0xF0000: case 0xF8000:
|
||||
return;
|
||||
}
|
||||
if (isram[addr>>16]) ram[addr]=val;
|
||||
if (isram[addr >> 16])
|
||||
ram[addr] = val;
|
||||
}
|
||||
/*void writedma2(uint8_t val)
|
||||
{
|
||||
|
|
@ -301,10 +305,144 @@ void _dma_write(uint32_t addr, uint8_t val)
|
|||
}
|
||||
}*/
|
||||
|
||||
int dma_channel_read(int channel)
|
||||
{
|
||||
uint16_t temp;
|
||||
|
||||
if (channel < 4)
|
||||
{
|
||||
// pclog("Read DMA channel %i\n", channel);
|
||||
if (dma.m & (1 << channel))
|
||||
return DMA_NODATA;
|
||||
if ((dma.mode[channel] & 0xC) != 8)
|
||||
return DMA_NODATA;
|
||||
temp = _dma_read(dma.ac[channel] + (dma.page[channel] << 16)); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
|
||||
// pclog(" - %02X %05X\n", temp, dma.ac[channel] + (dma.page[channel] << 16));
|
||||
if (dma.mode[channel] & 0x20) dma.ac[channel]--;
|
||||
else dma.ac[channel]++;
|
||||
dma.cc[channel]--;
|
||||
if (!dma.cc[channel] && (dma.mode[channel] & 0x10))
|
||||
{
|
||||
dma.cc[channel] = dma.cb[channel] + 1;
|
||||
dma.ac[channel] = dma.ab[channel];
|
||||
dma.stat |= (1 << channel);
|
||||
}
|
||||
else if (dma.cc[channel]<=-1)
|
||||
{
|
||||
dma.m |= (1 << channel);
|
||||
dma.stat |= (1 << channel);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel &= 3;
|
||||
if (dma16.m & (1 << channel))
|
||||
return DMA_NODATA;
|
||||
if ((dma16.mode[channel] & 0xC) != 8)
|
||||
return DMA_NODATA;
|
||||
temp = _dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16)) |
|
||||
(_dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1) << 8);
|
||||
if (dma16.mode[channel] & 0x20) dma16.ac[channel]--;
|
||||
else dma16.ac[channel]++;
|
||||
dma16.cc[channel]--;
|
||||
if (!dma16.cc[channel] && (dma16.mode[channel] & 0x10))
|
||||
{
|
||||
dma16.cc[channel] = dma16.cb[channel] + 1;
|
||||
dma16.ac[channel] = dma16.ab[channel];
|
||||
dma16.stat |= (1 << channel);
|
||||
}
|
||||
else if (dma16.cc[channel]<=-1)
|
||||
{
|
||||
dma16.m |= (1 << channel);
|
||||
dma16.stat |= (1 << channel);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
int dma_channel_write(int channel, uint16_t val)
|
||||
{
|
||||
if (channel < 4)
|
||||
{
|
||||
if (dma.m & (1 << channel))
|
||||
return DMA_NODATA;
|
||||
if ((dma.mode[channel] & 0xC) != 4)
|
||||
return DMA_NODATA;
|
||||
_dma_write(dma.ac[channel] + (dma.page[channel] << 16), val);
|
||||
if (dma.mode[channel]&0x20) dma.ac[channel]--;
|
||||
else dma.ac[channel]++;
|
||||
dma.cc[channel]--;
|
||||
if (!dma.cc[channel] && (dma.mode[channel] & 0x10))
|
||||
{
|
||||
dma.cc[channel] = dma.cb[channel] + 1;
|
||||
dma.ac[channel] = dma.ab[channel];
|
||||
dma.stat |= (1 << channel);
|
||||
}
|
||||
else if (dma.cc[channel]<=-1)
|
||||
{
|
||||
dma.m |= (1 << channel);
|
||||
dma.stat |= (1 << channel);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
channel &= 3;
|
||||
if (dma16.m & (1 << channel))
|
||||
return DMA_NODATA;
|
||||
if ((dma16.mode[channel] & 0xC) != 4)
|
||||
return DMA_NODATA;
|
||||
_dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16), val);
|
||||
_dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1, val >> 8);
|
||||
if (dma16.mode[channel]&0x20) dma16.ac[channel]--;
|
||||
else dma16.ac[channel]++;
|
||||
dma16.cc[channel]--;
|
||||
if (!dma16.cc[channel] && (dma16.mode[channel] & 0x10))
|
||||
{
|
||||
dma16.cc[channel] = dma16.cb[channel] + 1;
|
||||
dma16.ac[channel] = dma16.ab[channel];
|
||||
dma16.stat |= (1 << channel);
|
||||
}
|
||||
else if (dma16.cc[channel] <= -1)
|
||||
{
|
||||
dma16.m |= (1 << channel);
|
||||
dma16.stat |= (1 << channel);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int sbbufferpos;
|
||||
int readdma1()
|
||||
{
|
||||
uint8_t temp;
|
||||
pclog("readdma1 : Read DMA1 %02X %02X %i\n",dma.m,dma.mode[1], dma.cc[1]);
|
||||
if (dma.m & (1 << 1))
|
||||
return DMA_NODATA;
|
||||
if ((dma.mode[1]&0xC)!=8)
|
||||
return DMA_NODATA;
|
||||
temp=_dma_read((dma.ac[1]+(dma.page[1]<<16))&rammask); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
|
||||
pclog("readdma1 : DMA1 %02X %05X\n",temp,(dma.ac[1]+(dma.page[1]<<16))&rammask);
|
||||
if (dma.mode[1]&0x20) dma.ac[1]--;
|
||||
else dma.ac[1]++;
|
||||
dma.cc[1]--;
|
||||
if (!dma.cc[1] && (dma.mode[1]&0x10))
|
||||
{
|
||||
dma.cc[1]=dma.cb[1]+1;
|
||||
dma.ac[1]=dma.ab[1];
|
||||
dma.stat |= (1 << 1);
|
||||
}
|
||||
else if (dma.cc[1]<=-1)
|
||||
{
|
||||
dma.m |= (1 << 1);
|
||||
dma.stat |= (1 << 1);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
uint8_t readdma2()
|
||||
{
|
||||
uint8_t temp;
|
||||
// pclog("Read DMA2 %02X %02X\n",dma.m,dma.mode[2]);
|
||||
// pclog("Read DMA2 %02X %02X %i\n",dma.m,dma.mode[2], dma.cc[2]);
|
||||
if (dma.m&4)
|
||||
{
|
||||
fdc_abort();
|
||||
|
|
@ -324,12 +462,68 @@ uint8_t readdma2()
|
|||
{
|
||||
dma.cc[2]=dma.cb[2]+1;
|
||||
dma.ac[2]=dma.ab[2];
|
||||
dma.stat |= (1 << 2);
|
||||
}
|
||||
else if (dma.cc[2]<=-1)
|
||||
dma.m|=4;
|
||||
{
|
||||
dma.m|=4;
|
||||
dma.stat |= (1 << 2);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
int readdma3()
|
||||
{
|
||||
uint8_t temp;
|
||||
// pclog("Read DMA1 %02X %02X %i\n",dma.m,dma.mode[1], dma.cc[1]);
|
||||
if (dma.m & (1 << 3))
|
||||
return DMA_NODATA;
|
||||
if ((dma.mode[3]&0xC)!=8)
|
||||
return DMA_NODATA;
|
||||
temp=_dma_read((dma.ac[3]+(dma.page[3]<<16))&rammask); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
|
||||
//pclog("DMA3 %02X %05X\n",temp,(dma.ac[3]+(dma.page[3]<<16))&rammask);
|
||||
if (dma.mode[3]&0x20) dma.ac[3]--;
|
||||
else dma.ac[3]++;
|
||||
dma.cc[3]--;
|
||||
if (!dma.cc[3] && (dma.mode[3]&0x10))
|
||||
{
|
||||
dma.cc[3]=dma.cb[3]+1;
|
||||
dma.ac[3]=dma.ab[3];
|
||||
dma.stat |= (1 << 3);
|
||||
}
|
||||
else if (dma.cc[3]<=-1)
|
||||
{
|
||||
dma.m |= (1 << 3);
|
||||
dma.stat |= (1 << 3);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
void writedma1(uint8_t temp)
|
||||
{
|
||||
// pclog("Write DMA1 %02X %02X %04X\n",dma.m,dma.mode[1],dma.cc[1]);
|
||||
if (dma.m & (1 << 1))
|
||||
return;
|
||||
if ((dma.mode[1] & 0xC) != 4)
|
||||
return;
|
||||
// pclog("Write %05X %05X %02X\n",(dma.ac[2]+(dma.page[2]<<16)),rammask,temp);
|
||||
// ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]=temp;
|
||||
_dma_write((dma.ac[1]+(dma.page[1]<<16))&rammask,temp);
|
||||
if (dma.mode[1]&0x20) dma.ac[1]--;
|
||||
else dma.ac[1]++;
|
||||
dma.cc[1]--;
|
||||
if (!dma.cc[1] && (dma.mode[1]&0x10))
|
||||
{
|
||||
dma.cc[1]=dma.cb[1]+1;
|
||||
dma.ac[1]=dma.ab[1];
|
||||
dma.stat |= (1 << 1);
|
||||
}
|
||||
else if (dma.cc[1]<=-1)
|
||||
{
|
||||
// pclog("Reached TC\n");
|
||||
dma.m |= (1 << 1);
|
||||
dma.stat |= (1 << 1);
|
||||
}
|
||||
}
|
||||
void writedma2(uint8_t temp)
|
||||
{
|
||||
// pclog("Write DMA2 %02X %02X %04X\n",dma.m,dma.mode[2],dma.cc[2]);
|
||||
|
|
@ -353,35 +547,41 @@ void writedma2(uint8_t temp)
|
|||
{
|
||||
dma.cc[2]=dma.cb[2]+1;
|
||||
dma.ac[2]=dma.ab[2];
|
||||
dma.stat |= (1 << 2);
|
||||
}
|
||||
else if (dma.cc[2]<=-1)
|
||||
{
|
||||
// pclog("Reached TC\n");
|
||||
fdc_abort();
|
||||
dma.m|=4;
|
||||
dma.stat |= (1 << 2);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t readdma1()
|
||||
void writedma3(uint8_t temp)
|
||||
{
|
||||
uint8_t temp=0;
|
||||
/*if ((dma.ac[1]+(dma.page[1]<<16))<0x800000) */temp=ram[(dma.ac[1]+(dma.page[1]<<16))&rammask];
|
||||
// printf("Read DMA1 from %05X %02X %04X %02X %i\n",dma.ac[1]+(dma.page[1]<<16),dma.mode[1],dma.cc[1],temp,dmaon[1]);
|
||||
if (!dmaon[1])
|
||||
// pclog("Write DMA3 %02X %02X %04X\n",dma.m,dma.mode[3],dma.cc[3]);
|
||||
if (dma.m & (1 << 3))
|
||||
return;
|
||||
if ((dma.mode[3] & 0xC) != 4)
|
||||
return;
|
||||
// pclog("Write %05X %05X %02X\n",(dma.ac[2]+(dma.page[2]<<16)),rammask,temp);
|
||||
// ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]=temp;
|
||||
_dma_write((dma.ac[3]+(dma.page[3]<<16))&rammask,temp);
|
||||
if (dma.mode[3]&0x20) dma.ac[3]--;
|
||||
else dma.ac[3]++;
|
||||
dma.cc[3]--;
|
||||
if (!dma.cc[3] && (dma.mode[3]&0x10))
|
||||
{
|
||||
// printf("DMA off!\n");
|
||||
return temp;
|
||||
dma.cc[3]=dma.cb[3]+1;
|
||||
dma.ac[3]=dma.ab[3];
|
||||
dma.stat |= (1 << 3);
|
||||
}
|
||||
dma.ac[1]++;
|
||||
dma.cc[1]--;
|
||||
if (dma.cc[1]<=-1 && (dma.mode[1]&0x10))
|
||||
else if (dma.cc[3]<=-1)
|
||||
{
|
||||
dma.cc[1]=dma.cb[1];
|
||||
dma.ac[1]=dma.ab[1];
|
||||
// pclog("Reached TC\n");
|
||||
dma.m |= (1 << 3);
|
||||
dma.stat |= (1 << 3);
|
||||
}
|
||||
else if (dma.cc[1]<=-1)
|
||||
dmaon[1]=0;
|
||||
return temp;
|
||||
}
|
||||
|
||||
uint16_t readdma5()
|
||||
|
|
@ -402,26 +602,16 @@ uint16_t readdma5()
|
|||
{
|
||||
dma16.cc[1]=dma16.cb[1];
|
||||
dma16.ac[1]=dma16.ab[1];
|
||||
dma16.stat |= (1 << 1);
|
||||
}
|
||||
else if (dma16.cc[1]<=-1)
|
||||
dma16on[1]=0;
|
||||
{
|
||||
dma16on[1]=0;
|
||||
dma16.stat |= (1 << 1);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
void writedma1(uint8_t temp)
|
||||
{
|
||||
if (!dmaon[1]) return;
|
||||
ram[(dma.ac[1]+(dma.page[1]<<16))&rammask]=temp;
|
||||
dma.ac[1]++;
|
||||
dma.cc[1]--;
|
||||
if (!dma.cc[1] && (dma.mode[1]&0x10))
|
||||
{
|
||||
dma.cc[1]=dma.cb[1]+1;
|
||||
dma.ac[1]=dma.ab[1];
|
||||
}
|
||||
else if (dma.cc[1]<=-1)
|
||||
dmaon[1]=0;
|
||||
}
|
||||
void writedma5(uint16_t temp)
|
||||
{
|
||||
if (!dma16on[1]) return;
|
||||
|
|
@ -434,31 +624,15 @@ void writedma5(uint16_t temp)
|
|||
{
|
||||
dma16.cc[1]=dma16.cb[1];
|
||||
dma16.ac[1]=dma16.ab[1];
|
||||
dma16.stat |= (1 << 1);
|
||||
}
|
||||
else if (dma16.cc[1]<=-1)
|
||||
dma16on[1]=0;
|
||||
{
|
||||
dma16on[1]=0;
|
||||
dma16.stat |= (1 << 1);
|
||||
}
|
||||
}
|
||||
|
||||
int readdma3()
|
||||
{
|
||||
uint8_t temp=ram[((dma.page[3]<<16)+dma.ac[3])&rammask];
|
||||
if (dma.m&8)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
// printf("Read DMA 3 - %02X %05X %i\n",temp,(dma.page[3]<<16)+dma.ac[3],dma.cc[3]);
|
||||
if (!(dma.m&8))
|
||||
{
|
||||
dma.ac[3]++;
|
||||
dma.cc[3]--;
|
||||
if (dma.cc[3]==-1)
|
||||
{
|
||||
dma.m|=8;
|
||||
dma.stat|=8;
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
void readdma0()
|
||||
{
|
||||
if (AT) ppi.pb^=0x10;
|
||||
|
|
@ -474,9 +648,9 @@ void readdma0()
|
|||
dma.cc[0]--;
|
||||
if (dma.cc[0]==-1)
|
||||
{
|
||||
dma.stat|=1;
|
||||
dma.ac[0]=dma.ab[0];
|
||||
dma.cc[0]=dma.cb[0];
|
||||
dma.stat |= 1;
|
||||
}
|
||||
// }
|
||||
// ppi.pb^=0x10;
|
||||
|
|
|
|||
12
src/dma.h
12
src/dma.h
|
|
@ -1,3 +1,15 @@
|
|||
void dma_init();
|
||||
void dma16_init();
|
||||
void dma_reset();
|
||||
|
||||
#define DMA_NODATA -1
|
||||
|
||||
void readdma0();
|
||||
int readdma1();
|
||||
uint8_t readdma2();
|
||||
int readdma3();
|
||||
|
||||
void writedma2(uint8_t temp);
|
||||
|
||||
int dma_channel_read(int channel);
|
||||
int dma_channel_write(int channel, uint16_t val);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ uint8_t svga3d8;
|
|||
|
||||
uint8_t oldvram=0;
|
||||
int frames;
|
||||
int incga=1;
|
||||
int hsync;
|
||||
uint8_t cgastat;
|
||||
|
||||
|
|
@ -36,7 +35,7 @@ uint8_t *vram;
|
|||
|
||||
int egares;
|
||||
|
||||
uint8_t seqregs[32];
|
||||
uint8_t seqregs[64];
|
||||
int seqaddr;
|
||||
|
||||
uint8_t oak_regs[32];
|
||||
|
|
@ -54,7 +53,8 @@ int palchange=1;
|
|||
|
||||
int fullchange;
|
||||
|
||||
float dispontime,dispofftime,disptime;
|
||||
int dispontime,dispofftime;
|
||||
double disptime;
|
||||
|
||||
int ega_vtotal,ega_dispend,ega_vsyncstart,ega_split,ega_hdisp,ega_rowoffset;
|
||||
int vidclock;
|
||||
|
|
@ -135,8 +135,6 @@ void initega()
|
|||
}
|
||||
}
|
||||
crtc[0xC]=crtc[0xD]=0;
|
||||
if (romset==ROM_PC1640 || romset==ROM_PC1512) incga=1;
|
||||
else incga=0;
|
||||
for (c=0;c<4;c++)
|
||||
{
|
||||
for (d=0;d<4;d++)
|
||||
|
|
@ -277,6 +275,7 @@ int ega_getdepth()
|
|||
if (TRIDENT || ET4000W32) return bpp;
|
||||
return 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ega_getx()
|
||||
|
|
|
|||
104
src/fdc.c
104
src/fdc.c
|
|
@ -2,6 +2,11 @@
|
|||
#include <string.h>
|
||||
#include "ibm.h"
|
||||
|
||||
#include "dma.h"
|
||||
#include "io.h"
|
||||
#include "pic.h"
|
||||
#include "timer.h"
|
||||
|
||||
void fdc_poll();
|
||||
int timetolive;
|
||||
int TRACKS[2] = {80, 80};
|
||||
|
|
@ -105,9 +110,8 @@ void fdc_reset()
|
|||
}
|
||||
int ins;
|
||||
|
||||
void fdc_write(uint16_t addr, uint8_t val)
|
||||
void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int c;
|
||||
// printf("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate);
|
||||
switch (addr&7)
|
||||
{
|
||||
|
|
@ -122,7 +126,9 @@ void fdc_write(uint16_t addr, uint8_t val)
|
|||
}
|
||||
if ((val&4) && !(fdc.dor&4))
|
||||
{
|
||||
disctime=128;
|
||||
timer_process();
|
||||
disctime = 128 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
discint=-1;
|
||||
fdc_reset();
|
||||
}
|
||||
|
|
@ -132,7 +138,9 @@ void fdc_write(uint16_t addr, uint8_t val)
|
|||
case 4:
|
||||
if (val & 0x80)
|
||||
{
|
||||
disctime=128;
|
||||
timer_process();
|
||||
disctime = 128 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
discint=-1;
|
||||
fdc_reset();
|
||||
}
|
||||
|
|
@ -247,7 +255,9 @@ void fdc_write(uint16_t addr, uint8_t val)
|
|||
// exit(-1);
|
||||
fdc.stat=0x10;
|
||||
discint=0xfc;
|
||||
disctime=200;
|
||||
timer_process();
|
||||
disctime = 200 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -259,7 +269,8 @@ void fdc_write(uint16_t addr, uint8_t val)
|
|||
// pclog("Got all params\n");
|
||||
fdc.stat=0x30;
|
||||
discint=fdc.command&0x1F;
|
||||
disctime=1024;
|
||||
timer_process();
|
||||
disctime = 1024 * (1 << TIMER_SHIFT);
|
||||
fdc.drive=fdc.params[0]&1;
|
||||
if (discint==2 || discint==5 || discint==6)
|
||||
{
|
||||
|
|
@ -285,13 +296,13 @@ void fdc_write(uint16_t addr, uint8_t val)
|
|||
{
|
||||
// pclog("Wrong rate %i %i\n",fdc.rate,discrate[fdc.drive]);
|
||||
discint=0xFF;
|
||||
disctime=1024;
|
||||
disctime = 1024 * (1 << TIMER_SHIFT);
|
||||
}
|
||||
if (driveempty[fdc.drive])
|
||||
{
|
||||
// pclog("Drive empty\n");
|
||||
discint=0xFE;
|
||||
disctime=1024;
|
||||
disctime = 1024 * (1 << TIMER_SHIFT);
|
||||
}
|
||||
}
|
||||
if (discint == 7 || discint == 0xf)
|
||||
|
|
@ -303,6 +314,7 @@ void fdc_write(uint16_t addr, uint8_t val)
|
|||
{
|
||||
fdc.head = (fdc.params[0] & 4) ? 1 : 0;
|
||||
}
|
||||
timer_update_outstanding();
|
||||
// if (discint==5) fdc.pos=512;
|
||||
}
|
||||
}
|
||||
|
|
@ -320,7 +332,7 @@ void fdc_write(uint16_t addr, uint8_t val)
|
|||
}
|
||||
|
||||
int paramstogo=0;
|
||||
uint8_t fdc_read(uint16_t addr)
|
||||
uint8_t fdc_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// /*if (addr!=0x3f4) */printf("Read FDC %04X %04X:%04X %04X %i %02X %i ",addr,cs>>4,pc,BX,fdc.pos,fdc.st0,ins);
|
||||
|
|
@ -360,7 +372,12 @@ uint8_t fdc_read(uint16_t addr)
|
|||
lastbyte=0;
|
||||
temp=fdc.dat;
|
||||
}
|
||||
if (discint==0xA) disctime=1024;
|
||||
if (discint==0xA)
|
||||
{
|
||||
timer_process();
|
||||
disctime = 1024 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
}
|
||||
fdc.stat &= 0xf0;
|
||||
break;
|
||||
case 7: /*Disk change*/
|
||||
|
|
@ -395,6 +412,7 @@ static int fdc_reset_stat = 0;
|
|||
void fdc_poll()
|
||||
{
|
||||
int temp;
|
||||
disctime = 0;
|
||||
// pclog("fdc_poll %08X %i %02X\n", discint, fdc.drive, fdc.st0);
|
||||
switch (discint)
|
||||
{
|
||||
|
|
@ -420,7 +438,9 @@ void fdc_poll()
|
|||
fdc.dat=disc[fdc.drive][fdc.head][fdc.track[fdc.drive]][fdc.sector-1][fdc.pos];
|
||||
// pclog("Read %i %i %i %i %02X\n",fdc.head,fdc.track,fdc.sector,fdc.pos,fdc.dat);
|
||||
writedma2(fdc.dat);
|
||||
disctime=60;
|
||||
timer_process();
|
||||
disctime = 60 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -437,17 +457,6 @@ void fdc_poll()
|
|||
fdc.res[9]=fdc.params[4];
|
||||
paramstogo=7;
|
||||
return;
|
||||
disctime=1024;
|
||||
picint(0x40);
|
||||
fdc.stat=0xD0;
|
||||
switch (fdc.pos-512)
|
||||
{
|
||||
case 0: case 1: case 2: fdc.dat=0; break;
|
||||
case 3: fdc.dat=fdc.track[fdc.drive]; break;
|
||||
case 4: fdc.dat=fdc.head; break;
|
||||
case 5: fdc.dat=fdc.sector; break;
|
||||
case 6: fdc.dat=fdc.params[4]; discint=-2; lastbyte=1; break;
|
||||
}
|
||||
}
|
||||
fdc.pos++;
|
||||
if (fdc.pos==512 && fdc.params[5]!=1)
|
||||
|
|
@ -491,14 +500,18 @@ void fdc_poll()
|
|||
{
|
||||
fdc_abort_f=0;
|
||||
discint=0xFD;
|
||||
disctime=50;
|
||||
timer_process();
|
||||
disctime = 50 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
fdc.dat=disc[fdc.drive][fdc.head][fdc.track[fdc.drive]][fdc.sector-1][fdc.pos]=temp;
|
||||
// printf("Write data %i %i %02X %i:%i:%i:%i\n",fdc.sector-1,fdc.pos,fdc.dat,fdc.head,fdc.track[fdc.drive],fdc.sector-1,fdc.pos);
|
||||
disctime=60;
|
||||
timer_process();
|
||||
disctime = 60 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -517,19 +530,6 @@ void fdc_poll()
|
|||
fdc.res[10]=fdc.params[4];
|
||||
paramstogo=7;
|
||||
return;
|
||||
disctime=1024;
|
||||
picint(0x40);
|
||||
fdc.stat=0xD0;
|
||||
switch (fdc.pos-512)
|
||||
{
|
||||
case 0: fdc.dat=0x40; break;
|
||||
case 1: fdc.dat=2; break;
|
||||
case 2: fdc.dat=0; break;
|
||||
case 3: fdc.dat=fdc.track[fdc.drive]; break;
|
||||
case 4: fdc.dat=fdc.head; break;
|
||||
case 5: fdc.dat=fdc.sector; break;
|
||||
case 6: fdc.dat=fdc.params[4]; discint=-2; break;
|
||||
}
|
||||
}
|
||||
fdc.pos++;
|
||||
if (fdc.pos==512 && fdc.sector!=fdc.params[5])
|
||||
|
|
@ -548,7 +548,9 @@ void fdc_poll()
|
|||
fdc.dat=disc[fdc.drive][fdc.head][fdc.track[fdc.drive]][fdc.sector-1][fdc.pos];
|
||||
// printf("Read disc %i %i %i %i %02X\n",fdc.head,fdc.track,fdc.sector,fdc.pos,fdc.dat);
|
||||
writedma2(fdc.dat);
|
||||
disctime=60;
|
||||
timer_process();
|
||||
disctime = 60 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -579,12 +581,12 @@ void fdc_poll()
|
|||
fdc.pos++;
|
||||
if (fdc.pos==512)// && fdc.sector!=fdc.params[5])
|
||||
{
|
||||
// printf("Sector complete! %02X\n",fdc.params[5]);
|
||||
// pclog("Sector complete! %02X\n",fdc.params[5]);
|
||||
fdc.pos=0;
|
||||
fdc.sector++;
|
||||
if (fdc.sector > fdc.params[5])
|
||||
{
|
||||
// printf("Overrunnit!\n");
|
||||
// pclog("Overrunnit! %02X\n", fdc.command & 0x80);
|
||||
// dumpregs();
|
||||
// exit(-1);
|
||||
fdc.sector=1;
|
||||
|
|
@ -617,7 +619,9 @@ void fdc_poll()
|
|||
if (!driveempty[fdc.dor & 1]) discchanged[fdc.dor & 1] = 0;
|
||||
fdc.st0=0x20|fdc.drive|(fdc.head?4:0);
|
||||
discint=-3;
|
||||
disctime=2048;
|
||||
timer_process();
|
||||
disctime = 2048 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
// printf("Recalibrate complete!\n");
|
||||
fdc.stat = 0x80 | (1 << fdc.drive);
|
||||
return;
|
||||
|
|
@ -663,7 +667,9 @@ void fdc_poll()
|
|||
// printf("Seeked to track %i %i\n",fdc.track[fdc.drive], fdc.drive);
|
||||
fdc.st0=0x20|fdc.drive|(fdc.head?4:0);
|
||||
discint=-3;
|
||||
disctime=2048;
|
||||
timer_process();
|
||||
disctime = 2048 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
fdc.stat = 0x80 | (1 << fdc.drive);
|
||||
// pclog("Stat %02X ST0 %02X\n", fdc.stat, fdc.st0);
|
||||
return;
|
||||
|
|
@ -792,15 +798,19 @@ void fdc_poll()
|
|||
// exit(-1);
|
||||
}
|
||||
|
||||
|
||||
void fdc_init()
|
||||
{
|
||||
io_sethandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL);
|
||||
io_sethandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL);
|
||||
timer_add(fdc_poll, &disctime, &disctime, NULL);
|
||||
}
|
||||
|
||||
void fdc_add()
|
||||
{
|
||||
io_sethandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void fdc_remove()
|
||||
{
|
||||
io_removehandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL);
|
||||
io_removehandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL);
|
||||
io_removehandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
void fdc_init();
|
||||
void fdc_add();
|
||||
void fdc_remove();
|
||||
void fdc_reset();
|
||||
void fdc_poll();
|
||||
void fdc_abort();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
static int headland_index;
|
||||
static uint8_t headland_regs[256];
|
||||
|
||||
void headland_write(uint16_t addr, uint8_t val)
|
||||
void headland_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (addr & 1)
|
||||
{
|
||||
|
|
@ -20,15 +20,15 @@ void headland_write(uint16_t addr, uint8_t val)
|
|||
shadowbios = val & 0x10;
|
||||
shadowbios_write = !(val & 0x10);
|
||||
if (shadowbios)
|
||||
mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL );
|
||||
mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL , NULL);
|
||||
else
|
||||
mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml);
|
||||
mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL);
|
||||
}
|
||||
}
|
||||
else headland_index = val;
|
||||
}
|
||||
|
||||
uint8_t headland_read(uint16_t addr)
|
||||
uint8_t headland_read(uint16_t addr, void *priv)
|
||||
{
|
||||
if (addr & 1)
|
||||
{
|
||||
|
|
@ -41,5 +41,5 @@ uint8_t headland_read(uint16_t addr)
|
|||
|
||||
void headland_init()
|
||||
{
|
||||
io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL);
|
||||
io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
78
src/ibm.h
78
src/ibm.h
|
|
@ -1,5 +1,6 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#define printf pclog
|
||||
|
||||
/*Memory*/
|
||||
|
|
@ -291,9 +292,8 @@ int driveempty[2];
|
|||
#define PCI (romset == ROM_PCI486)
|
||||
|
||||
#define AMIBIOS (romset==ROM_AMI386 || romset==ROM_AMI486 || romset == ROM_WIN486)
|
||||
int FASTDISC;
|
||||
int ADLIB;
|
||||
int GAMEBLASTER;
|
||||
|
||||
int GAMEBLASTER, GUS;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -320,7 +320,8 @@ enum
|
|||
ROM_AMI386,
|
||||
ROM_AMI486,
|
||||
ROM_WIN486,
|
||||
ROM_PCI486
|
||||
ROM_PCI486,
|
||||
ROM_430VX
|
||||
};
|
||||
|
||||
//#define ROM_IBMPCJR 5 /*Not working! ROMs are corrupt*/
|
||||
|
|
@ -337,10 +338,18 @@ int romset;
|
|||
//#define GFX_OTI067 3 /*Using BIOS from Acer 386SX/25N - edit - only works with Acer BIOS! Stupid integrated systems*/
|
||||
#define GFX_TVGA 4 /*Using Trident 8900D BIOS*/
|
||||
#define GFX_ET4000 5 /*Tseng ET4000*/
|
||||
#define GFX_ET4000W32 6 /*Tseng ET4000/W32p (Diamond Stealth 32)*/
|
||||
#define GFX_BAHAMAS64 7 /*S3 Vision864 (Paradise Bahamas 64)*/
|
||||
#define GFX_N9_9FX 8 /*S3 764/Trio64 (Number Nine 9FX)*/
|
||||
#define GFX_STEALTH64 9 /*S3 Vision964 (Diamond Stealth 64 VRAM PCI)*/
|
||||
#define GFX_ET4000W32 6 /*Tseng ET4000/W32p (Diamond Stealth 32)*/
|
||||
#define GFX_BAHAMAS64 7 /*S3 Vision864 (Paradise Bahamas 64)*/
|
||||
#define GFX_N9_9FX 8 /*S3 764/Trio64 (Number Nine 9FX)*/
|
||||
#define GFX_STEALTH64 9 /*S3 Vision964 (Diamond Stealth 64 VRAM PCI)*/
|
||||
#define GFX_VIRGE 10 /*S3 Virge*/
|
||||
#define GFX_TGUI9440 11 /*Trident TGUI9440*/
|
||||
#define GFX_VGA 12 /*IBM VGA*/
|
||||
#define GFX_VGAEDGE16 13 /*ATI VGA Edge-16 (18800-1)*/
|
||||
#define GFX_VGACHARGER 14 /*ATI VGA Charger (28800-5)*/
|
||||
#define GFX_OTI067 15 /*Oak OTI-067*/
|
||||
#define GFX_MACH64GX 16 /*ATI Graphics Pro Turbo (Mach64)*/
|
||||
#define GFX_CL_GD5429 17 /*Cirrus Logic CL-GD5429*/
|
||||
|
||||
int gfxcard;
|
||||
|
||||
|
|
@ -354,7 +363,6 @@ int readflash;
|
|||
uint8_t hercctrl;
|
||||
int slowega,egacycles,egacycles2;
|
||||
extern uint8_t gdcreg[16];
|
||||
extern int incga;
|
||||
extern int egareads,egawrites;
|
||||
extern int cga_comp;
|
||||
extern int vid_resize;
|
||||
|
|
@ -383,13 +391,10 @@ extern int mousedelay;
|
|||
/*Sound*/
|
||||
uint8_t spkstat;
|
||||
|
||||
float spktime,soundtime,gustime,gustime2,vidtime,rtctime;
|
||||
float spktime;
|
||||
int rtctime;
|
||||
int soundtime,gustime,gustime2,vidtime;
|
||||
int ppispeakon;
|
||||
//#define SPKCONST (8000000.0/44100.0)
|
||||
float SPKCONST;
|
||||
float SOUNDCONST;
|
||||
float CASCONST;
|
||||
float GUSCONST,GUSCONST2;
|
||||
float CGACONST;
|
||||
float MDACONST;
|
||||
float VGACONST1,VGACONST2;
|
||||
|
|
@ -400,38 +405,23 @@ int gated,speakval,speakon;
|
|||
|
||||
|
||||
/*Sound Blaster*/
|
||||
int sbenable,sblatchi,sblatcho,sbcount,sb_enable_i,sb_count_i;
|
||||
int16_t sbdat;
|
||||
/*int sbenable,sblatchi,sblatcho,sbcount,sb_enable_i,sb_count_i;
|
||||
int16_t sbdat;*/
|
||||
void setsbclock(float clock);
|
||||
|
||||
#define SADLIB 1 /*No DSP*/
|
||||
#define SB1 2 /*DSP v1.05*/
|
||||
#define SB15 3 /*DSP v2.00*/
|
||||
#define SB2 4 /*DSP v2.01 - needed for high-speed DMA*/
|
||||
#define SBPRO 5 /*DSP v3.00*/
|
||||
#define SBPRO2 6 /*DSP v3.02 + OPL3*/
|
||||
#define SB16 7 /*DSP v4.05 + OPL3*/
|
||||
#define SADLIB 1 /*No DSP*/
|
||||
#define SB1 2 /*DSP v1.05*/
|
||||
#define SB15 3 /*DSP v2.00*/
|
||||
#define SB2 4 /*DSP v2.01 - needed for high-speed DMA*/
|
||||
#define SBPRO 5 /*DSP v3.00*/
|
||||
#define SBPRO2 6 /*DSP v3.02 + OPL3*/
|
||||
#define SB16 7 /*DSP v4.05 + OPL3*/
|
||||
#define SADGOLD 8 /*AdLib Gold*/
|
||||
#define SND_WSS 9 /*Windows Sound System*/
|
||||
#define SND_PAS16 10 /*Pro Audio Spectrum 16*/
|
||||
|
||||
int sbtype;
|
||||
|
||||
struct
|
||||
{
|
||||
int vocl,vocr,voc;
|
||||
int midl,midr,mid;
|
||||
int masl,masr,mas;
|
||||
} sbpmixer;
|
||||
extern int sb_freq;
|
||||
|
||||
struct
|
||||
{
|
||||
int master_l,master_r;
|
||||
int voice_l,voice_r;
|
||||
int fm_l,fm_r;
|
||||
int bass_l,bass_r;
|
||||
int treble_l,treble_r;
|
||||
int filter;
|
||||
} mixer;
|
||||
|
||||
|
||||
int clocks[3][12][4];
|
||||
int at70hz;
|
||||
|
||||
|
|
@ -466,3 +456,5 @@ extern int times;
|
|||
|
||||
|
||||
extern float isa_timing, bus_timing;
|
||||
|
||||
extern int frame;
|
||||
|
|
|
|||
388
src/ide.c
388
src/ide.c
|
|
@ -2,7 +2,7 @@
|
|||
IDE emulation*/
|
||||
//#define RPCEMU_IDE
|
||||
|
||||
#define IDE_TIME 5
|
||||
#define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT))
|
||||
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
|
|
@ -20,6 +20,9 @@
|
|||
#include "arm.h"
|
||||
#else
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "pic.h"
|
||||
#include "timer.h"
|
||||
#endif
|
||||
#include "ide.h"
|
||||
|
||||
|
|
@ -50,6 +53,11 @@
|
|||
#define WIN_SPECIFY 0x91 /* Initialize Drive Parameters */
|
||||
#define WIN_PACKETCMD 0xA0 /* Send a packet command. */
|
||||
#define WIN_PIDENTIFY 0xA1 /* Identify ATAPI device */
|
||||
#define WIN_READ_MULTIPLE 0xC4
|
||||
#define WIN_WRITE_MULTIPLE 0xC5
|
||||
#define WIN_SET_MULTIPLE_MODE 0xC6
|
||||
#define WIN_READ_DMA 0xC8
|
||||
#define WIN_WRITE_DMA 0xCA
|
||||
#define WIN_SETIDLE1 0xE3
|
||||
#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */
|
||||
|
||||
|
|
@ -134,6 +142,7 @@ typedef struct IDE
|
|||
int lba;
|
||||
uint32_t lba_addr;
|
||||
int skip512;
|
||||
int blocksize, blockcount;
|
||||
} IDE;
|
||||
|
||||
IDE ide_drives[4];
|
||||
|
|
@ -142,6 +151,10 @@ IDE *ext_ide;
|
|||
|
||||
char ide_fn[2][512];
|
||||
|
||||
int (*ide_bus_master_read_sector)(int channel, uint8_t *data);
|
||||
int (*ide_bus_master_write_sector)(int channel, uint8_t *data);
|
||||
void (*ide_bus_master_set_irq)(int channel);
|
||||
|
||||
static void callreadcd(IDE *ide);
|
||||
static void atapicommand(int ide_board);
|
||||
|
||||
|
|
@ -272,8 +285,15 @@ static void ide_identify(IDE *ide)
|
|||
#else
|
||||
ide_padstr((char *) (ide->buffer + 27), "PCemHD", 40); /* Model */
|
||||
#endif
|
||||
ide->buffer[49] = (1<<9); /* LBA supported */
|
||||
ide->buffer[20] = 3; /*Buffer type*/
|
||||
ide->buffer[21] = 512; /*Buffer size*/
|
||||
ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/
|
||||
ide->buffer[48] = 1; /*Dword transfers supported*/
|
||||
ide->buffer[49] = (1 << 9) | (1 << 8); /* LBA and DMA supported */
|
||||
ide->buffer[50] = 0x4000; /* Capabilities */
|
||||
ide->buffer[51] = 2 << 8; /*PIO timing mode*/
|
||||
ide->buffer[52] = 2 << 8; /*DMA timing mode*/
|
||||
ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0;
|
||||
#ifdef RPCEMU_IDE
|
||||
ide->buffer[60] = (65535 * 16 * 63) & 0xFFFF; /* Total addressable sectors (LBA) */
|
||||
ide->buffer[61] = (65535 * 16 * 63) >> 16;
|
||||
|
|
@ -281,6 +301,8 @@ static void ide_identify(IDE *ide)
|
|||
ide->buffer[60] = (hdc[cur_ide[0]].tracks * hdc[cur_ide[0]].hpc * hdc[cur_ide[0]].spt) & 0xFFFF; /* Total addressable sectors (LBA) */
|
||||
ide->buffer[61] = (hdc[cur_ide[0]].tracks * hdc[cur_ide[0]].hpc * hdc[cur_ide[0]].spt) >> 16;
|
||||
#endif
|
||||
ide->buffer[63] = 7; /*Multiword DMA*/
|
||||
ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -571,7 +593,9 @@ void writeidew(int ide_board, uint16_t val)
|
|||
if (ide->pos>=(ide->packlen+2))
|
||||
{
|
||||
ide->packetstatus=5;
|
||||
timer_process();
|
||||
idecallback[ide_board]=6*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
// pclog("Packet over!\n");
|
||||
ide_irq_lower(ide);
|
||||
}
|
||||
|
|
@ -583,8 +607,10 @@ void writeidew(int ide_board, uint16_t val)
|
|||
ide->pos=0;
|
||||
ide->atastat = BUSY_STAT;
|
||||
ide->packetstatus=1;
|
||||
idecallback[ide_board]=6*IDE_TIME;
|
||||
/* idecallback[ide_board]=6*IDE_TIME;*/
|
||||
timer_process();
|
||||
callbackide(ide_board);
|
||||
timer_update_outstanding();
|
||||
// idecallback[ide_board]=60*IDE_TIME;
|
||||
// if ((ide->buffer[0]&0xFF)==0x43) idecallback[ide_board]=1*IDE_TIME;
|
||||
// pclog("Packet now waiting!\n");
|
||||
|
|
@ -598,15 +624,25 @@ void writeidew(int ide_board, uint16_t val)
|
|||
{
|
||||
ide->pos=0;
|
||||
ide->atastat = BUSY_STAT;
|
||||
idecallback[ide_board]=6*IDE_TIME;
|
||||
// callbackide(ide_board);
|
||||
timer_process();
|
||||
if (ide->command == WIN_WRITE_MULTIPLE)
|
||||
callbackide(ide_board);
|
||||
else
|
||||
idecallback[ide_board]=6*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
}
|
||||
}
|
||||
|
||||
void writeidel(int ide_board, uint32_t val)
|
||||
{
|
||||
// pclog("WriteIDEl %08X\n", val);
|
||||
writeidew(ide_board, val);
|
||||
writeidew(ide_board, val >> 16);
|
||||
}
|
||||
|
||||
void writeide(int ide_board, uint16_t addr, uint8_t val)
|
||||
{
|
||||
IDE *ide = &ide_drives[cur_ide[ide_board]];
|
||||
uint8_t *idebufferb = (uint8_t *) ide->buffer;
|
||||
#ifndef RPCEMU_IDE
|
||||
/* if (ide_board && (cr0&1) && !(eflags&VM_FLAG))
|
||||
{
|
||||
|
|
@ -614,6 +650,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|||
return;
|
||||
}*/
|
||||
#endif
|
||||
// if ((cr0&1) && !(eflags&VM_FLAG))
|
||||
// pclog("WriteIDE %04X %02X from %04X(%08X):%08X\n", addr, val, CS, cs, pc);
|
||||
// return;
|
||||
addr|=0x80;
|
||||
// if (ide_board) pclog("Write IDEb %04X %02X %04X(%08X):%04X %i %02X %02X\n",addr,val,CS,cs,pc,ins,ide->atastat,ide_drives[0].atastat);
|
||||
|
|
@ -660,9 +698,26 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|||
dumpregs();
|
||||
exit(-1);
|
||||
}*/
|
||||
cur_ide[ide_board]=((val>>4)&1)+(ide_board<<1);
|
||||
ide = &ide_drives[cur_ide[ide_board]];
|
||||
|
||||
|
||||
if (cur_ide[ide_board] != ((val>>4)&1)+(ide_board<<1))
|
||||
{
|
||||
cur_ide[ide_board]=((val>>4)&1)+(ide_board<<1);
|
||||
|
||||
if (ide->reset)
|
||||
{
|
||||
ide->atastat = READY_STAT | DSC_STAT;
|
||||
ide->error=1;
|
||||
ide->secount=1;
|
||||
ide->sector=1;
|
||||
ide->head=0;
|
||||
ide->cylinder=0;
|
||||
ide->reset = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ide = &ide_drives[cur_ide[ide_board]];
|
||||
}
|
||||
|
||||
ide->head=val&0xF;
|
||||
ide->lba=val&0x40;
|
||||
|
||||
|
|
@ -684,17 +739,32 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|||
case WIN_SRST: /* ATAPI Device Reset */
|
||||
if (IDE_DRIVE_IS_CDROM(ide)) ide->atastat = BUSY_STAT;
|
||||
else ide->atastat = READY_STAT;
|
||||
timer_process();
|
||||
idecallback[ide_board]=100*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
return;
|
||||
|
||||
case WIN_RESTORE:
|
||||
case WIN_SEEK:
|
||||
// pclog("WIN_RESTORE start\n");
|
||||
ide->atastat = READY_STAT;
|
||||
timer_process();
|
||||
idecallback[ide_board]=100*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
return;
|
||||
|
||||
case WIN_READ_MULTIPLE:
|
||||
if (!ide->blocksize)
|
||||
fatal("READ_MULTIPLE - blocksize = 0\n");
|
||||
#if 0
|
||||
if (ide->lba) pclog("Read Multiple %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr);
|
||||
else pclog("Read Multiple %i sectors from sector %i cylinder %i head %i %i\n",ide->secount,ide->sector,ide->cylinder,ide->head,ins);
|
||||
#endif
|
||||
ide->blockcount = 0;
|
||||
|
||||
case WIN_READ:
|
||||
case WIN_READ_NORETRY:
|
||||
case WIN_READ_DMA:
|
||||
/* if (ide.secount>1)
|
||||
{
|
||||
fatal("Read %i sectors from sector %i cylinder %i head %i\n",ide.secount,ide.sector,ide.cylinder,ide.head);
|
||||
|
|
@ -704,12 +774,23 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|||
else pclog("Read %i sectors from sector %i cylinder %i head %i %i\n",ide->secount,ide->sector,ide->cylinder,ide->head,ins);
|
||||
#endif
|
||||
ide->atastat = BUSY_STAT;
|
||||
timer_process();
|
||||
idecallback[ide_board]=200*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
return;
|
||||
|
||||
|
||||
case WIN_WRITE_MULTIPLE:
|
||||
if (!ide->blocksize)
|
||||
fatal("Write_MULTIPLE - blocksize = 0\n");
|
||||
#if 0
|
||||
if (ide->lba) pclog("Write Multiple %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr);
|
||||
else pclog("Write Multiple %i sectors to sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head);
|
||||
#endif
|
||||
ide->blockcount = 0;
|
||||
|
||||
case WIN_WRITE:
|
||||
case WIN_WRITE_NORETRY:
|
||||
/* if (ide.secount>1)
|
||||
case WIN_WRITE_NORETRY:
|
||||
/* if (ide.secount>1)
|
||||
{
|
||||
fatal("Write %i sectors to sector %i cylinder %i head %i\n",ide.secount,ide.sector,ide.cylinder,ide.head);
|
||||
}*/
|
||||
|
|
@ -721,13 +802,26 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|||
ide->pos=0;
|
||||
return;
|
||||
|
||||
case WIN_WRITE_DMA:
|
||||
#if 0
|
||||
if (ide->lba) pclog("Write %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr);
|
||||
else pclog("Write %i sectors to sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head);
|
||||
#endif
|
||||
ide->atastat = BUSY_STAT;
|
||||
timer_process();
|
||||
idecallback[ide_board]=200*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
return;
|
||||
|
||||
case WIN_VERIFY:
|
||||
#if 0
|
||||
if (ide->lba) pclog("Read verify %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr);
|
||||
else pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head);
|
||||
#endif
|
||||
ide->atastat = BUSY_STAT;
|
||||
timer_process();
|
||||
idecallback[ide_board]=200*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
return;
|
||||
|
||||
case WIN_FORMAT:
|
||||
|
|
@ -739,17 +833,22 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|||
|
||||
case WIN_SPECIFY: /* Initialize Drive Parameters */
|
||||
ide->atastat = BUSY_STAT;
|
||||
timer_process();
|
||||
idecallback[ide_board]=200*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
// pclog("SPECIFY\n");
|
||||
// output=1;
|
||||
return;
|
||||
|
||||
case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */
|
||||
case WIN_PIDENTIFY: /* Identify Packet Device */
|
||||
case WIN_SET_MULTIPLE_MODE: /*Set Multiple Mode*/
|
||||
// output=1;
|
||||
case WIN_SETIDLE1: /* Idle */
|
||||
ide->atastat = BUSY_STAT;
|
||||
timer_process();
|
||||
idecallback[ide_board]=200*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
return;
|
||||
|
||||
case WIN_IDENTIFY: /* Identify Device */
|
||||
|
|
@ -757,13 +856,17 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|||
// output=3;
|
||||
// timetolive=500;
|
||||
ide->atastat = BUSY_STAT;
|
||||
timer_process();
|
||||
idecallback[ide_board]=200*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
return;
|
||||
|
||||
case WIN_PACKETCMD: /* ATAPI Packet */
|
||||
ide->packetstatus=0;
|
||||
ide->atastat = BUSY_STAT;
|
||||
timer_process();
|
||||
idecallback[ide_board]=1;//30*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
ide->pos=0;
|
||||
return;
|
||||
|
||||
|
|
@ -772,15 +875,18 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|||
ide->atastat = READY_STAT | ERR_STAT | DSC_STAT;
|
||||
ide->error = ABRT_ERR;
|
||||
ide_irq_raise(ide);
|
||||
/* fatal("Bad IDE command %02X\n", val);*/
|
||||
return;
|
||||
}
|
||||
// fatal("Bad IDE command %02X\n", val);
|
||||
|
||||
return;
|
||||
|
||||
case 0x3F6: /* Device control */
|
||||
if ((ide->fdisk&4) && !(val&4) && (ide->type != IDE_NONE))
|
||||
{
|
||||
timer_process();
|
||||
idecallback[ide_board]=500*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
ide->reset = 1;
|
||||
ide->atastat = BUSY_STAT;
|
||||
// pclog("IDE Reset\n");
|
||||
|
|
@ -795,7 +901,6 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|||
uint8_t readide(int ide_board, uint16_t addr)
|
||||
{
|
||||
IDE *ide = &ide_drives[cur_ide[ide_board]];
|
||||
const uint8_t *idebufferb = (const uint8_t *) ide->buffer;
|
||||
uint8_t temp;
|
||||
uint16_t tempw;
|
||||
|
||||
|
|
@ -807,6 +912,8 @@ uint8_t readide(int ide_board, uint16_t addr)
|
|||
return 0xFF;
|
||||
}*/
|
||||
#endif
|
||||
// if ((cr0&1) && !(eflags&VM_FLAG))
|
||||
// pclog("ReadIDE %04X from %04X(%08X):%08X\n", addr, CS, cs, pc);
|
||||
// return 0xFF;
|
||||
|
||||
if (ide->type == IDE_NONE && addr != 0x1f6) return 0xff;
|
||||
|
|
@ -866,7 +973,7 @@ uint8_t readide(int ide_board, uint16_t addr)
|
|||
else
|
||||
{
|
||||
// && ide->service) return ide.atastat[ide.board]|SERVICE_STAT;
|
||||
// pclog("Return status %02X\n",ide->atastat);
|
||||
// pclog("Return status %02X %04X:%04X %02X %02X\n",ide->atastat, CS ,pc, AH, BH);
|
||||
temp = ide->atastat;
|
||||
}
|
||||
break;
|
||||
|
|
@ -910,7 +1017,7 @@ uint16_t readidew(int ide_board)
|
|||
}*/
|
||||
#endif
|
||||
// return 0xFFFF;
|
||||
// pclog("Read IDEw %04X %04X:%04X %02X %i\n",ide->buffer[ide->pos >> 1],CS,pc,opcode,ins);
|
||||
// pclog("Read IDEw %04X %04X:%04X %02X %i %i\n",ide->buffer[ide->pos >> 1],CS,pc,opcode,ins, ide->pos);
|
||||
|
||||
//if (idedebug) pclog("Read IDEW %08X\n",PC);
|
||||
|
||||
|
|
@ -921,7 +1028,7 @@ uint16_t readidew(int ide_board)
|
|||
ide->pos+=2;
|
||||
if ((ide->pos>=512 && ide->command != WIN_PACKETCMD) || (ide->command == WIN_PACKETCMD && ide->pos>=ide->packlen))
|
||||
{
|
||||
// pclog("Over! packlen %i %i\n",ide.packlen,ide.pos);
|
||||
// pclog("Over! packlen %i %i\n",ide->packlen,ide->pos);
|
||||
ide->pos=0;
|
||||
if (ide->command == WIN_PACKETCMD)// && ide.packetstatus==6)
|
||||
{
|
||||
|
|
@ -932,16 +1039,24 @@ uint16_t readidew(int ide_board)
|
|||
{
|
||||
ide->atastat = READY_STAT | DSC_STAT;
|
||||
ide->packetstatus=0;
|
||||
if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY)
|
||||
if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE)
|
||||
{
|
||||
ide->secount--;
|
||||
if (ide->secount)
|
||||
{
|
||||
ide_next_sector(ide);
|
||||
ide->atastat = BUSY_STAT;
|
||||
idecallback[ide_board]=6*IDE_TIME;
|
||||
timer_process();
|
||||
if (ide->command == WIN_READ_MULTIPLE)
|
||||
callbackide(ide_board);
|
||||
else
|
||||
idecallback[ide_board]=6*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
// pclog("set idecallback\n");
|
||||
// callbackide(ide_board);
|
||||
}
|
||||
// else
|
||||
// pclog("readidew done %02X\n", ide->atastat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -949,6 +1064,12 @@ uint16_t readidew(int ide_board)
|
|||
return temp;
|
||||
}
|
||||
|
||||
uint32_t readidel(int ide_board)
|
||||
{
|
||||
uint16_t temp = readidew(ide_board);
|
||||
return temp | (readidew(ide_board) << 16);
|
||||
}
|
||||
|
||||
int times30=0;
|
||||
void callbackide(int ide_board)
|
||||
{
|
||||
|
|
@ -972,6 +1093,7 @@ void callbackide(int ide_board)
|
|||
ide->head=0;
|
||||
ide->cylinder=0;
|
||||
ide->reset = 0;
|
||||
ide->blocksize = 0;
|
||||
// pclog("Reset callback\n");
|
||||
return;
|
||||
}
|
||||
|
|
@ -996,9 +1118,10 @@ void callbackide(int ide_board)
|
|||
case WIN_RESTORE:
|
||||
case WIN_SEEK:
|
||||
if (IDE_DRIVE_IS_CDROM(ide)) {
|
||||
pclog("WIN_RESTORE callback on CD-ROM\n");
|
||||
goto abort_cmd;
|
||||
}
|
||||
// pclog("Restore callback\n");
|
||||
// pclog("WIN_RESTORE callback\n");
|
||||
ide->atastat = READY_STAT | DSC_STAT;
|
||||
ide_irq_raise(ide);
|
||||
return;
|
||||
|
|
@ -1026,6 +1149,66 @@ void callbackide(int ide_board)
|
|||
#endif
|
||||
return;
|
||||
|
||||
case WIN_READ_DMA:
|
||||
if (IDE_DRIVE_IS_CDROM(ide)) {
|
||||
goto abort_cmd;
|
||||
}
|
||||
addr = ide_get_sector(ide) * 512;
|
||||
fseeko64(ide->hdfile, addr, SEEK_SET);
|
||||
fread(ide->buffer, 512, 1, ide->hdfile);
|
||||
ide->pos=0;
|
||||
|
||||
if (ide_bus_master_read_sector)
|
||||
{
|
||||
if (ide_bus_master_read_sector(ide_board, (uint8_t *)ide->buffer))
|
||||
idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/
|
||||
else
|
||||
{
|
||||
/*DMA successful*/
|
||||
ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT;
|
||||
|
||||
ide->secount--;
|
||||
if (ide->secount)
|
||||
{
|
||||
ide_next_sector(ide);
|
||||
ide->atastat = BUSY_STAT;
|
||||
idecallback[ide_board]=6*IDE_TIME;
|
||||
}
|
||||
else
|
||||
{
|
||||
ide_irq_raise(ide);
|
||||
ide_bus_master_set_irq(ide_board);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef RPCEMU_IDE
|
||||
readflash=1;
|
||||
#endif
|
||||
return;
|
||||
|
||||
case WIN_READ_MULTIPLE:
|
||||
if (IDE_DRIVE_IS_CDROM(ide)) {
|
||||
goto abort_cmd;
|
||||
}
|
||||
addr = ide_get_sector(ide) * 512;
|
||||
// pclog("Read multiple from %08X %i (%i) %i\n", addr, ide->blockcount, ide->blocksize, ide->secount);
|
||||
fseeko64(ide->hdfile, addr, SEEK_SET);
|
||||
fread(ide->buffer, 512, 1, ide->hdfile);
|
||||
ide->pos=0;
|
||||
ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT;
|
||||
if (!ide->blockcount)// || ide->secount == 1)
|
||||
{
|
||||
// pclog("Read multiple int\n");
|
||||
ide_irq_raise(ide);
|
||||
}
|
||||
ide->blockcount++;
|
||||
if (ide->blockcount >= ide->blocksize)
|
||||
ide->blockcount = 0;
|
||||
#ifndef RPCEMU_IDE
|
||||
readflash=1;
|
||||
#endif
|
||||
return;
|
||||
|
||||
case WIN_WRITE:
|
||||
case WIN_WRITE_NORETRY:
|
||||
if (IDE_DRIVE_IS_CDROM(ide)) {
|
||||
|
|
@ -1049,6 +1232,71 @@ void callbackide(int ide_board)
|
|||
readflash=1;
|
||||
#endif
|
||||
return;
|
||||
|
||||
case WIN_WRITE_DMA:
|
||||
if (IDE_DRIVE_IS_CDROM(ide)) {
|
||||
goto abort_cmd;
|
||||
}
|
||||
|
||||
if (ide_bus_master_write_sector)
|
||||
{
|
||||
if (ide_bus_master_write_sector(ide_board, (uint8_t *)ide->buffer))
|
||||
idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/
|
||||
else
|
||||
{
|
||||
/*DMA successful*/
|
||||
addr = ide_get_sector(ide) * 512;
|
||||
fseeko64(ide->hdfile, addr, SEEK_SET);
|
||||
fwrite(ide->buffer, 512, 1, ide->hdfile);
|
||||
|
||||
ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT;
|
||||
|
||||
ide->secount--;
|
||||
if (ide->secount)
|
||||
{
|
||||
ide_next_sector(ide);
|
||||
ide->atastat = BUSY_STAT;
|
||||
idecallback[ide_board]=6*IDE_TIME;
|
||||
}
|
||||
else
|
||||
{
|
||||
ide_irq_raise(ide);
|
||||
ide_bus_master_set_irq(ide_board);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef RPCEMU_IDE
|
||||
readflash=1;
|
||||
#endif
|
||||
return;
|
||||
|
||||
case WIN_WRITE_MULTIPLE:
|
||||
if (IDE_DRIVE_IS_CDROM(ide)) {
|
||||
goto abort_cmd;
|
||||
}
|
||||
addr = ide_get_sector(ide) * 512;
|
||||
// pclog("Write sector callback %i %i %i offset %08X %i left %i\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt);
|
||||
fseeko64(ide->hdfile, addr, SEEK_SET);
|
||||
fwrite(ide->buffer, 512, 1, ide->hdfile);
|
||||
ide->blockcount++;
|
||||
if (ide->blockcount >= ide->blocksize || ide->secount == 1)
|
||||
{
|
||||
ide->blockcount = 0;
|
||||
ide_irq_raise(ide);
|
||||
}
|
||||
ide->secount--;
|
||||
if (ide->secount)
|
||||
{
|
||||
ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT;
|
||||
ide->pos=0;
|
||||
ide_next_sector(ide);
|
||||
}
|
||||
else
|
||||
ide->atastat = READY_STAT | DSC_STAT;
|
||||
#ifndef RPCEMU_IDE
|
||||
readflash=1;
|
||||
#endif
|
||||
return;
|
||||
|
||||
case WIN_VERIFY:
|
||||
if (IDE_DRIVE_IS_CDROM(ide)) {
|
||||
|
|
@ -1117,6 +1365,21 @@ void callbackide(int ide_board)
|
|||
// pclog("Not ATAPI\n");
|
||||
goto abort_cmd;
|
||||
|
||||
case WIN_SET_MULTIPLE_MODE:
|
||||
if (IDE_DRIVE_IS_CDROM(ide)) {
|
||||
#ifndef RPCEMU_IDE
|
||||
pclog("IS CDROM - ABORT\n");
|
||||
#endif
|
||||
goto abort_cmd;
|
||||
}
|
||||
ide->blocksize = ide->secount;
|
||||
ide->atastat = READY_STAT | DSC_STAT;
|
||||
#ifndef RPCEMU_IDE
|
||||
pclog("Set multiple mode - %i\n", ide->blocksize);
|
||||
#endif
|
||||
ide_irq_raise(ide);
|
||||
return;
|
||||
|
||||
case WIN_SETIDLE1: /* Idle */
|
||||
case 0xEF:
|
||||
goto abort_cmd;
|
||||
|
|
@ -1207,6 +1470,18 @@ abort_cmd:
|
|||
ide_irq_raise(ide);
|
||||
}
|
||||
|
||||
void ide_callback_pri()
|
||||
{
|
||||
idecallback[0] = 0;
|
||||
callbackide(0);
|
||||
}
|
||||
|
||||
void ide_callback_sec()
|
||||
{
|
||||
idecallback[1] = 0;
|
||||
callbackide(1);
|
||||
}
|
||||
|
||||
/*ATAPI CD-ROM emulation
|
||||
This mostly seems to work. It is implemented only on Windows at the moment as
|
||||
I haven't had time to implement any interfaces for it in the generic gui.
|
||||
|
|
@ -1714,44 +1989,93 @@ static void callreadcd(IDE *ide)
|
|||
|
||||
|
||||
|
||||
void ide_write_pri(uint16_t addr, uint8_t val)
|
||||
void ide_write_pri(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
writeide(0, addr, val);
|
||||
}
|
||||
void ide_write_pri_w(uint16_t addr, uint16_t val)
|
||||
void ide_write_pri_w(uint16_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
writeidew(0, val);
|
||||
}
|
||||
uint8_t ide_read_pri(uint16_t addr)
|
||||
void ide_write_pri_l(uint16_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
writeidel(0, val);
|
||||
}
|
||||
uint8_t ide_read_pri(uint16_t addr, void *priv)
|
||||
{
|
||||
return readide(0, addr);
|
||||
}
|
||||
uint16_t ide_read_pri_w(uint16_t addr)
|
||||
uint16_t ide_read_pri_w(uint16_t addr, void *priv)
|
||||
{
|
||||
return readidew(0);
|
||||
}
|
||||
uint32_t ide_read_pri_l(uint16_t addr, void *priv)
|
||||
{
|
||||
return readidel(0);
|
||||
}
|
||||
|
||||
void ide_write_sec(uint16_t addr, uint8_t val)
|
||||
void ide_write_sec(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
writeide(1, addr, val);
|
||||
}
|
||||
void ide_write_sec_w(uint16_t addr, uint16_t val)
|
||||
void ide_write_sec_w(uint16_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
writeidew(1, val);
|
||||
}
|
||||
uint8_t ide_read_sec(uint16_t addr)
|
||||
void ide_write_sec_l(uint16_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
writeidel(1, val);
|
||||
}
|
||||
uint8_t ide_read_sec(uint16_t addr, void *priv)
|
||||
{
|
||||
return readide(1, addr);
|
||||
}
|
||||
uint16_t ide_read_sec_w(uint16_t addr)
|
||||
uint16_t ide_read_sec_w(uint16_t addr, void *priv)
|
||||
{
|
||||
return readidew(1);
|
||||
}
|
||||
uint32_t ide_read_sec_l(uint16_t addr, void *priv)
|
||||
{
|
||||
return readidel(1);
|
||||
}
|
||||
|
||||
void ide_pri_enable()
|
||||
{
|
||||
io_sethandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL);
|
||||
io_sethandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL);
|
||||
}
|
||||
|
||||
void ide_pri_disable()
|
||||
{
|
||||
io_removehandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL);
|
||||
io_removehandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL);
|
||||
}
|
||||
|
||||
void ide_sec_enable()
|
||||
{
|
||||
io_sethandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL);
|
||||
io_sethandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL);
|
||||
}
|
||||
|
||||
void ide_sec_disable()
|
||||
{
|
||||
io_removehandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL);
|
||||
io_removehandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL);
|
||||
}
|
||||
|
||||
void ide_init()
|
||||
{
|
||||
io_sethandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, NULL, ide_write_pri, ide_write_pri_w, NULL);
|
||||
io_sethandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL);
|
||||
io_sethandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, NULL, ide_write_sec, ide_write_sec_w, NULL);
|
||||
io_sethandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL);
|
||||
ide_pri_enable();
|
||||
ide_sec_enable();
|
||||
ide_bus_master_read_sector = ide_bus_master_write_sector = NULL;
|
||||
|
||||
timer_add(ide_callback_pri, &idecallback[0], &idecallback[0], NULL);
|
||||
timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL);
|
||||
}
|
||||
|
||||
void ide_set_bus_master(int (*read_sector)(int channel, uint8_t *data), int (*write_sector)(int channel, uint8_t *data), void (*set_irq)(int channel))
|
||||
{
|
||||
ide_bus_master_read_sector = read_sector;
|
||||
ide_bus_master_write_sector = write_sector;
|
||||
ide_bus_master_set_irq = set_irq;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ extern uint16_t readidew(int ide_board);
|
|||
extern void callbackide(int ide_board);
|
||||
extern void resetide(void);
|
||||
extern void ide_init();
|
||||
extern void ide_pri_enable();
|
||||
extern void ide_sec_enable();
|
||||
extern void ide_pri_disable();
|
||||
extern void ide_sec_disable();
|
||||
extern void ide_set_bus_master(int (*read_sector)(int channel, uint8_t *data), int (*write_sector)(int channel, uint8_t *data), void (*set_irq)(int channel));
|
||||
|
||||
/*ATAPI stuff*/
|
||||
typedef struct ATAPI
|
||||
|
|
|
|||
208
src/io.c
208
src/io.c
|
|
@ -1,89 +1,112 @@
|
|||
#include "ibm.h"
|
||||
#include "ide.h"
|
||||
#include "io.h"
|
||||
#include "video.h"
|
||||
#include "cpu.h"
|
||||
|
||||
uint8_t (*port_inb[0x10000][2])(uint16_t addr);
|
||||
uint16_t (*port_inw[0x10000][2])(uint16_t addr);
|
||||
uint32_t (*port_inl[0x10000][2])(uint16_t addr);
|
||||
uint8_t (*port_inb[0x10000][2])(uint16_t addr, void *priv);
|
||||
uint16_t (*port_inw[0x10000][2])(uint16_t addr, void *priv);
|
||||
uint32_t (*port_inl[0x10000][2])(uint16_t addr, void *priv);
|
||||
|
||||
void (*port_outb[0x10000][2])(uint16_t addr, uint8_t val);
|
||||
void (*port_outw[0x10000][2])(uint16_t addr, uint16_t val);
|
||||
void (*port_outl[0x10000][2])(uint16_t addr, uint32_t val);
|
||||
void (*port_outb[0x10000][2])(uint16_t addr, uint8_t val, void *priv);
|
||||
void (*port_outw[0x10000][2])(uint16_t addr, uint16_t val, void *priv);
|
||||
void (*port_outl[0x10000][2])(uint16_t addr, uint32_t val, void *priv);
|
||||
|
||||
void *port_priv[0x10000][2];
|
||||
|
||||
void io_init()
|
||||
{
|
||||
int c;
|
||||
pclog("io_init\n");
|
||||
for (c = 0; c < 0x10000; c++)
|
||||
{
|
||||
port_inb[c][0] = port_inw[c][0] = port_inl[c][0] = NULL;
|
||||
port_outb[c][0] = port_outw[c][0] = port_outl[c][0] = NULL;
|
||||
port_inb[c][1] = port_inw[c][1] = port_inl[c][1] = NULL;
|
||||
port_outb[c][1] = port_outw[c][1] = port_outl[c][1] = NULL;
|
||||
port_priv[c][0] = port_priv[c][1] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void io_sethandler(uint16_t base, int size,
|
||||
uint8_t (*inb)(uint16_t addr),
|
||||
uint16_t (*inw)(uint16_t addr),
|
||||
uint32_t (*inl)(uint16_t addr),
|
||||
void (*outb)(uint16_t addr, uint8_t val),
|
||||
void (*outw)(uint16_t addr, uint16_t val),
|
||||
void (*outl)(uint16_t addr, uint32_t val))
|
||||
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)
|
||||
{
|
||||
int c;
|
||||
for (c = 0; c < size; c++)
|
||||
{
|
||||
if (!port_inb[ base + c][0]) port_inb[ base + c][0] = inb;
|
||||
else if (!port_inb[ base + c][1]) port_inb[ base + c][1] = inb;
|
||||
if (!port_inw[ base + c][0]) port_inw[ base + c][0] = inw;
|
||||
else if (!port_inw[ base + c][1]) port_inw[ base + c][1] = inw;
|
||||
if (!port_inl[ base + c][0]) port_inl[ base + c][0] = inl;
|
||||
else if (!port_inl[ base + c][1]) port_inl[ base + c][1] = inl;
|
||||
if (!port_outb[base + c][0]) port_outb[base + c][0] = outb;
|
||||
else if (!port_outb[base + c][1]) port_outb[base + c][1] = outb;
|
||||
if (!port_outw[base + c][0]) port_outw[base + c][0] = outw;
|
||||
else if (!port_outw[base + c][1]) port_outw[base + c][1] = outw;
|
||||
if (!port_outl[base + c][0]) port_outl[base + c][0] = outl;
|
||||
else if (!port_outl[base + c][1]) port_outl[base + c][1] = outl;
|
||||
if (!port_inb[ base + c][0] && !port_inw[ base + c][0] && !port_inl[ base + c][0] &&
|
||||
!port_outb[base + c][0] && !port_outw[base + c][0] && !port_outl[base + c][0])
|
||||
{
|
||||
port_inb[ base + c][0] = inb;
|
||||
port_inw[ base + c][0] = inw;
|
||||
port_inl[ base + c][0] = inl;
|
||||
port_outb[base + c][0] = outb;
|
||||
port_outw[base + c][0] = outw;
|
||||
port_outl[base + c][0] = outl;
|
||||
port_priv[base + c][0] = priv;
|
||||
}
|
||||
else if (!port_inb[ base + c][1] && !port_inw[ base + c][1] && !port_inl[ base + c][1] &&
|
||||
!port_outb[base + c][1] && !port_outw[base + c][1] && !port_outl[base + c][1])
|
||||
{
|
||||
port_inb[ base + c][1] = inb;
|
||||
port_inw[ base + c][1] = inw;
|
||||
port_inl[ base + c][1] = inl;
|
||||
port_outb[base + c][1] = outb;
|
||||
port_outw[base + c][1] = outw;
|
||||
port_outl[base + c][1] = outl;
|
||||
port_priv[base + c][1] = priv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void io_removehandler(uint16_t base, int size,
|
||||
uint8_t (*inb)(uint16_t addr),
|
||||
uint16_t (*inw)(uint16_t addr),
|
||||
uint32_t (*inl)(uint16_t addr),
|
||||
void (*outb)(uint16_t addr, uint8_t val),
|
||||
void (*outw)(uint16_t addr, uint16_t val),
|
||||
void (*outl)(uint16_t addr, uint32_t val))
|
||||
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)
|
||||
{
|
||||
int c;
|
||||
for (c = 0; c < size; c++)
|
||||
{
|
||||
if (port_inb[ base + c][0] == inb)
|
||||
port_inb[ base + c][0] = NULL;
|
||||
if (port_inb[ base + c][1] == inb)
|
||||
port_inb[ base + c][1] = NULL;
|
||||
if (port_inw[ base + c][0] == inw)
|
||||
port_inw[ base + c][0] = NULL;
|
||||
if (port_inw[ base + c][1] == inw)
|
||||
port_inw[ base + c][1] = NULL;
|
||||
if (port_inl[ base + c][0] == inl)
|
||||
port_inl[ base + c][0] = NULL;
|
||||
if (port_inl[ base + c][1] == inl)
|
||||
port_inl[ base + c][1] = NULL;
|
||||
if (port_outb[ base + c][0] == outb)
|
||||
port_outb[ base + c][0] = NULL;
|
||||
if (port_outb[ base + c][1] == outb)
|
||||
port_outb[ base + c][1] = NULL;
|
||||
if (port_outw[ base + c][0] == outw)
|
||||
port_outw[ base + c][0] = NULL;
|
||||
if (port_outw[ base + c][1] == outw)
|
||||
port_outw[ base + c][1] = NULL;
|
||||
if (port_outl[ base + c][0] == outl)
|
||||
port_outl[ base + c][0] = NULL;
|
||||
if (port_outl[ base + c][1] == outl)
|
||||
port_outl[ base + c][1] = NULL;
|
||||
if (port_priv[base + c][0] == priv)
|
||||
{
|
||||
if (port_inb[ base + c][0] == inb)
|
||||
port_inb[ base + c][0] = NULL;
|
||||
if (port_inw[ base + c][0] == inw)
|
||||
port_inw[ base + c][0] = NULL;
|
||||
if (port_inl[ base + c][0] == inl)
|
||||
port_inl[ base + c][0] = NULL;
|
||||
if (port_outb[ base + c][0] == outb)
|
||||
port_outb[ base + c][0] = NULL;
|
||||
if (port_outw[ base + c][0] == outw)
|
||||
port_outw[ base + c][0] = NULL;
|
||||
if (port_outl[ base + c][0] == outl)
|
||||
port_outl[ base + c][0] = NULL;
|
||||
}
|
||||
if (port_priv[base + c][1] == priv)
|
||||
{
|
||||
if (port_inb[ base + c][1] == inb)
|
||||
port_inb[ base + c][1] = NULL;
|
||||
if (port_inw[ base + c][1] == inw)
|
||||
port_inw[ base + c][1] = NULL;
|
||||
if (port_inl[ base + c][1] == inl)
|
||||
port_inl[ base + c][1] = NULL;
|
||||
if (port_outb[ base + c][1] == outb)
|
||||
port_outb[ base + c][1] = NULL;
|
||||
if (port_outw[ base + c][1] == outw)
|
||||
port_outw[ base + c][1] = NULL;
|
||||
if (port_outl[ base + c][1] == outl)
|
||||
port_outl[ base + c][1] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,63 +118,39 @@ int t237=0;
|
|||
uint8_t inb(uint16_t port)
|
||||
{
|
||||
uint8_t temp = 0xff;
|
||||
int tempi;
|
||||
if (port_inb[port][0])
|
||||
temp &= port_inb[port][0](port);
|
||||
if (port_inb[port][1])
|
||||
temp &= port_inb[port][1](port);
|
||||
return temp;
|
||||
|
||||
if (port&0x80) sw9=2;
|
||||
// if ((port&0x3F0)==0x3D0) printf("Video access read %03X %04X:%04X\n",port,cs>>4,pc);
|
||||
// if (cs<0xF0000 || cs>0x100000) printf("IN %04X %04X(%06X):%08X\n",port,CS,cs,pc);
|
||||
// /*if (output==3) */printf("IN %04X %04X:%04X\n",port,CS,pc);
|
||||
// if (port == 0x23) pclog("IN %04X %04X:%08X\n", port, CS, pc);
|
||||
switch (port)
|
||||
{
|
||||
case 0x220: case 0x221: case 0x222: case 0x223: /*Gameblaster*/
|
||||
if (sbtype>=SBPRO) return readsb(port);
|
||||
if (GAMEBLASTER) return readcms(port);
|
||||
return 0xFF;
|
||||
}
|
||||
// printf("Bad IN port %04X %04X:%04X\n",port,cs>>4,pc);
|
||||
return 0xff;
|
||||
/*dumpregs();
|
||||
exit(-1);*/
|
||||
}
|
||||
|
||||
/*uint8_t inb(uint16_t port)
|
||||
{
|
||||
uint8_t temp = _inb(port);
|
||||
// if (port != 0x61) pclog("IN %04X %02X %04X(%08X):%08X %f %04X %i %i\n", port, temp, CS, cs, pc, pit.c[1], CX, keybsenddelay, GetTickCount());
|
||||
if (port_inb[port][0])
|
||||
temp &= port_inb[port][0](port, port_priv[port][0]);
|
||||
if (port_inb[port][1])
|
||||
temp &= port_inb[port][1](port, port_priv[port][1]);
|
||||
|
||||
/* if (!port_inb[port][0] && !port_inb[port][1])
|
||||
pclog("Bad INB %04X %04X:%04X\n", port, CS, pc);*/
|
||||
|
||||
return temp;
|
||||
}*/
|
||||
}
|
||||
|
||||
uint8_t cpu_readport(uint32_t port) { return inb(port); }
|
||||
|
||||
void outb(uint16_t port, uint8_t val)
|
||||
{
|
||||
// /*if (output==3) */printf("OUT %04X %02X %04X(%08X):%08X %i %i\n", port, val, CS, cs, pc, ins, GetTickCount());
|
||||
if (port_outb[port][0])
|
||||
port_outb[port][0](port, val);
|
||||
port_outb[port][0](port, val, port_priv[port][0]);
|
||||
if (port_outb[port][1])
|
||||
port_outb[port][1](port, val);
|
||||
port_outb[port][1](port, val, port_priv[port][1]);
|
||||
|
||||
/* if (!port_outb[port][0] && !port_outb[port][1])
|
||||
pclog("Bad OUTB %04X %02X %04X:%08X\n", port, val, CS, pc);*/
|
||||
return;
|
||||
switch (port)
|
||||
{
|
||||
case 0x220: case 0x221: case 0x222: case 0x223: /*Gameblaster*/
|
||||
if (GAMEBLASTER) writecms(port,val);
|
||||
return;
|
||||
}
|
||||
pclog("OUT %04X %02X %04X:%08X\n",port,val,CS,pc);
|
||||
}
|
||||
|
||||
uint16_t inw(uint16_t port)
|
||||
{
|
||||
// pclog("INW %04X\n", port);
|
||||
if (port_inw[port][0])
|
||||
return port_inw[port][0](port);
|
||||
return port_inw[port][0](port, port_priv[port][0]);
|
||||
if (port_inw[port][1])
|
||||
return port_inw[port][1](port);
|
||||
return port_inw[port][1](port, port_priv[port][1]);
|
||||
|
||||
return inb(port) | (inb(port + 1) << 8);
|
||||
}
|
||||
|
|
@ -159,10 +158,13 @@ uint16_t inw(uint16_t port)
|
|||
void outw(uint16_t port, uint16_t val)
|
||||
{
|
||||
// printf("OUTW %04X %04X %04X:%08X\n",port,val, CS, pc);
|
||||
/* if ((port & ~0xf) == 0xf000)
|
||||
pclog("OUTW %04X %04X\n", port, val);*/
|
||||
|
||||
if (port_outw[port][0])
|
||||
port_outw[port][0](port, val);
|
||||
port_outw[port][0](port, val, port_priv[port][0]);
|
||||
if (port_outw[port][1])
|
||||
port_outw[port][1](port, val);
|
||||
port_outw[port][1](port, val, port_priv[port][1]);
|
||||
|
||||
if (port_outw[port][0] || port_outw[port][1])
|
||||
return;
|
||||
|
|
@ -173,20 +175,24 @@ void outw(uint16_t port, uint16_t val)
|
|||
|
||||
uint32_t inl(uint16_t port)
|
||||
{
|
||||
// pclog("INL %04X\n", port);
|
||||
if (port_inl[port][0])
|
||||
return port_inl[port][0](port);
|
||||
return port_inl[port][0](port, port_priv[port][0]);
|
||||
if (port_inl[port][1])
|
||||
return port_inl[port][1](port);
|
||||
return port_inl[port][1](port, port_priv[port][1]);
|
||||
|
||||
return inw(port) | (inw(port + 2) << 16);
|
||||
}
|
||||
|
||||
void outl(uint16_t port, uint32_t val)
|
||||
{
|
||||
/* if ((port & ~0xf) == 0xf000)
|
||||
pclog("OUTL %04X %08X\n", port, val);*/
|
||||
|
||||
if (port_outl[port][0])
|
||||
port_outl[port][0](port, val);
|
||||
port_outl[port][0](port, val, port_priv[port][0]);
|
||||
if (port_outl[port][1])
|
||||
port_outl[port][1](port, val);
|
||||
port_outl[port][1](port, val, port_priv[port][1]);
|
||||
|
||||
if (port_outl[port][0] || port_outl[port][1])
|
||||
return;
|
||||
|
|
|
|||
26
src/io.h
26
src/io.h
|
|
@ -1,17 +1,19 @@
|
|||
void io_init();
|
||||
|
||||
void io_sethandler(uint16_t base, int size,
|
||||
uint8_t (*inb)(uint16_t addr),
|
||||
uint16_t (*inw)(uint16_t addr),
|
||||
uint32_t (*inl)(uint16_t addr),
|
||||
void (*outb)(uint16_t addr, uint8_t val),
|
||||
void (*outw)(uint16_t addr, uint16_t val),
|
||||
void (*outl)(uint16_t addr, uint32_t val));
|
||||
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_removehandler(uint16_t base, int size,
|
||||
uint8_t (*inb)(uint16_t addr),
|
||||
uint16_t (*inw)(uint16_t addr),
|
||||
uint32_t (*inl)(uint16_t addr),
|
||||
void (*outb)(uint16_t addr, uint8_t val),
|
||||
void (*outw)(uint16_t addr, uint16_t val),
|
||||
void (*outl)(uint16_t addr, uint32_t val));
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
|
||||
uint8_t europcdat[16];
|
||||
struct
|
||||
|
|
@ -10,7 +11,7 @@ struct
|
|||
int addr;
|
||||
} europc_rtc;
|
||||
|
||||
void writejim(uint16_t addr, uint8_t val)
|
||||
void writejim(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
if ((addr&0xFF0)==0x250) europcdat[addr&0xF]=val;
|
||||
switch (addr)
|
||||
|
|
@ -38,7 +39,7 @@ void writejim(uint16_t addr, uint8_t val)
|
|||
// printf("Write JIM %04X %02X\n",addr,val);
|
||||
}
|
||||
|
||||
uint8_t readjim(uint16_t addr)
|
||||
uint8_t readjim(uint16_t addr, void *p)
|
||||
{
|
||||
// printf("Read JIM %04X\n",addr);
|
||||
switch (addr)
|
||||
|
|
@ -74,5 +75,5 @@ void jim_init()
|
|||
else viddat=0x10;
|
||||
europc_rtc.dat[0xB]=viddat;
|
||||
europc_rtc.dat[0xD]=viddat; /*Checksum*/
|
||||
io_sethandler(0x250, 0x10, readjim, NULL, NULL, writejim, NULL, NULL);
|
||||
io_sethandler(0x250, 0x10, readjim, NULL, NULL, writejim, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ void keyboard_process()
|
|||
continue;
|
||||
if (!key[c] && scancodes[c].scancodes_break[0] == -1)
|
||||
continue;
|
||||
pclog("Key %02X start\n", c);
|
||||
// pclog("Key %02X start\n", c);
|
||||
d = 0;
|
||||
if (key[c])
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "pic.h"
|
||||
#include "sound.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
|
|
@ -53,7 +54,7 @@ void keyboard_amstrad_adddata(uint8_t val)
|
|||
return;
|
||||
}
|
||||
|
||||
void keyboard_amstrad_write(uint16_t port, uint8_t val)
|
||||
void keyboard_amstrad_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
pclog("keyboard_amstrad : write %04X %02X %02X\n", port, val, keyboard_amstrad.pb);
|
||||
/* if (ram[8] == 0xc3)
|
||||
|
|
@ -102,7 +103,7 @@ void keyboard_amstrad_write(uint16_t port, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t keyboard_amstrad_read(uint16_t port)
|
||||
uint8_t keyboard_amstrad_read(uint16_t port, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// pclog("keyboard_amstrad : read %04X ", port);
|
||||
|
|
@ -161,7 +162,7 @@ void keyboard_amstrad_init()
|
|||
{
|
||||
//return;
|
||||
pclog("keyboard_amstrad_init\n");
|
||||
io_sethandler(0x0060, 0x0006, keyboard_amstrad_read, NULL, NULL, keyboard_amstrad_write, NULL, NULL);
|
||||
io_sethandler(0x0060, 0x0006, keyboard_amstrad_read, NULL, NULL, keyboard_amstrad_write, NULL, NULL, NULL);
|
||||
keyboard_amstrad_reset();
|
||||
keyboard_send = keyboard_amstrad_adddata;
|
||||
keyboard_poll = keyboard_amstrad_poll;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "pic.h"
|
||||
#include "sound.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "keyboard_at.h"
|
||||
|
|
@ -44,22 +46,23 @@ int mouse_queue_start = 0, mouse_queue_end = 0;
|
|||
|
||||
void keyboard_at_poll()
|
||||
{
|
||||
keybsenddelay += (1000 * TIMER_USEC);
|
||||
if (keyboard_at.wantirq)
|
||||
{
|
||||
keyboard_at.wantirq = 0;
|
||||
picint(2);
|
||||
pclog("keyboard_at : take IRQ\n");
|
||||
// pclog("keyboard_at : take IRQ\n");
|
||||
}
|
||||
else if (keyboard_at.wantirq12)
|
||||
{
|
||||
keyboard_at.wantirq12 = 0;
|
||||
picint(0x1000);
|
||||
pclog("keyboard_at : take IRQ 12\n");
|
||||
// pclog("keyboard_at : take IRQ 12\n");
|
||||
}
|
||||
if (!(keyboard_at.status & STAT_OFULL) && !(keyboard_at.mem[0] & 0x10) &&
|
||||
mouse_queue_start != mouse_queue_end)
|
||||
{
|
||||
pclog("Reading %02X from the mouse queue at %i\n", keyboard_at.out, key_queue_start);
|
||||
// pclog("Reading %02X from the mouse queue at %i\n", keyboard_at.out, key_queue_start);
|
||||
keyboard_at.out = mouse_queue[mouse_queue_start];
|
||||
mouse_queue_start = (mouse_queue_start + 1) & 0xf;
|
||||
keyboard_at.status |= STAT_OFULL | STAT_MFULL;
|
||||
|
|
@ -70,7 +73,7 @@ void keyboard_at_poll()
|
|||
else if (!(keyboard_at.status & STAT_OFULL) && !(keyboard_at.mem[0] & 0x10) &&
|
||||
key_queue_start != key_queue_end)
|
||||
{
|
||||
pclog("Reading %02X from the key queue at %i\n", keyboard_at.out, key_queue_start);
|
||||
// pclog("Reading %02X from the key queue at %i\n", keyboard_at.out, key_queue_start);
|
||||
keyboard_at.out = key_queue[key_queue_start];
|
||||
key_queue_start = (key_queue_start + 1) & 0xf;
|
||||
keyboard_at.status |= STAT_OFULL;
|
||||
|
|
@ -81,7 +84,7 @@ void keyboard_at_poll()
|
|||
else if (!(keyboard_at.status & STAT_OFULL) &&
|
||||
key_ctrl_queue_start != key_ctrl_queue_end)
|
||||
{
|
||||
pclog("Reading %02X from the key ctrl_queue at %i\n", keyboard_at.out, key_ctrl_queue_start);
|
||||
// pclog("Reading %02X from the key ctrl_queue at %i\n", keyboard_at.out, key_ctrl_queue_start);
|
||||
keyboard_at.out = key_ctrl_queue[key_ctrl_queue_start];
|
||||
key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf;
|
||||
keyboard_at.status |= STAT_OFULL;
|
||||
|
|
@ -97,7 +100,7 @@ void keyboard_at_adddata(uint8_t val)
|
|||
// {
|
||||
key_ctrl_queue[key_ctrl_queue_end] = val;
|
||||
key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf;
|
||||
pclog("keyboard_at : %02X added to queue\n", val);
|
||||
// pclog("keyboard_at : %02X added to queue\n", val);
|
||||
/* return;
|
||||
}
|
||||
keyboard_at.out = val;
|
||||
|
|
@ -110,9 +113,15 @@ void keyboard_at_adddata(uint8_t val)
|
|||
|
||||
void keyboard_at_adddata_keyboard(uint8_t val)
|
||||
{
|
||||
/* if (val == 0x1c)
|
||||
{
|
||||
key_1c++;
|
||||
if (key_1c == 4)
|
||||
output = 3;
|
||||
}*/
|
||||
key_queue[key_queue_end] = val;
|
||||
key_queue_end = (key_queue_end + 1) & 0xf;
|
||||
pclog("keyboard_at : %02X added to key queue\n", val);
|
||||
// pclog("keyboard_at : %02X added to key queue\n", val);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -120,13 +129,13 @@ void keyboard_at_adddata_mouse(uint8_t val)
|
|||
{
|
||||
mouse_queue[mouse_queue_end] = val;
|
||||
mouse_queue_end = (mouse_queue_end + 1) & 0xf;
|
||||
pclog("keyboard_at : %02X added to mouse queue\n", val);
|
||||
// pclog("keyboard_at : %02X added to mouse queue\n", val);
|
||||
return;
|
||||
}
|
||||
|
||||
void keyboard_at_write(uint16_t port, uint8_t val)
|
||||
void keyboard_at_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
pclog("keyboard_at : write %04X %02X %i %02X\n", port, val, keyboard_at.key_wantdata, ram[8]);
|
||||
// pclog("keyboard_at : write %04X %02X %i %02X\n", port, val, keyboard_at.key_wantdata, ram[8]);
|
||||
/* if (ram[8] == 0xc3)
|
||||
{
|
||||
output = 3;
|
||||
|
|
@ -165,7 +174,7 @@ void keyboard_at_write(uint16_t port, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0xd1: /*Write output port*/
|
||||
pclog("Write output port - %02X %02X %04X:%04X\n", keyboard_at.output_port, val, CS, pc);
|
||||
// pclog("Write output port - %02X %02X %04X:%04X\n", keyboard_at.output_port, val, CS, pc);
|
||||
if ((keyboard_at.output_port ^ val) & 0x02) /*A20 enable change*/
|
||||
{
|
||||
mem_a20_key = val & 0x02;
|
||||
|
|
@ -384,7 +393,7 @@ void keyboard_at_write(uint16_t port, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t keyboard_at_read(uint16_t port)
|
||||
uint8_t keyboard_at_read(uint16_t port, void *priv)
|
||||
{
|
||||
uint8_t temp = 0xff;
|
||||
cycles -= 4;
|
||||
|
|
@ -428,9 +437,11 @@ void keyboard_at_reset()
|
|||
void keyboard_at_init()
|
||||
{
|
||||
//return;
|
||||
io_sethandler(0x0060, 0x0005, keyboard_at_read, NULL, NULL, keyboard_at_write, NULL, NULL);
|
||||
io_sethandler(0x0060, 0x0005, keyboard_at_read, NULL, NULL, keyboard_at_write, NULL, NULL, NULL);
|
||||
keyboard_at_reset();
|
||||
keyboard_send = keyboard_at_adddata_keyboard;
|
||||
keyboard_poll = keyboard_at_poll;
|
||||
mouse_write = NULL;
|
||||
|
||||
timer_add(keyboard_at_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "mouse.h"
|
||||
#include "pic.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "keyboard_olim24.h"
|
||||
|
|
@ -63,7 +64,7 @@ void keyboard_olim24_adddata(uint8_t val)
|
|||
return;
|
||||
}
|
||||
|
||||
void keyboard_olim24_write(uint16_t port, uint8_t val)
|
||||
void keyboard_olim24_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
pclog("keyboard_olim24 : write %04X %02X\n", port, val);
|
||||
/* if (ram[8] == 0xc3)
|
||||
|
|
@ -138,7 +139,7 @@ void keyboard_olim24_write(uint16_t port, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t keyboard_olim24_read(uint16_t port)
|
||||
uint8_t keyboard_olim24_read(uint16_t port, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// pclog("keyboard_olim24 : read %04X ", port);
|
||||
|
|
@ -276,8 +277,8 @@ void mouse_olim24_poll(int x, int y, int b)
|
|||
void keyboard_olim24_init()
|
||||
{
|
||||
//return;
|
||||
io_sethandler(0x0060, 0x0001, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL);
|
||||
io_sethandler(0x0064, 0x0001, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL);
|
||||
io_sethandler(0x0060, 0x0001, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0064, 0x0001, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL, NULL);
|
||||
keyboard_olim24_reset();
|
||||
keyboard_send = keyboard_olim24_adddata;
|
||||
keyboard_poll = keyboard_olim24_poll;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "pic.h"
|
||||
#include "sound.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "keyboard_xt.h"
|
||||
|
|
@ -28,6 +30,7 @@ static int key_queue_start = 0, key_queue_end = 0;
|
|||
|
||||
void keyboard_xt_poll()
|
||||
{
|
||||
keybsenddelay += (1000 * TIMER_USEC);
|
||||
if (keyboard_xt.wantirq)
|
||||
{
|
||||
keyboard_xt.wantirq = 0;
|
||||
|
|
@ -51,7 +54,7 @@ void keyboard_xt_adddata(uint8_t val)
|
|||
return;
|
||||
}
|
||||
|
||||
void keyboard_xt_write(uint16_t port, uint8_t val)
|
||||
void keyboard_xt_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
pclog("keyboard_xt : write %04X %02X %02X\n", port, val, keyboard_xt.pb);
|
||||
/* if (ram[8] == 0xc3)
|
||||
|
|
@ -86,10 +89,10 @@ void keyboard_xt_write(uint16_t port, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t keyboard_xt_read(uint16_t port)
|
||||
uint8_t keyboard_xt_read(uint16_t port, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// pclog("keyboard_xt : read %04X ", port);
|
||||
pclog("keyboard_xt : read %04X ", port);
|
||||
switch (port)
|
||||
{
|
||||
case 0x60:
|
||||
|
|
@ -142,7 +145,7 @@ uint8_t keyboard_xt_read(uint16_t port)
|
|||
//dumpregs();
|
||||
//exit(-1);
|
||||
}
|
||||
// pclog("%02X\n", temp);
|
||||
pclog("%02X\n", temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
|
@ -156,8 +159,10 @@ void keyboard_xt_reset()
|
|||
void keyboard_xt_init()
|
||||
{
|
||||
//return;
|
||||
io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL);
|
||||
io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL, NULL);
|
||||
keyboard_xt_reset();
|
||||
keyboard_send = keyboard_xt_adddata;
|
||||
keyboard_poll = keyboard_xt_poll;
|
||||
|
||||
timer_add(keyboard_xt_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
|
||||
}
|
||||
|
|
|
|||
35
src/lpt.c
35
src/lpt.c
|
|
@ -4,7 +4,7 @@
|
|||
#include "lpt.h"
|
||||
|
||||
static uint8_t lpt1_dat, lpt2_dat;
|
||||
void lpt1_write(uint16_t port, uint8_t val)
|
||||
void lpt1_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
switch (port & 3)
|
||||
{
|
||||
|
|
@ -17,7 +17,7 @@ void lpt1_write(uint16_t port, uint8_t val)
|
|||
break;
|
||||
}
|
||||
}
|
||||
uint8_t lpt1_read(uint16_t port)
|
||||
uint8_t lpt1_read(uint16_t port, void *priv)
|
||||
{
|
||||
switch (port & 3)
|
||||
{
|
||||
|
|
@ -29,7 +29,7 @@ uint8_t lpt1_read(uint16_t port)
|
|||
return 0xff;
|
||||
}
|
||||
|
||||
void lpt2_write(uint16_t port, uint8_t val)
|
||||
void lpt2_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
switch (port & 3)
|
||||
{
|
||||
|
|
@ -42,7 +42,7 @@ void lpt2_write(uint16_t port, uint8_t val)
|
|||
break;
|
||||
}
|
||||
}
|
||||
uint8_t lpt2_read(uint16_t port)
|
||||
uint8_t lpt2_read(uint16_t port, void *priv)
|
||||
{
|
||||
switch (port & 3)
|
||||
{
|
||||
|
|
@ -56,11 +56,32 @@ uint8_t lpt2_read(uint16_t port)
|
|||
|
||||
void lpt_init()
|
||||
{
|
||||
io_sethandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL);
|
||||
io_sethandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL);
|
||||
io_sethandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void lpt1_init(uint16_t port)
|
||||
{
|
||||
io_sethandler(port, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL);
|
||||
}
|
||||
void lpt1_remove()
|
||||
{
|
||||
io_removehandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x03bc, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL);
|
||||
}
|
||||
void lpt2_init(uint16_t port)
|
||||
{
|
||||
io_sethandler(port, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
}
|
||||
void lpt2_remove()
|
||||
{
|
||||
io_removehandler(0x0379, 0x0002, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL);
|
||||
io_removehandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x03bc, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void lpt2_remove_ams()
|
||||
{
|
||||
io_removehandler(0x0379, 0x0002, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,6 @@
|
|||
void lpt_init();
|
||||
void lpt2_remove();
|
||||
extern void lpt_init();
|
||||
extern void lpt1_init(uint16_t port);
|
||||
extern void lpt1_remove();
|
||||
extern void lpt2_init(uint16_t port);
|
||||
extern void lpt2_remove();
|
||||
extern void lpt2_remove_ams();
|
||||
|
|
|
|||
454
src/mem.c
454
src/mem.c
|
|
@ -8,17 +8,20 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ibm.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "mem.h"
|
||||
#include "video.h"
|
||||
#include "x86.h"
|
||||
#include "cpu.h"
|
||||
|
||||
static uint8_t (*_mem_read_b[0x20000])(uint32_t addr);
|
||||
static uint16_t (*_mem_read_w[0x20000])(uint32_t addr);
|
||||
static uint32_t (*_mem_read_l[0x20000])(uint32_t addr);
|
||||
static void (*_mem_write_b[0x20000])(uint32_t addr, uint8_t val);
|
||||
static void (*_mem_write_w[0x20000])(uint32_t addr, uint16_t val);
|
||||
static void (*_mem_write_l[0x20000])(uint32_t addr, uint32_t val);
|
||||
static uint8_t (*_mem_read_b[0x40000])(uint32_t addr, void *priv);
|
||||
static uint16_t (*_mem_read_w[0x40000])(uint32_t addr, void *priv);
|
||||
static uint32_t (*_mem_read_l[0x40000])(uint32_t addr, void *priv);
|
||||
static void (*_mem_write_b[0x40000])(uint32_t addr, uint8_t val, void *priv);
|
||||
static void (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv);
|
||||
static void (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv);
|
||||
static void *_mem_priv[0x40000];
|
||||
|
||||
int shadowbios,shadowbios_write;
|
||||
|
||||
|
|
@ -40,14 +43,14 @@ uint8_t romext[32768];
|
|||
FILE *romfopen(char *fn, char *mode)
|
||||
{
|
||||
char s[512];
|
||||
pclog("romfopen %s\n", fn);
|
||||
// pclog("romfopen %s\n", fn);
|
||||
strcpy(s,pcempath);
|
||||
pclog("s = %s\n", s);
|
||||
// pclog("s = %s\n", s);
|
||||
put_backslash(s);
|
||||
pclog("s = %s\n", s);
|
||||
pclog("strcat %s %s\n", s, fn);
|
||||
// pclog("s = %s\n", s);
|
||||
// pclog("strcat %s %s\n", s, fn);
|
||||
strcat(s,fn);
|
||||
pclog("s = %s\n", s);
|
||||
// pclog("s = %s\n", s);
|
||||
return fopen(s,mode);
|
||||
}
|
||||
|
||||
|
|
@ -76,18 +79,14 @@ static void mem_load_atide_bios()
|
|||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
int loadbios()
|
||||
|
||||
int mem_load_video_bios()
|
||||
{
|
||||
FILE *f=NULL,*ff=NULL;
|
||||
FILE *f = NULL;
|
||||
int c;
|
||||
|
||||
loadfont("mda.rom", 0);
|
||||
|
||||
memset(vrom,0x63,0x8000);
|
||||
// printf("Loadrom - VGA %i\n",VGA);
|
||||
if (VID_EGA)
|
||||
switch (gfxcard)
|
||||
{
|
||||
case GFX_EGA:
|
||||
f=romfopen("roms/ibm_6277356_ega_card_u44_27128.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
|
|
@ -101,67 +100,170 @@ int loadbios()
|
|||
vrom[c]=getc(f);
|
||||
}
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (VGA)
|
||||
{
|
||||
break;
|
||||
|
||||
case GFX_TVGA:
|
||||
f=romfopen("roms/trident.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (ET4000)
|
||||
{
|
||||
break;
|
||||
|
||||
case GFX_ET4000:
|
||||
f=romfopen("roms/et4000.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (ET4000W32)
|
||||
{
|
||||
break;
|
||||
|
||||
case GFX_ET4000W32:
|
||||
f=romfopen("roms/et4000w32.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (gfxcard == GFX_BAHAMAS64)
|
||||
{
|
||||
break;
|
||||
|
||||
case GFX_BAHAMAS64:
|
||||
f=romfopen("roms/bahamas64.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (gfxcard == GFX_N9_9FX)
|
||||
{
|
||||
break;
|
||||
|
||||
case GFX_N9_9FX:
|
||||
f=romfopen("roms/s3_764.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (gfxcard == GFX_STEALTH64)
|
||||
{
|
||||
break;
|
||||
|
||||
case GFX_STEALTH64:
|
||||
f=romfopen("roms/TRIO64 (Ver. 1.5-07) [VGA] (S3 Incorporated).bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GFX_VIRGE:
|
||||
f=romfopen("roms/s3virge.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
memset(romext,0x63,0x8000);
|
||||
case GFX_TGUI9440:
|
||||
f=romfopen("roms/9440.vbi","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case GFX_VGA:
|
||||
f=romfopen("roms/ibm_vga.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case GFX_VGAEDGE16:
|
||||
f=romfopen("roms/vgaedge16.vbi","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case GFX_VGACHARGER:
|
||||
f=romfopen("roms/bios.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case GFX_OTI067:
|
||||
f=romfopen("roms/oti067/bios.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case GFX_MACH64GX:
|
||||
f=romfopen("roms/mach64gx/bios.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case GFX_CL_GD5429:
|
||||
f=romfopen("roms/5429.vbi","rb");
|
||||
if (f)
|
||||
{
|
||||
fread(vrom,32768,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
memset(vrom,0x63,0x8000);
|
||||
return 1;
|
||||
}
|
||||
pclog("mem_load_video_bios : failed to load video BIOS for gfxcard %i\n", gfxcard);
|
||||
memset(vrom,0x63,0x8000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loadbios()
|
||||
{
|
||||
FILE *f=NULL,*ff=NULL;
|
||||
int c;
|
||||
|
||||
loadfont("mda.rom", 0);
|
||||
|
||||
biosmask = 0xffff;
|
||||
|
||||
memset(romext,0x63,0x4000);
|
||||
|
||||
pclog("Starting with romset %i\n", romset);
|
||||
|
||||
switch (romset)
|
||||
|
|
@ -484,6 +586,17 @@ int loadbios()
|
|||
//is486=1;
|
||||
return 1;
|
||||
|
||||
case ROM_430VX:
|
||||
// f = romfopen("roms/430vx/Ga586atv.bin", "rb");
|
||||
// f = fopen("roms/430vx/vx29.BIN", "rb");
|
||||
f = romfopen("roms/430vx/55XWUQ0E.BIN", "rb");
|
||||
// f=romfopen("roms/430vx/430vx","rb");
|
||||
if (!f) break;
|
||||
fread(rom, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
//is486=1;
|
||||
return 1;
|
||||
}
|
||||
printf("Failed to load ROM!\n");
|
||||
if (f) fclose(f);
|
||||
|
|
@ -663,20 +776,23 @@ extern uint32_t testr[9];
|
|||
|
||||
uint32_t mmutranslatereal(uint32_t addr, int rw)
|
||||
{
|
||||
int mmuout=0;
|
||||
uint32_t addr2;
|
||||
uint32_t temp,temp2,temp3;
|
||||
if (abrt) return -1;
|
||||
if (abrt)
|
||||
{
|
||||
// pclog("Translate recursive abort\n");
|
||||
return -1;
|
||||
}
|
||||
/* if ((addr&~0xFFFFF)==0x77f00000) pclog("Do translate %08X %i %08X %08X\n",addr,rw,EAX,pc);
|
||||
if (addr==0x77f61000) output = 3;
|
||||
if (addr==0x77f62000) { dumpregs(); exit(-1); }
|
||||
if (addr==0x77f9a000) { dumpregs(); exit(-1); }*/
|
||||
addr2=(cr3+((addr>>20)&0xFFC));
|
||||
temp=temp2=((uint32_t *)ram)[addr2>>2];
|
||||
// pclog("Do translate %08X %i %08X\n", addr, rw, temp);
|
||||
// if (output == 3) pclog("Do translate %08X %i %08X\n", addr, rw, temp);
|
||||
if (!(temp&1))// || (CPL==3 && !(temp&4) && !cpl_override) || (rw && !(temp&2) && (CPL==3 || cr0&WP_FLAG)))
|
||||
{
|
||||
// if (/*output==3 && */!nopageerrors) pclog("Section not present! %08X %08X %02X %04X:%08X %i %i\n",addr,temp,opcode,CS,pc,CPL,rw);
|
||||
// /*if (!nopageerrors && opcode != 0xf3 && opcode != 0x89) */pclog("Section not present! %08X %08X %02X %04X:%08X %i %i\n",addr,temp,opcode,CS,pc,CPL,rw);
|
||||
|
||||
cr2=addr;
|
||||
temp&=1;
|
||||
|
|
@ -693,13 +809,16 @@ uint32_t mmutranslatereal(uint32_t addr, int rw)
|
|||
}
|
||||
temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2];
|
||||
temp3=temp&temp2;
|
||||
// pclog("Do translate %08X %08X\n", temp, temp3);
|
||||
// if (output == 3) pclog("Do translate %08X %08X\n", temp, temp3);
|
||||
if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG)))
|
||||
{
|
||||
// if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %04X:%08X %04X:%08X %i %i %i\n",addr,temp,opcode,opcode2,CS,pc,SS,ESP,ins,CPL,rw);
|
||||
// /*if (!nopageerrors && opcode != 0xf3 && opcode != 0x89) */pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X %04X:%08X %i %i %i\n",addr,temp,opcode,opcode2,frame,rmdat32, CS,pc,SS,ESP,ins,CPL,rw);
|
||||
|
||||
// dumpregs();
|
||||
// exit(-1);
|
||||
// if (addr == 0x815F6E90) output = 3;
|
||||
/* if (addr == 0x10ADE020) output = 3;
|
||||
if (addr == 0x10000008)
|
||||
/* if (addr == 0x10ADE020) output = 3;*/
|
||||
/* if (addr == 0x10150010 && !nopageerrors)
|
||||
{
|
||||
dumpregs();
|
||||
exit(-1);
|
||||
|
|
@ -816,7 +935,7 @@ uint8_t *getpccache(uint32_t a)
|
|||
{
|
||||
// int logit=(a>0xFFFFF);
|
||||
uint32_t a2=a;
|
||||
if (readlookup2[a>>12]!=0xFFFFFFFF) return &ram[(uint8_t *)readlookup2[a>>12] - (uint8_t *)(a&~0xFFF)];
|
||||
//if (readlookup2[a>>12]!=0xFFFFFFFF) return &ram[(uint8_t *)readlookup2[a>>12] - (uint8_t *)(a&~0xFFF)];
|
||||
if (cr0>>31)
|
||||
{
|
||||
// if (output==3) pclog("Translate GetPCCache %08X\n",a);
|
||||
|
|
@ -870,12 +989,8 @@ uint8_t readmembl(uint32_t addr)
|
|||
}
|
||||
addr &= rammask;
|
||||
|
||||
switch (addr>>16)
|
||||
{
|
||||
case 13: if (romset==ROM_AMI286) return neat_readems(addr); return 0xFF;
|
||||
// case 14: pclog("Read %06X\n", addr); if (shadowbios) { /*printf("Read shadow RAM %08X %02X\n",addr,ram[addr]);*/ return ram[addr]; }
|
||||
}
|
||||
if (_mem_read_b[addr >> 15]) return _mem_read_b[addr >> 15](addr);
|
||||
if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv[addr >> 14]);
|
||||
// pclog("Bad readmembl %08X %04X:%08X\n", addr, CS, pc);
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
|
|
@ -890,15 +1005,8 @@ void writemembl(uint32_t addr, uint8_t val)
|
|||
}
|
||||
addr &= rammask;
|
||||
|
||||
switch (addr>>16)
|
||||
{
|
||||
case 13: if (romset==ROM_AMI286) neat_writeems(addr,val); return;
|
||||
// case 14: printf("Write %08X %02X\n",addr,val); //ram[addr]=val;
|
||||
// if (isram[(addr>>16)&0xFF]) ram[addr]=val;
|
||||
// return;
|
||||
}
|
||||
if (_mem_write_b[addr >> 15]) _mem_write_b[addr >> 15](addr, val);
|
||||
// else pclog("Bad write %08X %02X\n", addr, val);
|
||||
if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv[addr >> 14]);
|
||||
// else pclog("Bad write %08X %02X %04X:%08X\n", addr, val, CS, pc);
|
||||
}
|
||||
|
||||
uint8_t readmemb386l(uint32_t seg, uint32_t addr)
|
||||
|
|
@ -910,10 +1018,10 @@ uint8_t readmemb386l(uint32_t seg, uint32_t addr)
|
|||
return -1;
|
||||
}
|
||||
mem_logical_addr = addr = addr + seg;
|
||||
if (readlookup2[mem_logical_addr >> 12] != 0xFFFFFFFF)
|
||||
/* if (readlookup2[mem_logical_addr >> 12] != 0xFFFFFFFF)
|
||||
{
|
||||
return ram[readlookup2[mem_logical_addr >> 12] + (mem_logical_addr & 0xFFF)];
|
||||
}
|
||||
}*/
|
||||
|
||||
if (cr0 >> 31)
|
||||
{
|
||||
|
|
@ -923,7 +1031,8 @@ uint8_t readmemb386l(uint32_t seg, uint32_t addr)
|
|||
|
||||
addr &= rammask;
|
||||
|
||||
if (_mem_read_b[addr >> 15]) return _mem_read_b[addr >> 15](addr);
|
||||
if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv[addr >> 14]);
|
||||
// pclog("Bad readmemb386l %08X %04X:%08X\n", addr, CS, pc);
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
|
|
@ -945,8 +1054,11 @@ void writememb386l(uint32_t seg, uint32_t addr, uint8_t val)
|
|||
|
||||
addr &= rammask;
|
||||
|
||||
if (_mem_write_b[addr >> 15]) _mem_write_b[addr >> 15](addr, val);
|
||||
// else pclog("Bad write %08X %02X\n", addr, val);
|
||||
/* if (addr >= 0xa0000 && addr < 0xc0000)
|
||||
pclog("writemembl %08X %02X\n", addr, val);*/
|
||||
|
||||
if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv[addr >> 14]);
|
||||
// else pclog("Bad write %08X %02X %04X:%08X\n", addr, val, CS, pc);
|
||||
}
|
||||
|
||||
uint16_t readmemwl(uint32_t seg, uint32_t addr)
|
||||
|
|
@ -956,8 +1068,8 @@ uint16_t readmemwl(uint32_t seg, uint32_t addr)
|
|||
{
|
||||
if (cr0>>31)
|
||||
{
|
||||
if (mmutranslate(addr2, 0) == 0xffffffff) return;
|
||||
if (mmutranslate(addr2+1, 0) == 0xffffffff) return;
|
||||
if (mmutranslate(addr2, 0) == 0xffffffff) return 0xffff;
|
||||
if (mmutranslate(addr2+1, 0) == 0xffffffff) return 0xffff;
|
||||
}
|
||||
if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8);
|
||||
else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8);
|
||||
|
|
@ -976,12 +1088,12 @@ uint16_t readmemwl(uint32_t seg, uint32_t addr)
|
|||
|
||||
addr2 &= rammask;
|
||||
|
||||
if (_mem_read_w[addr2 >> 15]) return _mem_read_w[addr2 >> 15](addr2);
|
||||
if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]);
|
||||
|
||||
if (_mem_read_b[addr2 >> 15])
|
||||
if (_mem_read_b[addr2 >> 14])
|
||||
{
|
||||
if (AT) return _mem_read_b[addr2 >> 15](addr2) | (_mem_read_b[(addr2 + 1) >> 15](addr2 + 1) << 8);
|
||||
else return _mem_read_b[addr2 >> 15](addr2) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 15](seg + ((addr + 1) & 0xffff)) << 8);
|
||||
if (AT) return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv[addr2 >> 14]) << 8);
|
||||
else return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv[addr2 >> 14]) << 8);
|
||||
}
|
||||
return 0xffff;
|
||||
}
|
||||
|
|
@ -1022,19 +1134,20 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val)
|
|||
}
|
||||
|
||||
addr2 &= rammask;
|
||||
|
||||
/* if (addr2 >= 0xa0000 && addr2 < 0xc0000)
|
||||
pclog("writememwl %08X %02X\n", addr2, val);*/
|
||||
|
||||
if (_mem_write_w[addr2 >> 15])
|
||||
if (_mem_write_w[addr2 >> 14])
|
||||
{
|
||||
_mem_write_w[addr2 >> 15](addr2, val);
|
||||
_mem_write_w[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_mem_write_b[addr2 >> 15])
|
||||
if (_mem_write_b[addr2 >> 14])
|
||||
{
|
||||
_mem_write_b[addr2 >> 15](addr2, val);
|
||||
_mem_write_b[(addr2 + 1) >> 15](addr2 + 1, val >> 8);
|
||||
// if (AT) _
|
||||
// else _mem_write_b[(seg + ((addr + 1) & 0xffff)) >> 15](seg + ((addr + 1) & 0xffff), val >> 8);
|
||||
_mem_write_b[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]);
|
||||
_mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv[addr2 >> 14]);
|
||||
return;
|
||||
}
|
||||
// pclog("Bad write %08X %04X\n", addr, val);
|
||||
|
|
@ -1047,8 +1160,8 @@ uint32_t readmemll(uint32_t seg, uint32_t addr)
|
|||
{
|
||||
if (cr0>>31)
|
||||
{
|
||||
if (mmutranslate(addr2, 0) == 0xffffffff) return;
|
||||
if (mmutranslate(addr2+3, 0) == 0xffffffff) return;
|
||||
if (mmutranslate(addr2, 0) == 0xffffffff) return 0xffffffff;
|
||||
if (mmutranslate(addr2+3, 0) == 0xffffffff) return 0xffffffff;
|
||||
}
|
||||
return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16);
|
||||
}
|
||||
|
|
@ -1068,11 +1181,11 @@ uint32_t readmemll(uint32_t seg, uint32_t addr)
|
|||
|
||||
addr2&=rammask;
|
||||
|
||||
if (_mem_read_l[addr2 >> 15]) return _mem_read_l[addr2 >> 15](addr2);
|
||||
if (_mem_read_l[addr2 >> 14]) return _mem_read_l[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]);
|
||||
|
||||
if (_mem_read_w[addr2 >> 15]) return _mem_read_w[addr2 >> 15](addr2) | (_mem_read_w[addr2 >> 15](addr2 + 2) << 16);
|
||||
if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv[addr2 >> 14]) << 16);
|
||||
|
||||
if (_mem_read_b[addr2 >> 15]) return _mem_read_b[addr2 >> 15](addr2) | (_mem_read_b[addr2 >> 15](addr2 + 1) << 8) | (_mem_read_b[addr2 >> 15](addr2 + 2) << 16) | (_mem_read_b[addr2 >> 15](addr2 + 3) << 24);
|
||||
if (_mem_read_b[addr2 >> 14]) return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv[addr2 >> 14]) << 8) | (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv[addr2 >> 14]) << 16) | (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv[addr2 >> 14]) << 24);
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
|
@ -1106,67 +1219,70 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val)
|
|||
|
||||
addr2&=rammask;
|
||||
|
||||
if (_mem_write_l[addr2 >> 15])
|
||||
/* if (addr >= 0xa0000 && addr < 0xc0000)
|
||||
pclog("writememll %08X %08X\n", addr, val);*/
|
||||
|
||||
if (_mem_write_l[addr2 >> 14])
|
||||
{
|
||||
_mem_write_l[addr2 >> 15](addr2, val);
|
||||
_mem_write_l[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]);
|
||||
return;
|
||||
}
|
||||
if (_mem_write_w[addr2 >> 15])
|
||||
if (_mem_write_w[addr2 >> 14])
|
||||
{
|
||||
_mem_write_w[addr2 >> 15](addr2, val);
|
||||
_mem_write_w[addr2 >> 15](addr2 + 2, val >> 16);
|
||||
_mem_write_w[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]);
|
||||
_mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv[addr2 >> 14]);
|
||||
return;
|
||||
}
|
||||
if (_mem_write_b[addr2 >> 15])
|
||||
if (_mem_write_b[addr2 >> 14])
|
||||
{
|
||||
_mem_write_b[addr2 >> 15](addr2, val);
|
||||
_mem_write_b[addr2 >> 15](addr2 + 1, val >> 8);
|
||||
_mem_write_b[addr2 >> 15](addr2 + 2, val >> 16);
|
||||
_mem_write_b[addr2 >> 15](addr2 + 3, val >> 24);
|
||||
_mem_write_b[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]);
|
||||
_mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv[addr2 >> 14]);
|
||||
_mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv[addr2 >> 14]);
|
||||
_mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv[addr2 >> 14]);
|
||||
return;
|
||||
}
|
||||
// pclog("Bad write %08X %08X\n", addr, val);
|
||||
}
|
||||
|
||||
uint8_t mem_read_ram(uint32_t addr)
|
||||
uint8_t mem_read_ram(uint32_t addr, void *priv)
|
||||
{
|
||||
// if (addr < 0xa0000) pclog("Read RAMb %08X\n", addr);
|
||||
// if (addr >= 0xe0000 && addr < 0x100000) pclog("Read RAMb %08X\n", addr);
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
return ram[addr];
|
||||
}
|
||||
uint16_t mem_read_ramw(uint32_t addr)
|
||||
uint16_t mem_read_ramw(uint32_t addr, void *priv)
|
||||
{
|
||||
// if (addr < 0xa0000) pclog("Read RAMw %08X\n", addr);
|
||||
// if (addr >= 0xe0000 && addr < 0x100000) pclog("Read RAMw %08X\n", addr);
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
return *(uint16_t *)&ram[addr];
|
||||
}
|
||||
uint32_t mem_read_raml(uint32_t addr)
|
||||
uint32_t mem_read_raml(uint32_t addr, void *priv)
|
||||
{
|
||||
// if (addr < 0xa0000) pclog("Read RAMl %08X\n", addr);
|
||||
// if (addr >= 0xe0000 && addr < 0x100000) pclog("Read RAMl %08X\n", addr);
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
return *(uint32_t *)&ram[addr];
|
||||
}
|
||||
|
||||
void mem_write_ram(uint32_t addr, uint8_t val)
|
||||
void mem_write_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
ram[addr] = val;
|
||||
// if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMb %08X\n", addr);
|
||||
}
|
||||
void mem_write_ramw(uint32_t addr, uint16_t val)
|
||||
void mem_write_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
*(uint16_t *)&ram[addr] = val;
|
||||
// if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMw %08X %04X:%04X\n", addr, CS, pc);
|
||||
// if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMw %08X %04X:%04X %i %04X %04X:%04X %04X:%04X\n", addr, CS, pc, ins, val, DS,SI, ES,DI);
|
||||
}
|
||||
void mem_write_raml(uint32_t addr, uint32_t val)
|
||||
void mem_write_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
*(uint32_t *)&ram[addr] = val;
|
||||
// if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMl %08X %04X:%04X %04X:%04X %04X:%04X\n", addr, CS, pc, DS,SI, ES,DI);
|
||||
}
|
||||
|
||||
uint8_t mem_read_bios(uint32_t addr)
|
||||
uint8_t mem_read_bios(uint32_t addr, void *priv)
|
||||
{
|
||||
if (AMIBIOS && (addr&0xFFFFF)==0xF8281) /*This is read constantly during AMIBIOS POST, but is never written to. It's clearly a status register of some kind, but for what?*/
|
||||
{
|
||||
|
|
@ -1177,39 +1293,39 @@ uint8_t mem_read_bios(uint32_t addr)
|
|||
// if (output) pclog("Read BIOS %08X %02X %04X:%04X\n", addr, rom[addr & biosmask], CS, pc);
|
||||
return rom[addr & biosmask];
|
||||
}
|
||||
uint16_t mem_read_biosw(uint32_t addr)
|
||||
uint16_t mem_read_biosw(uint32_t addr, void *priv)
|
||||
{
|
||||
// if (output) pclog("Read BIOS %08X %04X %04X:%04X\n", addr, *(uint16_t *)&rom[addr & biosmask], CS, pc);
|
||||
// /*if (output) */pclog("Read BIOS %08X %04X %04X:%04X\n", addr, *(uint16_t *)&rom[addr & biosmask], CS, pc);
|
||||
return *(uint16_t *)&rom[addr & biosmask];
|
||||
}
|
||||
uint32_t mem_read_biosl(uint32_t addr)
|
||||
uint32_t mem_read_biosl(uint32_t addr, void *priv)
|
||||
{
|
||||
// if (output) pclog("Read BIOS %08X %02X %04X:%04X\n", addr, *(uint32_t *)&rom[addr & biosmask], CS, pc);
|
||||
// pclog("Read BIOS %08X %02X %04X:%04X\n", addr, *(uint32_t *)&rom[addr & biosmask], CS, pc);
|
||||
return *(uint32_t *)&rom[addr & biosmask];
|
||||
}
|
||||
|
||||
uint8_t mem_read_vrom(uint32_t addr)
|
||||
uint8_t mem_read_vrom(uint32_t addr, void *priv)
|
||||
{
|
||||
return vrom[addr & 0x7fff];
|
||||
}
|
||||
uint16_t mem_read_vromw(uint32_t addr)
|
||||
uint16_t mem_read_vromw(uint32_t addr, void *priv)
|
||||
{
|
||||
return *(uint16_t *)&vrom[addr & 0x7fff];
|
||||
}
|
||||
uint32_t mem_read_vroml(uint32_t addr)
|
||||
uint32_t mem_read_vroml(uint32_t addr, void *priv)
|
||||
{
|
||||
return *(uint32_t *)&vrom[addr & 0x7fff];
|
||||
}
|
||||
|
||||
uint8_t mem_read_romext(uint32_t addr)
|
||||
uint8_t mem_read_romext(uint32_t addr, void *priv)
|
||||
{
|
||||
return romext[addr & 0x7fff];
|
||||
}
|
||||
uint16_t mem_read_romextw(uint32_t addr)
|
||||
uint16_t mem_read_romextw(uint32_t addr, void *priv)
|
||||
{
|
||||
return *(uint16_t *)&romext[addr & 0x7fff];
|
||||
}
|
||||
uint32_t mem_read_romextl(uint32_t addr)
|
||||
uint32_t mem_read_romextl(uint32_t addr, void *priv)
|
||||
{
|
||||
return *(uint32_t *)&romext[addr & 0x7fff];
|
||||
}
|
||||
|
|
@ -1233,16 +1349,16 @@ void mem_init()
|
|||
isram[c]=1;
|
||||
if (c >= 0xa && c<=0xF) isram[c]=0;
|
||||
}
|
||||
for (c = 0; c < 0x20000; c++)
|
||||
_mem_read_b[c] = _mem_read_w[c] = _mem_read_l[c] = _mem_write_b[c] = _mem_write_w[c] = _mem_write_l[c] = NULL;
|
||||
for (c = 0; c < 0x40000; c++)
|
||||
_mem_read_b[c] = _mem_read_w[c] = _mem_read_l[c] = _mem_write_b[c] = _mem_write_w[c] = _mem_write_l[c] = _mem_priv[c] = NULL;
|
||||
|
||||
mem_sethandler(0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml);
|
||||
mem_sethandler(0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL);
|
||||
if (mem_size > 1)
|
||||
mem_sethandler(0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml);
|
||||
mem_sethandler(0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL);
|
||||
|
||||
mem_sethandler(0xc0000, 0x08000, mem_read_vrom, mem_read_vromw, mem_read_vroml, NULL, NULL, NULL);
|
||||
mem_sethandler(0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL);
|
||||
mem_sethandler(0xe0000, 0x20000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml);
|
||||
mem_sethandler(0xc0000, 0x08000, mem_read_vrom, mem_read_vromw, mem_read_vroml, NULL, NULL, NULL, NULL);
|
||||
mem_sethandler(0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, NULL);
|
||||
mem_sethandler(0xe0000, 0x20000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL);
|
||||
// pclog("Mem resize %i %i\n",mem_size,c);
|
||||
}
|
||||
|
||||
|
|
@ -1258,16 +1374,16 @@ void mem_resize()
|
|||
isram[c]=1;
|
||||
if (c >= 0xa && c<=0xF) isram[c]=0;
|
||||
}
|
||||
for (c = 0; c < 0x20000; c++)
|
||||
_mem_read_b[c] = _mem_read_w[c] = _mem_read_l[c] = _mem_write_b[c] = _mem_write_w[c] = _mem_write_l[c] = NULL;
|
||||
for (c = 0; c < 0x40000; c++)
|
||||
_mem_read_b[c] = _mem_read_w[c] = _mem_read_l[c] = _mem_write_b[c] = _mem_write_w[c] = _mem_write_l[c] = _mem_priv[c] = NULL;
|
||||
|
||||
mem_sethandler(0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml);
|
||||
mem_sethandler(0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL);
|
||||
if (mem_size > 1)
|
||||
mem_sethandler(0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml);
|
||||
mem_sethandler(0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL);
|
||||
|
||||
mem_sethandler(0xc0000, 0x8000, mem_read_vrom, mem_read_vromw, mem_read_vroml, NULL, NULL, NULL);
|
||||
mem_sethandler(0xc8000, 0x8000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL);
|
||||
mem_sethandler(0xe0000, 0x20000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml);
|
||||
mem_sethandler(0xc0000, 0x8000, mem_read_vrom, mem_read_vromw, mem_read_vroml, NULL, NULL, NULL, NULL);
|
||||
mem_sethandler(0xc8000, 0x8000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, NULL);
|
||||
mem_sethandler(0xe0000, 0x20000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL);
|
||||
// pclog("Mem resize %i %i\n",mem_size,c);
|
||||
}
|
||||
|
||||
|
|
@ -1295,44 +1411,62 @@ void mem_updatecache()
|
|||
}
|
||||
|
||||
void mem_sethandler(uint32_t base, uint32_t size,
|
||||
uint8_t (*read_b)(uint32_t addr),
|
||||
uint16_t (*read_w)(uint32_t addr),
|
||||
uint32_t (*read_l)(uint32_t addr),
|
||||
void (*write_b)(uint32_t addr, uint8_t val),
|
||||
void (*write_w)(uint32_t addr, uint16_t val),
|
||||
void (*write_l)(uint32_t addr, uint32_t val))
|
||||
uint8_t (*read_b)(uint32_t addr, void *priv),
|
||||
uint16_t (*read_w)(uint32_t addr, void *priv),
|
||||
uint32_t (*read_l)(uint32_t addr, void *priv),
|
||||
void (*write_b)(uint32_t addr, uint8_t val, void *priv),
|
||||
void (*write_w)(uint32_t addr, uint16_t val, void *priv),
|
||||
void (*write_l)(uint32_t addr, uint32_t val, void *priv),
|
||||
void *priv)
|
||||
{
|
||||
uint32_t c;
|
||||
for (c = base; c < base + size; c += 0x8000)
|
||||
// printf("mem_sethandler : %05X %04X %08X %08X %08X %08X %08X\n", base, size, read_w, write_w, mem_read_biosw, mem_read_ramw, mem_write_ramw);
|
||||
for (c = base; c < base + size; c += 0x4000)
|
||||
{
|
||||
_mem_read_b[ c >> 15] = read_b;
|
||||
_mem_read_w[ c >> 15] = read_w;
|
||||
_mem_read_l[ c >> 15] = read_l;
|
||||
_mem_write_b[c >> 15] = write_b;
|
||||
_mem_write_w[c >> 15] = write_w;
|
||||
_mem_write_l[c >> 15] = write_l;
|
||||
_mem_read_b[ c >> 14] = read_b;
|
||||
_mem_read_w[ c >> 14] = read_w;
|
||||
_mem_read_l[ c >> 14] = read_l;
|
||||
_mem_write_b[c >> 14] = write_b;
|
||||
_mem_write_w[c >> 14] = write_w;
|
||||
_mem_write_l[c >> 14] = write_l;
|
||||
_mem_priv[c >> 14] = priv;
|
||||
}
|
||||
for (c = base; c < base + size; c += 0x1000)
|
||||
{
|
||||
readlookup2[c >> 12] = 0xFFFFFFFF;
|
||||
writelookup2[c >> 12] = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
void mem_removehandler(uint32_t base, uint32_t size,
|
||||
uint8_t (*read_b)(uint32_t addr),
|
||||
uint16_t (*read_w)(uint32_t addr),
|
||||
uint32_t (*read_l)(uint32_t addr),
|
||||
void (*write_b)(uint32_t addr, uint8_t val),
|
||||
void (*write_w)(uint32_t addr, uint16_t val),
|
||||
void (*write_l)(uint32_t addr, uint32_t val))
|
||||
uint8_t (*read_b)(uint32_t addr, void *priv),
|
||||
uint16_t (*read_w)(uint32_t addr, void *priv),
|
||||
uint32_t (*read_l)(uint32_t addr, void *priv),
|
||||
void (*write_b)(uint32_t addr, uint8_t val, void *priv),
|
||||
void (*write_w)(uint32_t addr, uint16_t val, void *priv),
|
||||
void (*write_l)(uint32_t addr, uint32_t val, void *priv),
|
||||
void *priv)
|
||||
{
|
||||
uint32_t c;
|
||||
if ((base + size) > 0xffff8000)
|
||||
size = 0xffff0000 - base;
|
||||
for (c = base; c < base + size; c += 0x8000)
|
||||
for (c = base; c < base + size; c += 0x4000)
|
||||
{
|
||||
if ( _mem_read_b[c >> 15] == read_b) _mem_read_b[c >> 15] = NULL;
|
||||
if ( _mem_read_w[c >> 15] == read_w) _mem_read_w[c >> 15] = NULL;
|
||||
if ( _mem_read_l[c >> 15] == read_l) _mem_read_l[c >> 15] = NULL;
|
||||
if (_mem_write_b[c >> 15] == write_b) _mem_write_b[c >> 15] = NULL;
|
||||
if (_mem_write_w[c >> 15] == write_w) _mem_write_w[c >> 15] = NULL;
|
||||
if (_mem_write_l[c >> 15] == write_l) _mem_write_l[c >> 15] = NULL;
|
||||
if (_mem_priv[c >> 14] == priv)
|
||||
{
|
||||
if ( _mem_read_b[c >> 14] == read_b) _mem_read_b[c >> 14] = NULL;
|
||||
if ( _mem_read_w[c >> 14] == read_w) _mem_read_w[c >> 14] = NULL;
|
||||
if ( _mem_read_l[c >> 14] == read_l) _mem_read_l[c >> 14] = NULL;
|
||||
if (_mem_write_b[c >> 14] == write_b) _mem_write_b[c >> 14] = NULL;
|
||||
if (_mem_write_w[c >> 14] == write_w) _mem_write_w[c >> 14] = NULL;
|
||||
if (_mem_write_l[c >> 14] == write_l) _mem_write_l[c >> 14] = NULL;
|
||||
_mem_priv[c >> 14] = NULL;
|
||||
}
|
||||
}
|
||||
for (c = base; c < base + size; c += 0x1000)
|
||||
{
|
||||
readlookup2[c >> 12] = 0xFFFFFFFF;
|
||||
writelookup2[c >> 12] = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1342,7 +1476,7 @@ static int mem_a20_state = 0;
|
|||
void mem_a20_recalc()
|
||||
{
|
||||
int state = mem_a20_key | mem_a20_alt;
|
||||
pclog("A20 recalc %i %i\n", state, mem_a20_state);
|
||||
// pclog("A20 recalc %i %i\n", state, mem_a20_state);
|
||||
if (state && !mem_a20_state)
|
||||
{
|
||||
rammask = 0xffffffff;
|
||||
|
|
@ -1353,6 +1487,6 @@ void mem_a20_recalc()
|
|||
rammask = 0xffefffff;
|
||||
flushmmucache();
|
||||
}
|
||||
pclog("rammask now %08X\n", rammask);
|
||||
// pclog("rammask now %08X\n", rammask);
|
||||
mem_a20_state = state;
|
||||
}
|
||||
|
|
|
|||
46
src/mem.h
46
src/mem.h
|
|
@ -7,34 +7,38 @@ extern int cache;
|
|||
extern int memwaitstate;
|
||||
|
||||
void mem_sethandler(uint32_t base, uint32_t size,
|
||||
uint8_t (*read_b)(uint32_t addr),
|
||||
uint16_t (*read_w)(uint32_t addr),
|
||||
uint32_t (*read_l)(uint32_t addr),
|
||||
void (*write_b)(uint32_t addr, uint8_t val),
|
||||
void (*write_w)(uint32_t addr, uint16_t val),
|
||||
void (*write_l)(uint32_t addr, uint32_t val));
|
||||
uint8_t (*read_b)(uint32_t addr, void *priv),
|
||||
uint16_t (*read_w)(uint32_t addr, void *priv),
|
||||
uint32_t (*read_l)(uint32_t addr, void *priv),
|
||||
void (*write_b)(uint32_t addr, uint8_t val, void *priv),
|
||||
void (*write_w)(uint32_t addr, uint16_t val, void *priv),
|
||||
void (*write_l)(uint32_t addr, uint32_t val, void *priv),
|
||||
void *priv);
|
||||
|
||||
void mem_removehandler(uint32_t base, uint32_t size,
|
||||
uint8_t (*read_b)(uint32_t addr),
|
||||
uint16_t (*read_w)(uint32_t addr),
|
||||
uint32_t (*read_l)(uint32_t addr),
|
||||
void (*write_b)(uint32_t addr, uint8_t val),
|
||||
void (*write_w)(uint32_t addr, uint16_t val),
|
||||
void (*write_l)(uint32_t addr, uint32_t val));
|
||||
uint8_t (*read_b)(uint32_t addr, void *priv),
|
||||
uint16_t (*read_w)(uint32_t addr, void *priv),
|
||||
uint32_t (*read_l)(uint32_t addr, void *priv),
|
||||
void (*write_b)(uint32_t addr, uint8_t val, void *priv),
|
||||
void (*write_w)(uint32_t addr, uint16_t val, void *priv),
|
||||
void (*write_l)(uint32_t addr, uint32_t val, void *priv),
|
||||
void *priv);
|
||||
extern int mem_a20_alt;
|
||||
extern int mem_a20_key;
|
||||
void mem_a20_recalc();
|
||||
|
||||
uint8_t mem_read_ram(uint32_t addr);
|
||||
uint16_t mem_read_ramw(uint32_t addr);
|
||||
uint32_t mem_read_raml(uint32_t addr);
|
||||
uint8_t mem_read_ram(uint32_t addr, void *priv);
|
||||
uint16_t mem_read_ramw(uint32_t addr, void *priv);
|
||||
uint32_t mem_read_raml(uint32_t addr, void *priv);
|
||||
|
||||
void mem_write_ram(uint32_t addr, uint8_t val);
|
||||
void mem_write_ramw(uint32_t addr, uint16_t val);
|
||||
void mem_write_raml(uint32_t addr, uint32_t val);
|
||||
void mem_write_ram(uint32_t addr, uint8_t val, void *priv);
|
||||
void mem_write_ramw(uint32_t addr, uint16_t val, void *priv);
|
||||
void mem_write_raml(uint32_t addr, uint32_t val, void *priv);
|
||||
|
||||
uint8_t mem_read_bios(uint32_t addr);
|
||||
uint16_t mem_read_biosw(uint32_t addr);
|
||||
uint32_t mem_read_biosl(uint32_t addr);
|
||||
uint8_t mem_read_bios(uint32_t addr, void *priv);
|
||||
uint16_t mem_read_biosw(uint32_t addr, void *priv);
|
||||
uint32_t mem_read_biosl(uint32_t addr, void *priv);
|
||||
|
||||
FILE *romfopen(char *fn, char *mode);
|
||||
|
||||
int mem_load_video_bios();
|
||||
|
|
|
|||
69
src/model.c
69
src/model.c
|
|
@ -6,14 +6,17 @@
|
|||
#include "acer386sx.h"
|
||||
#include "ali1429.h"
|
||||
#include "amstrad.h"
|
||||
#include "device.h"
|
||||
#include "dma.h"
|
||||
#include "fdc.h"
|
||||
#include "headland.h"
|
||||
#include "i430vx.h"
|
||||
#include "ide.h"
|
||||
#include "jim.h"
|
||||
#include "keyboard_xt.h"
|
||||
#include "keyboard_amstrad.h"
|
||||
#include "keyboard_at.h"
|
||||
#include "keyboard_olim24.h"
|
||||
#include "keyboard_xt.h"
|
||||
#include "lpt.h"
|
||||
#include "mouse_ps2.h"
|
||||
#include "mouse_serial.h"
|
||||
|
|
@ -22,9 +25,11 @@
|
|||
#include "olivetti_m24.h"
|
||||
#include "pci.h"
|
||||
#include "pic.h"
|
||||
#include "piix.h"
|
||||
#include "pit.h"
|
||||
#include "psg.h"
|
||||
#include "serial.h"
|
||||
#include "sound_sn76489.h"
|
||||
#include "um8669f.h"
|
||||
#include "um8881f.h"
|
||||
#include "wd76c10.h"
|
||||
#include "xtide.h"
|
||||
|
|
@ -41,33 +46,35 @@ void at_wd76c10_init();
|
|||
void at_ali1429_init();
|
||||
void at_headland_init();
|
||||
void at_um8881f_init();
|
||||
void at_i430vx_init();
|
||||
|
||||
int model;
|
||||
|
||||
MODEL models[] =
|
||||
{
|
||||
{"IBM PC", ROM_IBMPC, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"IBM XT", ROM_IBMXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"Generic XT clone", ROM_GENXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"DTK XT clone", ROM_DTKXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"Tandy 1000", ROM_TANDY, { "", cpus_8088, "", NULL, "", NULL}, 1, tandy1k_init},
|
||||
{"Amstrad PC1512", ROM_PC1512, { "", cpus_pc1512,"", NULL, "", NULL}, 1, ams_init},
|
||||
{"Sinclair PC200", ROM_PC200, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Euro PC", ROM_EUROPC, { "", cpus_8086, "", NULL, "", NULL}, 0, europc_init},
|
||||
{"Olivetti M24", ROM_OLIM24, { "", cpus_8086, "", NULL, "", NULL}, 1, olim24_init},
|
||||
{"Amstrad PC1640", ROM_PC1640, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Amstrad PC2086", ROM_PC2086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Amstrad PC3086", ROM_PC3086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"IBM AT", ROM_IBMAT, { "", cpus_ibmat, "", NULL, "", NULL}, 0, at_init},
|
||||
{"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, at_init},
|
||||
{"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, at_neat_init},
|
||||
{"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, at_init},
|
||||
{"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, at_acer386sx_init},
|
||||
{"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, at_wd76c10_init},
|
||||
{"AMI 386 clone", ROM_AMI386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, at_headland_init},
|
||||
{"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init},
|
||||
{"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init},
|
||||
{"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_um8881f_init},
|
||||
{"IBM PC", ROM_IBMPC, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"IBM XT", ROM_IBMXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"Generic XT clone", ROM_GENXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"DTK XT clone", ROM_DTKXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"Tandy 1000", ROM_TANDY, { "", cpus_8088, "", NULL, "", NULL}, 1, tandy1k_init},
|
||||
{"Amstrad PC1512", ROM_PC1512, { "", cpus_pc1512, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Sinclair PC200", ROM_PC200, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Euro PC", ROM_EUROPC, { "", cpus_8086, "", NULL, "", NULL}, 0, europc_init},
|
||||
{"Olivetti M24", ROM_OLIM24, { "", cpus_8086, "", NULL, "", NULL}, 1, olim24_init},
|
||||
{"Amstrad PC1640", ROM_PC1640, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Amstrad PC2086", ROM_PC2086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Amstrad PC3086", ROM_PC3086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"IBM AT", ROM_IBMAT, { "", cpus_ibmat, "", NULL, "", NULL}, 0, at_init},
|
||||
{"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, at_init},
|
||||
{"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, at_neat_init},
|
||||
{"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, at_init},
|
||||
{"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, at_acer386sx_init},
|
||||
{"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, at_wd76c10_init},
|
||||
{"AMI 386 clone", ROM_AMI386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, at_headland_init},
|
||||
{"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init},
|
||||
{"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init},
|
||||
{"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_um8881f_init},
|
||||
{"Award 430VX PCI", ROM_430VX, { "IDT", cpus_WinChip, "", NULL, "", NULL}, 0, at_i430vx_init},
|
||||
{"", -1, {"", 0, "", 0, "", 0}, 0}
|
||||
};
|
||||
|
||||
|
|
@ -84,7 +91,7 @@ char *model_getname()
|
|||
void common_init()
|
||||
{
|
||||
dma_init();
|
||||
fdc_init();
|
||||
fdc_add();
|
||||
lpt_init();
|
||||
pic_init();
|
||||
pit_init();
|
||||
|
|
@ -105,7 +112,7 @@ void tandy1k_init()
|
|||
common_init();
|
||||
keyboard_xt_init();
|
||||
mouse_serial_init();
|
||||
psg_init();
|
||||
device_add(&sn76489_device);
|
||||
xtide_init();
|
||||
}
|
||||
|
||||
|
|
@ -191,6 +198,16 @@ void at_um8881f_init()
|
|||
um8881f_init();
|
||||
}
|
||||
|
||||
void at_i430vx_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
pci_init();
|
||||
i430vx_init();
|
||||
piix_init(7);
|
||||
um8669f_init();
|
||||
}
|
||||
|
||||
void model_init()
|
||||
{
|
||||
pclog("Initting as %s\n", model_getname());
|
||||
|
|
|
|||
|
|
@ -14,3 +14,7 @@ typedef struct
|
|||
extern MODEL models[];
|
||||
|
||||
extern int model;
|
||||
|
||||
int model_getromset();
|
||||
char *model_getname();
|
||||
void model_init();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#include "ibm.h"
|
||||
#include "mouse.h"
|
||||
#include "pic.h"
|
||||
#include "serial.h"
|
||||
#include "timer.h"
|
||||
|
||||
static int oldb=0;
|
||||
|
||||
|
|
@ -37,11 +39,12 @@ void mouse_serial_poll(int x, int y, int b)
|
|||
void mouse_serial_rcr()
|
||||
{
|
||||
mousepos=-1;
|
||||
mousedelay=1000;
|
||||
mousedelay=5000 * (1 << TIMER_SHIFT);
|
||||
}
|
||||
|
||||
void mousecallback()
|
||||
{
|
||||
mousedelay = 0;
|
||||
if (mousepos == -1)
|
||||
{
|
||||
mousepos = 0;
|
||||
|
|
@ -62,5 +65,6 @@ void mouse_serial_init()
|
|||
{
|
||||
mouse_poll = mouse_serial_poll;
|
||||
serial_rcr = mouse_serial_rcr;
|
||||
timer_add(mousecallback, &mousedelay, &mousedelay, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
14
src/neat.c
14
src/neat.c
|
|
@ -7,7 +7,7 @@ static uint8_t neat_regs[256];
|
|||
static int neat_index;
|
||||
static int neat_emspage[4];
|
||||
|
||||
void neat_write(uint16_t port, uint8_t val)
|
||||
void neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
switch (port)
|
||||
{
|
||||
|
|
@ -35,7 +35,7 @@ void neat_write(uint16_t port, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t neat_read(uint16_t port)
|
||||
uint8_t neat_read(uint16_t port, void *priv)
|
||||
{
|
||||
switch (port)
|
||||
{
|
||||
|
|
@ -60,9 +60,9 @@ uint8_t neat_readems(uint32_t addr)
|
|||
|
||||
void neat_init()
|
||||
{
|
||||
io_sethandler(0x0022, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL);
|
||||
io_sethandler(0x0208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL);
|
||||
io_sethandler(0x4208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL);
|
||||
io_sethandler(0x8208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL);
|
||||
io_sethandler(0xc208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL);
|
||||
io_sethandler(0x0022, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x4208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x8208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL);
|
||||
io_sethandler(0xc208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
32
src/nvr.c
32
src/nvr.c
|
|
@ -1,7 +1,10 @@
|
|||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "nvr.h"
|
||||
#include "pic.h"
|
||||
#include "timer.h"
|
||||
|
||||
int oldromset;
|
||||
int nvrmask=63;
|
||||
|
|
@ -10,6 +13,8 @@ int nvraddr;
|
|||
|
||||
SYSTEMTIME systemtime;
|
||||
|
||||
int nvr_dosave = 0;
|
||||
|
||||
void getnvrtime()
|
||||
{
|
||||
int c,d;
|
||||
|
|
@ -51,9 +56,9 @@ void getnvrtime()
|
|||
void nvr_recalc()
|
||||
{
|
||||
int c;
|
||||
float newrtctime;
|
||||
int newrtctime;
|
||||
c=1<<((nvrram[0xA]&0xF)-1);
|
||||
newrtctime=RTCCONST*(float)c;
|
||||
newrtctime=(int)(RTCCONST * c * (1 << TIMER_SHIFT));
|
||||
if (rtctime>newrtctime) rtctime=newrtctime;
|
||||
}
|
||||
|
||||
|
|
@ -62,11 +67,11 @@ void nvr_rtc()
|
|||
int c;
|
||||
if (!(nvrram[0xA]&0xF))
|
||||
{
|
||||
rtctime=99999999;
|
||||
rtctime=0x7fffffff;
|
||||
return;
|
||||
}
|
||||
c=1<<((nvrram[0xA]&0xF)-1);
|
||||
rtctime+=RTCCONST*(float)c;
|
||||
rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT));
|
||||
// pclog("RTCtime now %f\n",rtctime);
|
||||
nvrram[0xC]=0x40;
|
||||
if (nvrram[0xB]&0x40)
|
||||
|
|
@ -78,7 +83,7 @@ void nvr_rtc()
|
|||
}
|
||||
}
|
||||
|
||||
void writenvr(uint16_t addr, uint8_t val)
|
||||
void writenvr(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int c;
|
||||
// printf("Write NVR %03X %02X %02X %04X:%04X %i\n",addr,nvraddr,val,cs>>4,pc,ins);
|
||||
|
|
@ -86,7 +91,7 @@ void writenvr(uint16_t addr, uint8_t val)
|
|||
{
|
||||
// if (nvraddr == 0x33) pclog("NVRWRITE33 %02X %04X:%04X %i\n",val,CS,pc,ins);
|
||||
if (nvraddr >= 0xe && nvrram[nvraddr] != val)
|
||||
savenvr();
|
||||
nvr_dosave = 1;
|
||||
if (nvraddr!=0xC && nvraddr!=0xD) nvrram[nvraddr]=val;
|
||||
|
||||
if (nvraddr==0xA)
|
||||
|
|
@ -95,16 +100,16 @@ void writenvr(uint16_t addr, uint8_t val)
|
|||
if (val&0xF)
|
||||
{
|
||||
c=1<<((val&0xF)-1);
|
||||
rtctime+=RTCCONST*(float)c;
|
||||
rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT));
|
||||
}
|
||||
else
|
||||
rtctime=99999999;
|
||||
rtctime = 0x7fffffff;
|
||||
}
|
||||
}
|
||||
else nvraddr=val&nvrmask;
|
||||
}
|
||||
|
||||
uint8_t readnvr(uint16_t addr)
|
||||
uint8_t readnvr(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// printf("Read NVR %03X %02X %02X %04X:%04X\n",addr,nvraddr,nvrram[nvraddr],cs>>4,pc);
|
||||
|
|
@ -157,6 +162,7 @@ void loadnvr()
|
|||
case ROM_AMI486: f = romfopen("ami486.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_WIN486: f = romfopen("win486.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_PCI486: f = romfopen("hot-433.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_430VX: f = romfopen("hot-433.nvr", "rb"); nvrmask = 127; break;
|
||||
default: return;
|
||||
}
|
||||
if (!f)
|
||||
|
|
@ -169,7 +175,7 @@ void loadnvr()
|
|||
nvrram[0xA]=6;
|
||||
nvrram[0xB]=0;
|
||||
c=1<<((6&0xF)-1);
|
||||
rtctime+=RTCCONST*(float)c;
|
||||
rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT));
|
||||
}
|
||||
void savenvr()
|
||||
{
|
||||
|
|
@ -178,7 +184,7 @@ void savenvr()
|
|||
{
|
||||
case ROM_PC1512: f = romfopen("pc1512.nvr" , "wb"); break;
|
||||
case ROM_PC1640: f = romfopen("pc1640.nvr" , "wb"); break;
|
||||
case ROM_PC200: f = romfopen("pc200.nvr" , "wb"); break;
|
||||
case ROM_PC200: f = romfopen("pc200.nvr" , "wb"); break;
|
||||
case ROM_PC2086: f = romfopen("pc2086.nvr" , "wb"); break;
|
||||
case ROM_PC3086: f = romfopen("pc3086.nvr" , "wb"); break;
|
||||
case ROM_IBMAT: f = romfopen("at.nvr" , "wb"); break;
|
||||
|
|
@ -192,6 +198,7 @@ void savenvr()
|
|||
case ROM_AMI486: f = romfopen("ami486.nvr" , "wb"); break;
|
||||
case ROM_WIN486: f = romfopen("win486.nvr" , "wb"); break;
|
||||
case ROM_PCI486: f = romfopen("hot-433.nvr", "wb"); break;
|
||||
case ROM_430VX: f = romfopen("hot-433.nvr", "wb"); break;
|
||||
default: return;
|
||||
}
|
||||
fwrite(nvrram,128,1,f);
|
||||
|
|
@ -200,5 +207,6 @@ void savenvr()
|
|||
|
||||
void nvr_init()
|
||||
{
|
||||
io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL);
|
||||
io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL, NULL);
|
||||
timer_add(nvr_rtc, &rtctime, TIMER_ALWAYS_ENABLED, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,3 @@
|
|||
void nvr_init();
|
||||
|
||||
extern int nvr_dosave;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include "io.h"
|
||||
#include "olivetti_m24.h"
|
||||
|
||||
uint8_t olivetti_m24_read(uint16_t port)
|
||||
uint8_t olivetti_m24_read(uint16_t port, void *priv)
|
||||
{
|
||||
switch (port)
|
||||
{
|
||||
|
|
@ -16,5 +16,5 @@ uint8_t olivetti_m24_read(uint16_t port)
|
|||
|
||||
void olivetti_m24_init()
|
||||
{
|
||||
io_sethandler(0x0066, 0x0002, olivetti_m24_read, NULL, NULL, NULL, NULL, NULL);
|
||||
io_sethandler(0x0066, 0x0002, olivetti_m24_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
205
src/pc.c
205
src/pc.c
|
|
@ -1,19 +1,36 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "ibm.h"
|
||||
#include "video.h"
|
||||
#include "device.h"
|
||||
|
||||
#include "ali1429.h"
|
||||
#include "amstrad.h"
|
||||
#include "cdrom-ioctl.h"
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "dma.h"
|
||||
#include "mem.h"
|
||||
#include "fdc.h"
|
||||
#include "sound_gus.h"
|
||||
#include "ide.h"
|
||||
#include "keyboard.h"
|
||||
#include "mem.h"
|
||||
#include "model.h"
|
||||
#include "mouse.h"
|
||||
#include "nvr.h"
|
||||
#include "pic.h"
|
||||
#include "pit.h"
|
||||
#include "serial.h"
|
||||
#include "cdrom-ioctl.h"
|
||||
#include "cpu.h"
|
||||
#include "model.h"
|
||||
#include "plat-mouse.h"
|
||||
#include "serial.h"
|
||||
#include "sound.h"
|
||||
#include "sound_cms.h"
|
||||
#include "sound_opl.h"
|
||||
#include "sound_sb.h"
|
||||
#include "timer.h"
|
||||
#include "vid_voodoo.h"
|
||||
#include "video.h"
|
||||
|
||||
int frame = 0;
|
||||
|
||||
int cdrom_enabled;
|
||||
int CPUID;
|
||||
|
|
@ -42,8 +59,8 @@ int mousecapture;
|
|||
FILE *pclogf;
|
||||
void pclog(const char *format, ...)
|
||||
{
|
||||
char buf[256];
|
||||
return;
|
||||
char buf[1024];
|
||||
//return;
|
||||
if (!pclogf)
|
||||
pclogf=fopen("pclog.txt","wt");
|
||||
//return;
|
||||
|
|
@ -79,6 +96,7 @@ int pollmouse_delay = 2;
|
|||
void pollmouse()
|
||||
{
|
||||
int x,y;
|
||||
// return;
|
||||
pollmouse_delay--;
|
||||
if (pollmouse_delay) return;
|
||||
pollmouse_delay = 2;
|
||||
|
|
@ -149,6 +167,7 @@ void pc_reset()
|
|||
{
|
||||
resetx86();
|
||||
cpu_set();
|
||||
//timer_reset();
|
||||
dma_reset();
|
||||
fdc_reset();
|
||||
pic_reset();
|
||||
|
|
@ -157,8 +176,7 @@ void pc_reset()
|
|||
|
||||
setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed);
|
||||
|
||||
adlib_reset();
|
||||
sb_reset();
|
||||
// sb_reset();
|
||||
|
||||
ali1429_reset();
|
||||
et4000w32_reset();
|
||||
|
|
@ -185,31 +203,39 @@ void initpc()
|
|||
cpuspeed2=(AT)?2:1;
|
||||
// cpuspeed2=cpuspeed;
|
||||
atfullspeed=0;
|
||||
|
||||
|
||||
device_init();
|
||||
pclog("Initvideo\n");
|
||||
|
||||
initvideo();
|
||||
mem_init();
|
||||
loadbios();
|
||||
mem_load_video_bios();
|
||||
|
||||
loaddisc(0,discfns[0]);
|
||||
loaddisc(1,discfns[1]);
|
||||
|
||||
timer_reset();
|
||||
sound_reset();
|
||||
fdc_init();
|
||||
|
||||
//loadfont();
|
||||
loadnvr();
|
||||
resetvideo();
|
||||
initsound();
|
||||
initpsg();
|
||||
sound_init();
|
||||
inithdc();
|
||||
initega();
|
||||
initgus();
|
||||
resetide();
|
||||
ioctl_open(cdrom_drive);
|
||||
model_init();
|
||||
video_init();
|
||||
adlib_init();
|
||||
sb_init();
|
||||
gus_init();
|
||||
|
||||
speaker_init();
|
||||
sound_card_init(sound_card_current);
|
||||
if (GUS)
|
||||
device_add(&gus_device);
|
||||
if (GAMEBLASTER)
|
||||
device_add(&cms_device);
|
||||
|
||||
pc_reset();
|
||||
|
||||
pit_reset();
|
||||
|
|
@ -222,7 +248,7 @@ void initpc()
|
|||
// CPUID=(is486 && (cpuspeed==7 || cpuspeed>=9));
|
||||
// pclog("Init - CPUID %i %i\n",CPUID,cpuspeed);
|
||||
shadowbios=0;
|
||||
|
||||
voodoo_init();
|
||||
}
|
||||
|
||||
void resetpc()
|
||||
|
|
@ -236,13 +262,22 @@ void resetpc()
|
|||
|
||||
void resetpchard()
|
||||
{
|
||||
device_close_all();
|
||||
device_init();
|
||||
|
||||
timer_reset();
|
||||
sound_reset();
|
||||
mem_resize();
|
||||
fdc_init();
|
||||
model_init();
|
||||
pclog("Video_init\n");
|
||||
video_init();
|
||||
adlib_init();
|
||||
sb_init();
|
||||
gus_init();
|
||||
speaker_init();
|
||||
sound_card_init(sound_card_current);
|
||||
if (GUS)
|
||||
device_add(&gus_device);
|
||||
if (GAMEBLASTER)
|
||||
device_add(&cms_device);
|
||||
|
||||
pc_reset();
|
||||
|
||||
|
|
@ -278,14 +313,14 @@ int sreadlnum,swritelnum,segareads,segawrites, scycles_lost;
|
|||
int serial_fifo_read, serial_fifo_write;
|
||||
|
||||
int emu_fps = 0;
|
||||
|
||||
extern int totaldiff;
|
||||
void runpc()
|
||||
{
|
||||
char s[200];
|
||||
int done=0;
|
||||
clockrate = models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed;
|
||||
if (is386) exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
|
||||
else if (AT) exec286(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
|
||||
else if (AT) exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
|
||||
else execx86(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
|
||||
keyboard_poll_host();
|
||||
keyboard_process();
|
||||
|
|
@ -320,10 +355,12 @@ void runpc()
|
|||
if (win_title_update)
|
||||
{
|
||||
win_title_update=0;
|
||||
sprintf(s, "PCem v0.7 - %s - %s - %s - %i%% %i %04X %i", model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : "Press CTRL-END to release mouse", fps, et4000w32p_getclock(), ECX, ins);
|
||||
sprintf(s, "PCem v0.7 - %s - %s - %s - %i%% - %i", model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : "Press CTRL-END to release mouse", fps, totaldiff);
|
||||
totaldiff = 0;
|
||||
set_window_title(s);
|
||||
}
|
||||
done++;
|
||||
frame++;
|
||||
/* if ((at70hz && VGA)!=oldat70hz)
|
||||
{
|
||||
oldat70hz=(at70hz && VGA);
|
||||
|
|
@ -369,7 +406,6 @@ void closepc()
|
|||
// ioctl_close();
|
||||
dumpegaregs();
|
||||
dumppic();
|
||||
dumpgus();
|
||||
// output=7;
|
||||
// setpitclock(clocks[0][0][0]);
|
||||
// while (1) runpc();
|
||||
|
|
@ -377,6 +413,7 @@ void closepc()
|
|||
savedisc(1);
|
||||
dumpregs();
|
||||
closevideo();
|
||||
device_close_all();
|
||||
}
|
||||
|
||||
/*int main()
|
||||
|
|
@ -398,94 +435,86 @@ void loadconfig()
|
|||
{
|
||||
char s[512];
|
||||
char *p;
|
||||
append_filename(s,pcempath,"pcem.cfg",511);
|
||||
append_filename(s, pcempath, "pcem.cfg", 511);
|
||||
set_config_file(s);
|
||||
ADLIB=get_config_int(NULL,"adlib",1);
|
||||
GAMEBLASTER=get_config_int(NULL,"gameblaster",0);
|
||||
FASTDISC=get_config_int(NULL,"fast_disc",1);
|
||||
GAMEBLASTER = get_config_int(NULL, "gameblaster", 0);
|
||||
GUS = get_config_int(NULL, "gus", 0);
|
||||
|
||||
model = get_config_int(NULL, "model", 14);
|
||||
pclog("Model %i\n", model);
|
||||
|
||||
romset = model_getromset();
|
||||
cpu_manufacturer = get_config_int(NULL, "cpu_manufacturer", 0);
|
||||
cpu = get_config_int(NULL, "cpu", 0);
|
||||
|
||||
gfxcard=get_config_int(NULL,"gfxcard",0);
|
||||
gfxcard = get_config_int(NULL, "gfxcard", 0);
|
||||
video_speed = get_config_int(NULL, "video_speed", 3);
|
||||
sbtype=get_config_int(NULL,"sndcard",SB2);
|
||||
pclog("Model1 %i\n", model);
|
||||
p=(char *)get_config_string(NULL,"disc_a","");
|
||||
if (p) strcpy(discfns[0],p);
|
||||
else strcpy(discfns[0],"");
|
||||
pclog("Model2 %i\n", model);
|
||||
p=(char *)get_config_string(NULL,"disc_b","");
|
||||
if (p) strcpy(discfns[1],p);
|
||||
else strcpy(discfns[1],"");
|
||||
pclog("Model3 %i\n", model);
|
||||
mem_size=get_config_int(NULL,"mem_size",4);
|
||||
cdrom_drive=get_config_int(NULL,"cdrom_drive",0);
|
||||
cdrom_enabled=get_config_int(NULL,"cdrom_enabled",0);
|
||||
|
||||
slowega=get_config_int(NULL,"slow_video",1);
|
||||
cache=get_config_int(NULL,"cache",3);
|
||||
cga_comp=get_config_int(NULL,"cga_composite",0);
|
||||
|
||||
kb_win=get_config_int(NULL,"kb_win",0);
|
||||
vid_resize=get_config_int(NULL,"vid_resize",0);
|
||||
// cpuspeed=2;
|
||||
sound_card_current = get_config_int(NULL, "sndcard", SB2);
|
||||
|
||||
hdc[0].spt=get_config_int(NULL,"hdc_sectors",0);
|
||||
hdc[0].hpc=get_config_int(NULL,"hdc_heads",0);
|
||||
hdc[0].tracks=get_config_int(NULL,"hdc_cylinders",0);
|
||||
p = (char *)get_config_string(NULL, "disc_a", "");
|
||||
if (p) strcpy(discfns[0], p);
|
||||
else strcpy(discfns[0], "");
|
||||
|
||||
p = (char *)get_config_string(NULL, "disc_b", "");
|
||||
if (p) strcpy(discfns[1], p);
|
||||
else strcpy(discfns[1], "");
|
||||
|
||||
mem_size = get_config_int(NULL, "mem_size", 4);
|
||||
cdrom_drive = get_config_int(NULL, "cdrom_drive", 0);
|
||||
cdrom_enabled = get_config_int(NULL, "cdrom_enabled", 0);
|
||||
|
||||
slowega = get_config_int(NULL, "slow_video", 1);
|
||||
cache = get_config_int(NULL, "cache", 3);
|
||||
cga_comp = get_config_int(NULL, "cga_composite", 0);
|
||||
|
||||
kb_win = get_config_int(NULL, "kb_win", 0);
|
||||
vid_resize = get_config_int(NULL, "vid_resize", 0);
|
||||
|
||||
hdc[0].spt = get_config_int(NULL, "hdc_sectors", 0);
|
||||
hdc[0].hpc = get_config_int(NULL, "hdc_heads", 0);
|
||||
hdc[0].tracks = get_config_int(NULL, "hdc_cylinders", 0);
|
||||
p = (char *)get_config_string(NULL, "hdc_fn", "");
|
||||
if (p) strcpy(ide_fn[0], p);
|
||||
else strcpy(ide_fn[0], "");
|
||||
hdc[1].spt=get_config_int(NULL,"hdd_sectors",0);
|
||||
hdc[1].hpc=get_config_int(NULL,"hdd_heads",0);
|
||||
hdc[1].tracks=get_config_int(NULL,"hdd_cylinders",0);
|
||||
hdc[1].spt = get_config_int(NULL, "hdd_sectors", 0);
|
||||
hdc[1].hpc = get_config_int(NULL, "hdd_heads", 0);
|
||||
hdc[1].tracks = get_config_int(NULL, "hdd_cylinders", 0);
|
||||
p = (char *)get_config_string(NULL, "hdd_fn", "");
|
||||
if (p) strcpy(ide_fn[1], p);
|
||||
else strcpy(ide_fn[1], "");
|
||||
pclog("Model4 %i\n", model);
|
||||
}
|
||||
|
||||
void saveconfig()
|
||||
{
|
||||
pclog("saveconfig\n");
|
||||
config_new();
|
||||
pclog("config_new\n");
|
||||
set_config_int(NULL,"adlib",ADLIB);
|
||||
pclog("sci 1\n");
|
||||
set_config_int(NULL,"gameblaster",GAMEBLASTER);
|
||||
set_config_int(NULL,"fast_disc",FASTDISC);
|
||||
set_config_int(NULL, "gameblaster", GAMEBLASTER);
|
||||
set_config_int(NULL, "gus", GUS);
|
||||
|
||||
set_config_int(NULL, "model", model);
|
||||
set_config_int(NULL, "cpu_manufacturer", cpu_manufacturer);
|
||||
set_config_int(NULL, "cpu", cpu);
|
||||
|
||||
set_config_int(NULL,"gfxcard",gfxcard);
|
||||
set_config_int(NULL,"video_speed", video_speed);
|
||||
set_config_int(NULL,"sndcard",sbtype);
|
||||
set_config_int(NULL,"cpu_speed",cpuspeed);
|
||||
set_config_int(NULL,"has_fpu",hasfpu);
|
||||
set_config_int(NULL,"slow_video",slowega);
|
||||
set_config_int(NULL,"cache",cache);
|
||||
set_config_int(NULL,"cga_composite",cga_comp);
|
||||
set_config_string(NULL,"disc_a",discfns[0]);
|
||||
set_config_string(NULL,"disc_b",discfns[1]);
|
||||
set_config_int(NULL,"mem_size",mem_size);
|
||||
set_config_int(NULL,"cdrom_drive",cdrom_drive);
|
||||
set_config_int(NULL,"cdrom_enabled",cdrom_enabled);
|
||||
set_config_int(NULL,"kb_win",kb_win);
|
||||
set_config_int(NULL,"vid_resize",vid_resize);
|
||||
set_config_int(NULL, "gfxcard", gfxcard);
|
||||
set_config_int(NULL, "video_speed", video_speed);
|
||||
set_config_int(NULL, "sndcard", sound_card_current);
|
||||
set_config_int(NULL, "cpu_speed", cpuspeed);
|
||||
set_config_int(NULL, "has_fpu", hasfpu);
|
||||
set_config_int(NULL, "slow_video", slowega);
|
||||
set_config_int(NULL, "cache", cache);
|
||||
set_config_int(NULL, "cga_composite", cga_comp);
|
||||
set_config_string(NULL, "disc_a", discfns[0]);
|
||||
set_config_string(NULL, "disc_b", discfns[1]);
|
||||
set_config_int(NULL, "mem_size", mem_size);
|
||||
set_config_int(NULL, "cdrom_drive", cdrom_drive);
|
||||
set_config_int(NULL, "cdrom_enabled", cdrom_enabled);
|
||||
set_config_int(NULL, "kb_win", kb_win);
|
||||
set_config_int(NULL, "vid_resize", vid_resize);
|
||||
|
||||
set_config_int(NULL,"hdc_sectors",hdc[0].spt);
|
||||
set_config_int(NULL,"hdc_heads",hdc[0].hpc);
|
||||
set_config_int(NULL,"hdc_cylinders",hdc[0].tracks);
|
||||
set_config_int(NULL, "hdc_sectors", hdc[0].spt);
|
||||
set_config_int(NULL, "hdc_heads", hdc[0].hpc);
|
||||
set_config_int(NULL, "hdc_cylinders", hdc[0].tracks);
|
||||
set_config_string(NULL, "hdc_fn", ide_fn[0]);
|
||||
set_config_int(NULL,"hdd_sectors",hdc[1].spt);
|
||||
set_config_int(NULL,"hdd_heads",hdc[1].hpc);
|
||||
set_config_int(NULL,"hdd_cylinders",hdc[1].tracks);
|
||||
set_config_int(NULL, "hdd_sectors", hdc[1].spt);
|
||||
set_config_int(NULL, "hdd_heads", hdc[1].hpc);
|
||||
set_config_int(NULL, "hdd_cylinders", hdc[1].tracks);
|
||||
set_config_string(NULL, "hdd_fn", ide_fn[1]);
|
||||
pclog("saveconfig done\n");
|
||||
}
|
||||
|
|
|
|||
29
src/pci.c
29
src/pci.c
|
|
@ -4,13 +4,12 @@
|
|||
|
||||
#include "pci.h"
|
||||
|
||||
void (*pci_card_write[32])(int func, int addr, uint8_t val);
|
||||
uint8_t (*pci_card_read[32])(int func, int addr);
|
||||
void (*pci_card_write[32])(int func, int addr, uint8_t val, void *priv);
|
||||
uint8_t (*pci_card_read[32])(int func, int addr, void *priv);
|
||||
void *pci_priv[32];
|
||||
static int pci_index, pci_func, pci_card, pci_bus, pci_enable;
|
||||
static uint8_t card_16[256];
|
||||
static uint8_t card_18[256];
|
||||
|
||||
void pci_write(uint16_t port, uint8_t val)
|
||||
void pci_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
switch (port)
|
||||
{
|
||||
|
|
@ -32,16 +31,16 @@ void pci_write(uint16_t port, uint8_t val)
|
|||
if (!pci_enable)
|
||||
return;
|
||||
|
||||
pclog("PCI write bus %i card %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_index | (port & 3), val, CS, pc);
|
||||
// pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), val, CS, pc);
|
||||
|
||||
if (!pci_bus && pci_card_write[pci_card])
|
||||
pci_card_write[pci_card](pci_func, pci_index | (port & 3), val);
|
||||
pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t pci_read(uint16_t port)
|
||||
uint8_t pci_read(uint16_t port, void *priv)
|
||||
{
|
||||
switch (port)
|
||||
{
|
||||
|
|
@ -58,10 +57,10 @@ uint8_t pci_read(uint16_t port)
|
|||
if (!pci_enable)
|
||||
return 0xff;
|
||||
|
||||
pclog("PCI read bus %i card %i index %02X\n", pci_bus, pci_card, pci_index | (port & 3));
|
||||
// pclog("PCI read bus %i card %i func %i index %02X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3));
|
||||
|
||||
if (!pci_bus && pci_card_read[pci_card])
|
||||
return pci_card_read[pci_card](pci_func, pci_index | (port & 3));
|
||||
return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]);
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
|
@ -71,19 +70,20 @@ void pci_init()
|
|||
{
|
||||
int c;
|
||||
|
||||
io_sethandler(0x0cf8, 0x0008, pci_read, NULL, NULL, pci_write, NULL, NULL);
|
||||
io_sethandler(0x0cf8, 0x0008, pci_read, NULL, NULL, pci_write, NULL, NULL, NULL);
|
||||
|
||||
for (c = 0; c < 32; c++)
|
||||
pci_card_read[c] = pci_card_write[c] = NULL;
|
||||
pci_card_read[c] = pci_card_write[c] = pci_priv[c] = NULL;
|
||||
}
|
||||
|
||||
void pci_add_specific(int card, uint8_t (*read)(int func, int addr), void (*write)(int func, int addr, uint8_t val))
|
||||
void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv)
|
||||
{
|
||||
pci_card_read[card] = read;
|
||||
pci_card_write[card] = write;
|
||||
pci_priv[card] = priv;
|
||||
}
|
||||
|
||||
void pci_add(uint8_t (*read)(int func, int addr), void (*write)(int func, int addr, uint8_t val))
|
||||
void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv)
|
||||
{
|
||||
int c;
|
||||
|
||||
|
|
@ -93,6 +93,7 @@ void pci_add(uint8_t (*read)(int func, int addr), void (*write)(int func, int ad
|
|||
{
|
||||
pci_card_read[c] = read;
|
||||
pci_card_write[c] = write;
|
||||
pci_priv[c] = priv;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
void pci_init();
|
||||
void pci_add_specific(int card, uint8_t (*read)(int func, int addr), void (*write)(int func, int addr, uint8_t val));
|
||||
void pci_add(uint8_t (*read)(int func, int addr), void (*write)(int func, int addr, uint8_t val));
|
||||
void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
|
||||
void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
|
||||
|
|
|
|||
33
src/pic.c
33
src/pic.c
|
|
@ -1,14 +1,16 @@
|
|||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "pic.h"
|
||||
|
||||
int output;
|
||||
int intclear;
|
||||
int keywaiting=0;
|
||||
int pit0;
|
||||
int pic_intpending;
|
||||
|
||||
void pic_updatepending()
|
||||
{
|
||||
pic_intpending = (((pic.pend&~pic.mask)&~pic.mask2) || ((pic2.pend&~pic2.mask)&~pic2.mask2));
|
||||
// pclog("pic_intpending = %i %02X %02X %02X\n", pic_intpending, pic.pend, pic.mask, pic.mask2);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -27,7 +29,7 @@ void pic_reset()
|
|||
pic_intpending = 0;
|
||||
}
|
||||
|
||||
void pic_write(uint16_t addr, uint8_t val)
|
||||
void pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int c;
|
||||
// pclog("Write PIC %04X %02X %04X(%06X):%04X\n",addr,val,CS,cs,pc);
|
||||
|
|
@ -87,7 +89,6 @@ void pic_write(uint16_t addr, uint8_t val)
|
|||
pic.ins&=~(1<<c);
|
||||
pic.mask2&=~(1<<c);
|
||||
// pic.pend&=~(1<<c);
|
||||
if (c==0) pit0=1;
|
||||
if (c==1 && keywaiting)
|
||||
{
|
||||
intclear&=~1;
|
||||
|
|
@ -109,20 +110,20 @@ void pic_write(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t pic_read(uint16_t addr)
|
||||
uint8_t pic_read(uint16_t addr, void *priv)
|
||||
{
|
||||
if (addr&1) { /*pclog("Read PIC mask %02X\n",pic.mask);*/ return pic.mask; }
|
||||
if (pic.read) { /*pclog("Read PIC ins %02X\n",pic.ins);*/ return pic.ins; }
|
||||
if (pic.read) { /*pclog("Read PIC ins %02X\n",pic.ins);*/ return pic.ins | (pic2.ins ? 4 : 0); }
|
||||
// pclog("Read PIC pend %02X %08X\n",pic.pend,EDX);
|
||||
return pic.pend;
|
||||
}
|
||||
|
||||
void pic_init()
|
||||
{
|
||||
io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL);
|
||||
io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void pic2_write(uint16_t addr, uint8_t val)
|
||||
void pic2_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int c;
|
||||
// pclog("Write PIC2 %04X %02X %04X:%04X %i\n",addr,val,CS,pc,ins);
|
||||
|
|
@ -137,6 +138,7 @@ void pic2_write(uint16_t addr, uint8_t val)
|
|||
break;
|
||||
case 1: /*ICW2*/
|
||||
pic2.vector=val&0xF8;
|
||||
// pclog("PIC2 vector %02X\n", val & 0xf8);
|
||||
if (pic2.icw1&2) pic2.icw=3;
|
||||
else pic2.icw=2;
|
||||
break;
|
||||
|
|
@ -188,17 +190,17 @@ void pic2_write(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t pic2_read(uint16_t addr)
|
||||
uint8_t pic2_read(uint16_t addr, void *priv)
|
||||
{
|
||||
if (addr&1) { /*pclog("Read PIC2 mask %02X %04X:%08X\n",pic2.mask,CS,pc); */return pic2.mask; }
|
||||
if (pic2.read) { /*pclog("Read PIC2 ins %02X %04X:%08X\n",pic2.ins,CS,pc); */return pic2.ins; }
|
||||
// pclog("Read PIC2 pend %02X %04X:%08X\n",pic2.pend,CS,pc);
|
||||
/*pclog("Read PIC2 pend %02X %04X:%08X\n",pic2.pend,CS,pc);*/
|
||||
return pic2.pend;
|
||||
}
|
||||
|
||||
void pic2_init()
|
||||
{
|
||||
io_sethandler(0x00a0, 0x0002, pic2_read, NULL, NULL, pic2_write, NULL, NULL);
|
||||
io_sethandler(0x00a0, 0x0002, pic2_read, NULL, NULL, pic2_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -213,6 +215,7 @@ int pic_current[16];
|
|||
|
||||
void picint(uint16_t num)
|
||||
{
|
||||
// pclog("picint : %04X\n", num);
|
||||
// if (num == 0x10) pclog("PICINT 10\n");
|
||||
if (num>0xFF)
|
||||
{
|
||||
|
|
@ -222,6 +225,7 @@ void picint(uint16_t num)
|
|||
{
|
||||
pic.pend|=num;
|
||||
}
|
||||
// pclog("picint : PEND now %02X %02X\n", pic.pend, pic2.pend);
|
||||
pic_updatepending();
|
||||
}
|
||||
|
||||
|
|
@ -248,7 +252,7 @@ void picintc(uint16_t num)
|
|||
{
|
||||
int c = 0;
|
||||
while (!(num & (1 << c))) c++;
|
||||
// pclog("INTC %04X %i\n", num, c);
|
||||
//pclog("INTC %04X %i\n", num, c);
|
||||
pic_current[c]=0;
|
||||
if (num>0xFF) pic2.pend&=~(num>>8);
|
||||
else
|
||||
|
|
@ -270,6 +274,7 @@ uint8_t picinterrupt()
|
|||
pic.mask2|=(1<<c);
|
||||
|
||||
pic_updatepending();
|
||||
// pclog("picinterrupt : Taking PIC1 int %i\n", c);
|
||||
// if (!c) pclog("Taking timer int\n");
|
||||
// if (c==5) printf("GUS IRQ!\n");
|
||||
// if (c==1) printf("Keyboard int!\n");
|
||||
|
|
@ -277,6 +282,8 @@ uint8_t picinterrupt()
|
|||
return c+pic.vector;
|
||||
}
|
||||
}
|
||||
/* if (pic.mask2 & 4)
|
||||
return 0xff;*/
|
||||
temp=pic2.pend&~pic2.mask;
|
||||
for (c=0;c<8;c++)
|
||||
{
|
||||
|
|
@ -286,6 +293,7 @@ uint8_t picinterrupt()
|
|||
pic2.ins|=(1<<c);
|
||||
pic2.mask2|=(1<<c);
|
||||
pic_updatepending();
|
||||
//pclog("Taking PIC2 int %i\n", c);
|
||||
// if (c==(14-8)) pclog("Taking IRQ 14 %02X\n",c+pic2.vector);
|
||||
// printf("Taking high IRQ! %i\n",c);
|
||||
// if (c==1) printf("Keyboard int!\n");
|
||||
|
|
@ -298,10 +306,9 @@ uint8_t picinterrupt()
|
|||
|
||||
void picclear(int num)
|
||||
{
|
||||
// printf("Pic clear %02X\n",num);
|
||||
// pclog("Pic clear %02X\n",num);
|
||||
pic.pend&=~num;
|
||||
pic.ins&=~num;
|
||||
if (num==1) pit0=1;
|
||||
pic_updatepending();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
void pic_init();
|
||||
void pic2_init();
|
||||
void pic_reset();
|
||||
|
||||
void picint(uint16_t num);
|
||||
void picintlevel(uint16_t num);
|
||||
void picintc(uint16_t num);
|
||||
uint8_t picinterrupt();
|
||||
void picclear(int num);
|
||||
|
|
|
|||
42
src/pit.c
42
src/pit.c
|
|
@ -5,9 +5,15 @@
|
|||
|
||||
#include <string.h>
|
||||
#include "ibm.h"
|
||||
#include "pit.h"
|
||||
#include "video.h"
|
||||
|
||||
#include "cpu.h"
|
||||
#include "dma.h"
|
||||
#include "io.h"
|
||||
#include "pic.h"
|
||||
#include "pit.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
|
||||
/*B0 to 40, two writes to 43, then two reads - value does not change!*/
|
||||
/*B4 to 40, two writes to 43, then two reads - value _does_ change!*/
|
||||
//Tyrian writes 4300 or 17512
|
||||
|
|
@ -21,31 +27,25 @@ float isa_timing, bus_timing;
|
|||
int firsttime=1;
|
||||
void setpitclock(float clock)
|
||||
{
|
||||
float temp;
|
||||
// printf("PIT clock %f\n",clock);
|
||||
cpuclock=clock;
|
||||
PITCONST=clock/1193182.0;
|
||||
SPKCONST=clock/48000.0;
|
||||
CGACONST=(clock/(19687500.0/11.0));
|
||||
MDACONST=(clock/1813000.0);
|
||||
VGACONST1=(clock/25175000.0);
|
||||
VGACONST2=(clock/28322000.0);
|
||||
setsbclock(clock);
|
||||
SOUNDCONST=clock/200.0;
|
||||
CASCONST=PITCONST*1192;
|
||||
isa_timing = clock/8000000.0;
|
||||
bus_timing = clock/(double)cpu_busspeed;
|
||||
video_updatetiming();
|
||||
// pclog("egacycles %i egacycles2 %i temp %f clock %f\n",egacycles,egacycles2,temp,clock);
|
||||
GUSCONST=(clock/3125.0)/4.0;
|
||||
GUSCONST2=(clock/3125.0)/4.0; //Timer 2 at different rate to 1?
|
||||
video_recalctimings();
|
||||
RTCCONST=clock/32768.0;
|
||||
TIMER_USEC = (int)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT));
|
||||
device_speed_changed();
|
||||
}
|
||||
|
||||
//#define PITCONST (8000000.0/1193000.0)
|
||||
//#define PITCONST (cpuclock/1193000.0)
|
||||
int pit0;
|
||||
void pit_reset()
|
||||
{
|
||||
memset(&pit,0,sizeof(PIT));
|
||||
|
|
@ -69,12 +69,10 @@ float pit_timer0_freq()
|
|||
return 1193182.0f/(float)pit.l[0];
|
||||
}
|
||||
extern int ins;
|
||||
void pit_write(uint16_t addr, uint8_t val)
|
||||
void pit_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int t;
|
||||
uint8_t oldctrl=pit.ctrl;
|
||||
cycles -= (int)PITCONST;
|
||||
pit0=1;
|
||||
// printf("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,pc,ins);
|
||||
switch (addr&3)
|
||||
{
|
||||
|
|
@ -135,13 +133,15 @@ void pit_write(uint16_t addr, uint8_t val)
|
|||
pit.l[t]=val;
|
||||
pit.thit[t]=0;
|
||||
pit.c[t]=pit.l[t]*PITCONST;
|
||||
picintc(1);
|
||||
if (!t)
|
||||
picintc(1);
|
||||
break;
|
||||
case 2:
|
||||
pit.l[t]=(val<<8);
|
||||
pit.thit[t]=0;
|
||||
pit.c[t]=pit.l[t]*PITCONST;
|
||||
picintc(1);
|
||||
if (!t)
|
||||
picintc(1);
|
||||
break;
|
||||
case 0:
|
||||
pit.l[t]&=0xFF;
|
||||
|
|
@ -150,7 +150,8 @@ void pit_write(uint16_t addr, uint8_t val)
|
|||
// pclog("%04X %f\n",pit.l[t],pit.c[t]);
|
||||
pit.thit[t]=0;
|
||||
pit.wm[t]=3;
|
||||
picintc(1);
|
||||
if (!t)
|
||||
picintc(1);
|
||||
break;
|
||||
case 3:
|
||||
pit.l[t]&=0xFF00;
|
||||
|
|
@ -190,7 +191,7 @@ void pit_write(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t pit_read(uint16_t addr)
|
||||
uint8_t pit_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
cycles -= (int)PITCONST;
|
||||
|
|
@ -250,8 +251,8 @@ void pit_poll()
|
|||
else pit.c[0]+=((float)(0x10000*PITCONST));
|
||||
}
|
||||
// pit.c[0]+=(pit.l[0]*PITCONST);
|
||||
// printf("PIT over! %f %i\n",pit.c[0],pit.m[0]);
|
||||
if (!pit.thit[0] && (pit.l[0]>0x14))
|
||||
// if (output) printf("PIT over! %f %i\n",pit.c[0],pit.m[0]);
|
||||
if (!pit.thit[0])// && (pit.l[0]>0x14))
|
||||
{
|
||||
// printf("PIT int!\n");
|
||||
/// printf("%05X %05X %02X\n",pit.c[0],pit.l[0],pit.ctrls[0]);
|
||||
|
|
@ -259,7 +260,6 @@ void pit_poll()
|
|||
}
|
||||
if (!pit.m[0] || pit.m[0]==4) pit.thit[0]=1;
|
||||
// if ((pit.ctrls[0]&0xE)==2) pit.thit[0]=1;
|
||||
pit0=0;
|
||||
pitcount++;
|
||||
}
|
||||
if (pit.c[1]<1)
|
||||
|
|
@ -301,5 +301,5 @@ void pit_poll()
|
|||
|
||||
void pit_init()
|
||||
{
|
||||
io_sethandler(0x0040, 0x0004, pit_read, NULL, NULL, pit_write, NULL, NULL);
|
||||
io_sethandler(0x0040, 0x0004, pit_read, NULL, NULL, pit_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#define IDC_CHECK2 1011
|
||||
#define IDC_CHECK3 1012
|
||||
#define IDC_CHECK4 1013
|
||||
#define IDC_CHECKGUS 1014
|
||||
#define IDC_STATIC 1020
|
||||
#define IDC_EDIT1 1030
|
||||
#define IDC_EDIT2 1031
|
||||
|
|
|
|||
32
src/serial.c
32
src/serial.c
|
|
@ -1,7 +1,9 @@
|
|||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mouse.h"
|
||||
#include "pic.h"
|
||||
#include "serial.h"
|
||||
#include "timer.h"
|
||||
|
||||
SERIAL serial,serial2;
|
||||
|
||||
|
|
@ -48,7 +50,7 @@ void sendserial(uint8_t dat)
|
|||
serial.iir=4;
|
||||
}
|
||||
|
||||
void serial_write(uint16_t addr, uint8_t val)
|
||||
void serial_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// printf("Write serial %03X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
switch (addr&7)
|
||||
|
|
@ -89,7 +91,7 @@ void serial_write(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t serial_read(uint16_t addr)
|
||||
uint8_t serial_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// printf("Read serial %03X %04X(%08X):%04X %i %i ", addr, CS, cs, pc, mousedelay, ins);
|
||||
|
|
@ -104,7 +106,7 @@ uint8_t serial_read(uint16_t addr)
|
|||
if (serial_fifo_read != serial_fifo_write)
|
||||
{
|
||||
mousepos = 0;
|
||||
mousedelay = 1000;
|
||||
mousedelay = 5000 * (1 << TIMER_SHIFT);
|
||||
// pclog("Next FIFO\n");
|
||||
}
|
||||
break;
|
||||
|
|
@ -122,7 +124,7 @@ uint8_t serial_read(uint16_t addr)
|
|||
return temp;
|
||||
}
|
||||
|
||||
void serial2_write(uint16_t addr, uint8_t val)
|
||||
void serial2_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// printf("Write serial2 %03X %02X %04X:%04X\n",addr,val,cs>>4,pc);
|
||||
switch (addr&7)
|
||||
|
|
@ -156,7 +158,7 @@ void serial2_write(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t serial2_read(uint16_t addr)
|
||||
uint8_t serial2_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// printf("Read serial2 %03X %04X:%04X\n",addr,cs>>4,pc);
|
||||
|
|
@ -186,25 +188,25 @@ uint8_t serial2_read(uint16_t addr)
|
|||
/*Tandy might need COM1 at 2f8*/
|
||||
void serial1_init(uint16_t addr)
|
||||
{
|
||||
io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL);
|
||||
io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, NULL);
|
||||
serial_rcr = NULL;
|
||||
}
|
||||
void serial1_remove()
|
||||
{
|
||||
io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL);
|
||||
io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL);
|
||||
io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL);
|
||||
io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL);
|
||||
io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void serial2_init(uint16_t addr)
|
||||
{
|
||||
io_sethandler(addr, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL);
|
||||
io_sethandler(addr, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL, NULL);
|
||||
}
|
||||
void serial2_remove()
|
||||
{
|
||||
io_removehandler(0x2e8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL);
|
||||
io_removehandler(0x2f8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL);
|
||||
io_removehandler(0x3e8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL);
|
||||
io_removehandler(0x3f8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL);
|
||||
io_removehandler(0x2e8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x2f8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x3e8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x3f8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
276
src/sound.c
276
src/sound.c
|
|
@ -1,180 +1,146 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
|
||||
#include "filters.h"
|
||||
|
||||
int soundon = 1;
|
||||
int16_t *adbuffer,*adbuffer2;
|
||||
int16_t *psgbuffer;
|
||||
uint16_t *cmsbuffer;
|
||||
int16_t *spkbuffer;
|
||||
int16_t *outbuffer;
|
||||
uint16_t *gusbuffer;
|
||||
#include "sound_opl.h"
|
||||
|
||||
void initsound()
|
||||
#include "sound.h"
|
||||
#include "sound_adlib.h"
|
||||
#include "sound_adlibgold.h"
|
||||
#include "sound_pas16.h"
|
||||
#include "sound_sb.h"
|
||||
#include "sound_sb_dsp.h"
|
||||
#include "sound_wss.h"
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
int sound_card_current = 0;
|
||||
static int sound_card_last = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[32];
|
||||
device_t *device;
|
||||
} SOUND_CARD;
|
||||
|
||||
static SOUND_CARD sound_cards[] =
|
||||
{
|
||||
{"None", NULL},
|
||||
{"Adlib", &adlib_device},
|
||||
{"Sound Blaster 1.0", &sb_1_device},
|
||||
{"Sound Blaster 1.5", &sb_15_device},
|
||||
{"Sound Blaster 2.0", &sb_2_device},
|
||||
{"Sound Blaster Pro v1", &sb_pro_v1_device},
|
||||
{"Sound Blaster Pro v2", &sb_pro_v1_device},
|
||||
{"Sound Blaster 16", &sb_16_device},
|
||||
{"Adlib Gold", &adgold_device},
|
||||
{"Windows Sound System", &wss_device},
|
||||
{"Pro Audio Spectrum 16", &pas16_device},
|
||||
{"", NULL}
|
||||
};
|
||||
|
||||
char *sound_card_getname(int card)
|
||||
{
|
||||
return sound_cards[card].name;
|
||||
}
|
||||
|
||||
void sound_card_init()
|
||||
{
|
||||
if (sound_cards[sound_card_current].device)
|
||||
device_add(sound_cards[sound_card_current].device);
|
||||
sound_card_last = sound_card_current;
|
||||
}
|
||||
|
||||
static struct
|
||||
{
|
||||
void (*poll)(void *p);
|
||||
void (*get_buffer)(int16_t *buffer, int len, void *p);
|
||||
void *priv;
|
||||
} sound_handlers[8];
|
||||
|
||||
static int sound_handlers_num;
|
||||
|
||||
static int sound_poll_time = 0, sound_get_buffer_time = 0;
|
||||
|
||||
int soundon = 1;
|
||||
|
||||
|
||||
static int16_t cd_buffer[SOUNDBUFLEN * 2];
|
||||
|
||||
void sound_cd_poll(void *p)
|
||||
{
|
||||
}
|
||||
|
||||
void sound_cd_get_buffer(int16_t *buffer, int len, void *p)
|
||||
{
|
||||
int pos, c;
|
||||
ioctl_audio_callback(cd_buffer, (len * 2 * 441) / 480);
|
||||
pos = 0;
|
||||
|
||||
for (c = 0; c < len * 2; c+=2)
|
||||
{
|
||||
buffer[c] += cd_buffer[((pos >> 16) << 1)] / 2;
|
||||
buffer[c + 1] += cd_buffer[((pos >> 16) << 1) + 1] / 2;
|
||||
pos += 60211; //(44100 * 65536) / 48000;
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t *outbuffer;
|
||||
|
||||
void sound_init()
|
||||
{
|
||||
initalmain(0,NULL);
|
||||
inital();
|
||||
// install_sound(DIGI_AUTODETECT,MIDI_NONE,0);
|
||||
// as=play_audio_stream(SOUNDBUFLEN,16,1,48000,255,128);
|
||||
adbuffer=malloc((SOUNDBUFLEN)*2);
|
||||
adbuffer2=malloc((SOUNDBUFLEN)*2);
|
||||
psgbuffer=malloc((SOUNDBUFLEN)*2);
|
||||
cmsbuffer=malloc((SOUNDBUFLEN)*2*2);
|
||||
gusbuffer=malloc((SOUNDBUFLEN)*2*2);
|
||||
spkbuffer=malloc(((SOUNDBUFLEN)*2)+32);
|
||||
outbuffer=malloc((SOUNDBUFLEN)*2*2);
|
||||
|
||||
outbuffer = malloc(SOUNDBUFLEN * 2 * sizeof(int16_t));
|
||||
|
||||
sound_add_handler(sound_cd_poll, sound_cd_get_buffer, NULL);
|
||||
}
|
||||
|
||||
int adpoll=0;
|
||||
void pollad()
|
||||
void sound_add_handler(void (*poll)(void *p), void (*get_buffer)(int16_t *buffer, int len, void *p), void *p)
|
||||
{
|
||||
/* if (adpoll>=20) return;
|
||||
getadlibl(adbuffer+(adpoll*(48000/200)),48000/200);
|
||||
getadlibr(adbuffer2+(adpoll*(48000/200)),48000/200);
|
||||
adpoll++;*/
|
||||
// printf("ADPOLL %i\n",adpoll);
|
||||
sound_handlers[sound_handlers_num].poll = poll;
|
||||
sound_handlers[sound_handlers_num].get_buffer = get_buffer;
|
||||
sound_handlers[sound_handlers_num].priv = p;
|
||||
sound_handlers_num++;
|
||||
}
|
||||
|
||||
void polladlib()
|
||||
void sound_poll(void *priv)
|
||||
{
|
||||
getadlib(adbuffer+(adpoll),adbuffer2+(adpoll),1);
|
||||
adpoll++;
|
||||
}
|
||||
int c;
|
||||
|
||||
int psgpoll=0;
|
||||
void pollpsg()
|
||||
{
|
||||
if (psgpoll>=20) return;
|
||||
getpsg(psgbuffer+(psgpoll*(48000/200)),48000/200);
|
||||
psgpoll++;
|
||||
}
|
||||
|
||||
int cmspoll=0;
|
||||
void pollcms()
|
||||
{
|
||||
if (cmspoll>=20) return;
|
||||
getcms(cmsbuffer+(cmspoll*(48000/200)*2),48000/200);
|
||||
cmspoll++;
|
||||
}
|
||||
|
||||
int guspoll=0;
|
||||
void pollgussnd()
|
||||
{
|
||||
if (guspoll>=20) return;
|
||||
getgus(gusbuffer+(guspoll*(48000/200)*2),48000/200);
|
||||
guspoll++;
|
||||
}
|
||||
|
||||
int spkpos=0;
|
||||
int wasgated = 0;
|
||||
void pollspk()
|
||||
{
|
||||
if (spkpos>=SOUNDBUFLEN) return;
|
||||
// printf("SPeaker - %i %i %i %02X\n",speakval,gated,speakon,pit.m[2]);
|
||||
if (gated)
|
||||
{
|
||||
if (!pit.m[2] || pit.m[2]==4)
|
||||
spkbuffer[spkpos]=speakval;
|
||||
else
|
||||
spkbuffer[spkpos]=(speakon)?0x1400:0;
|
||||
}
|
||||
else
|
||||
spkbuffer[spkpos]=(wasgated)?0x1400:0;
|
||||
spkpos++;
|
||||
wasgated=0;
|
||||
sound_poll_time += (int)((double)TIMER_USEC * (1000000.0 / 48000.0));
|
||||
|
||||
for (c = 0; c < sound_handlers_num; c++)
|
||||
sound_handlers[c].poll(sound_handlers[c].priv);
|
||||
}
|
||||
|
||||
FILE *soundf;
|
||||
|
||||
static int16_t cd_buffer[(SOUNDBUFLEN) * 2];
|
||||
void pollsound()
|
||||
void sound_get_buffer(void *priv)
|
||||
{
|
||||
int c;
|
||||
int16_t t[4];
|
||||
uint32_t pos;
|
||||
// printf("Pollsound! %i\n",soundon);
|
||||
// if (soundon)
|
||||
// {
|
||||
for (c=0;c<(SOUNDBUFLEN);c++) outbuffer[c<<1]=outbuffer[(c<<1)+1]=0;
|
||||
for (c=0;c<(SOUNDBUFLEN);c++)
|
||||
{
|
||||
outbuffer[c<<1]+=((adbuffer[c]*mixer.fm_l)>>16);
|
||||
outbuffer[(c<<1)+1]+=((adbuffer[c]*mixer.fm_r)>>16);
|
||||
// if (!c) pclog("F %04X %04X %04X\n",adbuffer[c],outbuffer[c<<1],mixer.fm_l);
|
||||
}
|
||||
addsb(outbuffer);
|
||||
for (c=0;c<(SOUNDBUFLEN);c++)
|
||||
{
|
||||
// if (!c) pclog("M %04X ",outbuffer[c<<1]);
|
||||
outbuffer[c<<1]=(outbuffer[c<<1]*mixer.master_l)>>16;
|
||||
outbuffer[(c<<1)+1]=(outbuffer[(c<<1)+1]*mixer.master_r)>>16;
|
||||
// if (!c) pclog("%04X %04X\n",outbuffer[c<<1],mixer.master_l);
|
||||
}
|
||||
if (mixer.bass_l!=8 || mixer.bass_r!=8 || mixer.treble_l!=8 || mixer.treble_r!=8)
|
||||
{
|
||||
for (c=0;c<(SOUNDBUFLEN);c++)
|
||||
{
|
||||
if (mixer.bass_l>8) outbuffer[c<<1] =(outbuffer[c<<1] +(((int16_t)low_iir(0,(float)outbuffer[c<<1]) *(mixer.bass_l-8))>>1))*((15-mixer.bass_l)+16)>>5;
|
||||
if (mixer.bass_r>8) outbuffer[(c<<1)+1]=(outbuffer[(c<<1)+1]+(((int16_t)low_iir(1,(float)outbuffer[(c<<1)+1]) *(mixer.bass_r-8))>>1))*((15-mixer.bass_r)+16)>>5;
|
||||
if (mixer.treble_l>8) outbuffer[c<<1] =(outbuffer[c<<1] +(((int16_t)high_iir(0,(float)outbuffer[c<<1]) *(mixer.treble_l-8))>>1))*((15-mixer.treble_l)+16)>>5;
|
||||
if (mixer.treble_r>8) outbuffer[(c<<1)+1]=(outbuffer[(c<<1)+1]+(((int16_t)high_iir(1,(float)outbuffer[(c<<1)+1]) *(mixer.treble_r-8))>>1))*((15-mixer.treble_r)+16)>>5;
|
||||
if (mixer.bass_l<8) outbuffer[c<<1] =(outbuffer[c<<1] +(((int16_t)low_cut_iir(0,(float)outbuffer[c<<1]) *(8-mixer.bass_l))>>1))*(mixer.bass_l+16)>>5;
|
||||
if (mixer.bass_r<8) outbuffer[(c<<1)+1]=(outbuffer[(c<<1)+1]+(((int16_t)low_cut_iir(1,(float)outbuffer[(c<<1)+1]) *(8-mixer.bass_r))>>1))*(mixer.bass_r+16)>>5;
|
||||
if (mixer.treble_l<8) outbuffer[c<<1] =(outbuffer[c<<1] +(((int16_t)high_cut_iir(0,(float)outbuffer[c<<1]) *(8-mixer.treble_l))>>1))*(mixer.treble_l+16)>>5;
|
||||
if (mixer.treble_r<8) outbuffer[(c<<1)+1]=(outbuffer[(c<<1)+1]+(((int16_t)high_cut_iir(1,(float)outbuffer[(c<<1)+1])*(8-mixer.treble_r))>>1))*(mixer.treble_r+16)>>5;
|
||||
}
|
||||
}
|
||||
for (c=0;c<(SOUNDBUFLEN);c++)
|
||||
{
|
||||
outbuffer[c<<1]+=(spkbuffer[c]/2);
|
||||
outbuffer[(c<<1)+1]+=(spkbuffer[c]/2);
|
||||
}
|
||||
for (c=0;c<(SOUNDBUFLEN);c++)
|
||||
{
|
||||
outbuffer[c<<1]+=(psgbuffer[c]/2);
|
||||
outbuffer[(c<<1)+1]+=(psgbuffer[c]/2);
|
||||
}
|
||||
for (c=0;c<((SOUNDBUFLEN)*2);c++)
|
||||
outbuffer[c]+=(cmsbuffer[c]/2);
|
||||
for (c=0;c<((SOUNDBUFLEN)*2);c++)
|
||||
outbuffer[c]+=(gusbuffer[c]);
|
||||
adddac(outbuffer);
|
||||
ioctl_audio_callback(cd_buffer, ((SOUNDBUFLEN) * 2 * 441) / 480);
|
||||
pos = 0;
|
||||
for (c = 0; c < (SOUNDBUFLEN) * 2; c+=2)
|
||||
{
|
||||
outbuffer[c] += cd_buffer[((pos >> 16) << 1)] / 2;
|
||||
outbuffer[c + 1] += cd_buffer[((pos >> 16) << 1) + 1] / 2;
|
||||
// outbuffer[c] += (int16_t)((int32_t)cd_buffer[pos >> 16] * (65536 - (pos & 0xffff))) / 65536;
|
||||
// outbuffer[c] += (int16_t)((int32_t)cd_buffer[(pos >> 16) + 1] * (pos & 0xffff)) / 65536;
|
||||
pos += 60211; //(44100 * 65536) / 48000;
|
||||
}
|
||||
|
||||
// if (!soundf) soundf=fopen("sound.pcm","wb");
|
||||
// fwrite(outbuffer,(SOUNDBUFLEN)*2*2,1,soundf);
|
||||
if (soundon) givealbuffer(outbuffer);
|
||||
// }
|
||||
// addsb(outbuffer);
|
||||
// adddac(outbuffer);
|
||||
adpoll=0;
|
||||
psgpoll=0;
|
||||
cmspoll=0;
|
||||
spkpos=0;
|
||||
guspoll=0;
|
||||
|
||||
sound_get_buffer_time += (TIMER_USEC * (1000000 / 10));
|
||||
|
||||
memset(outbuffer, 0, SOUNDBUFLEN * 2 * sizeof(int16_t));
|
||||
|
||||
for (c = 0; c < sound_handlers_num; c++)
|
||||
sound_handlers[c].get_buffer(outbuffer, SOUNDBUFLEN, sound_handlers[c].priv);
|
||||
|
||||
/* if (!soundf) soundf=fopen("sound.pcm","wb");
|
||||
fwrite(outbuffer,(SOUNDBUFLEN)*2*2,1,soundf);*/
|
||||
|
||||
if (soundon) givealbuffer(outbuffer);
|
||||
}
|
||||
|
||||
int sndcount;
|
||||
void pollsound60hz()
|
||||
void sound_reset()
|
||||
{
|
||||
// printf("Poll sound %i\n",sndcount);
|
||||
// pollad();
|
||||
pollpsg();
|
||||
pollcms();
|
||||
pollgussnd();
|
||||
sndcount++;
|
||||
if (sndcount==20)
|
||||
{
|
||||
sndcount=0;
|
||||
pollsound();
|
||||
}
|
||||
timer_add(sound_poll, &sound_poll_time, TIMER_ALWAYS_ENABLED, NULL);
|
||||
timer_add(sound_get_buffer, &sound_get_buffer_time, TIMER_ALWAYS_ENABLED, NULL);
|
||||
|
||||
sound_handlers_num = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,9 @@
|
|||
void sound_add_handler(void (*poll)(void *p), void (*get_buffer)(int16_t *buffer, int len, void *p), void *p);
|
||||
|
||||
extern int wasgated;
|
||||
extern int sbtype;
|
||||
|
||||
extern int sound_card_current;
|
||||
|
||||
char *sound_card_getname(int card);
|
||||
void sound_card_init();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#define USE_OPENAL
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef USE_OPENAL
|
||||
#include <AL/al.h>
|
||||
#include <AL/alut.h>
|
||||
|
|
@ -91,7 +92,6 @@ void givealbuffer(int16_t *buf)
|
|||
#ifdef USE_OPENAL
|
||||
int processed;
|
||||
int state;
|
||||
int c;
|
||||
|
||||
//return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,23 @@
|
|||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "pci.h"
|
||||
|
||||
#include "um8881f.h"
|
||||
|
||||
static uint8_t card_16[256];
|
||||
static uint8_t card_18[256];
|
||||
|
||||
void um8881f_write(int func, int addr, uint8_t val)
|
||||
void um8881f_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (addr == 0x54)
|
||||
{
|
||||
if ((card_16[0x54] ^ val) & 0x01)
|
||||
{
|
||||
if (val & 1)
|
||||
mem_sethandler(0xe0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml);
|
||||
mem_sethandler(0xe0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL);
|
||||
else
|
||||
mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL );
|
||||
mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL , NULL);
|
||||
}
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
|
@ -26,10 +27,10 @@ void um8881f_write(int func, int addr, uint8_t val)
|
|||
{
|
||||
switch (val & 0xc0)
|
||||
{
|
||||
case 0x00: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml); break;
|
||||
case 0x40: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL ); break;
|
||||
case 0x80: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); break;
|
||||
case 0xc0: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL ); break;
|
||||
case 0x00: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break;
|
||||
case 0x40: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL , NULL); break;
|
||||
case 0x80: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break;
|
||||
case 0xc0: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL , NULL); break;
|
||||
}
|
||||
shadowbios = val & 0x80;
|
||||
shadowbios_write = !(val & 0x40);
|
||||
|
|
@ -40,18 +41,18 @@ void um8881f_write(int func, int addr, uint8_t val)
|
|||
card_16[addr] = val;
|
||||
}
|
||||
|
||||
uint8_t um8881f_read(int func, int addr)
|
||||
uint8_t um8881f_read(int func, int addr, void *priv)
|
||||
{
|
||||
return card_16[addr];
|
||||
}
|
||||
|
||||
void um8886f_write(int func, int addr, uint8_t val)
|
||||
void um8886f_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (addr >= 4)
|
||||
card_18[addr] = val;
|
||||
}
|
||||
|
||||
uint8_t um8886f_read(int func, int addr)
|
||||
uint8_t um8886f_read(int func, int addr, void *priv)
|
||||
{
|
||||
return card_18[addr];
|
||||
}
|
||||
|
|
@ -60,8 +61,8 @@ uint8_t um8886f_read(int func, int addr)
|
|||
|
||||
void um8881f_init()
|
||||
{
|
||||
pci_add_specific(16, um8881f_read, um8881f_write);
|
||||
pci_add_specific(18, um8886f_read, um8886f_write);
|
||||
pci_add_specific(16, um8881f_read, um8881f_write, NULL);
|
||||
pci_add_specific(18, um8886f_read, um8886f_write, NULL);
|
||||
|
||||
card_16[0] = card_18[0] = 0x60; /*UMC*/
|
||||
card_16[1] = card_18[1] = 0x10;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,15 @@
|
|||
/*CGA emulation*/
|
||||
#include <math.h>
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
#include "vid_cga.h"
|
||||
|
||||
void cga_out(uint16_t addr, uint8_t val)
|
||||
void cga_recalctimings();
|
||||
|
||||
void cga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old;
|
||||
// pclog("CGA_OUT %04X %02X\n", addr, val);
|
||||
|
|
@ -32,7 +39,7 @@ void cga_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t cga_in(uint16_t addr)
|
||||
uint8_t cga_in(uint16_t addr, void *priv)
|
||||
{
|
||||
// pclog("CGA_IN %04X\n", addr);
|
||||
switch (addr)
|
||||
|
|
@ -49,7 +56,7 @@ uint8_t cga_in(uint16_t addr)
|
|||
|
||||
extern uint8_t charbuffer[256];
|
||||
|
||||
void cga_write(uint32_t addr, uint8_t val)
|
||||
void cga_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("CGA_WRITE %04X %02X\n", addr, val);
|
||||
vram[addr&0x3FFF]=val;
|
||||
|
|
@ -58,7 +65,7 @@ void cga_write(uint32_t addr, uint8_t val)
|
|||
cycles -= 4;
|
||||
}
|
||||
|
||||
uint8_t cga_read(uint32_t addr)
|
||||
uint8_t cga_read(uint32_t addr, void *priv)
|
||||
{
|
||||
cycles -= 4;
|
||||
charbuffer[ ((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc] = vram[addr&0x3FFF];
|
||||
|
|
@ -69,22 +76,25 @@ uint8_t cga_read(uint32_t addr)
|
|||
|
||||
void cga_recalctimings()
|
||||
{
|
||||
double _dispontime, _dispofftime;
|
||||
pclog("Recalc - %i %i %i\n", crtc[0], crtc[1], cgamode & 1);
|
||||
if (cgamode&1)
|
||||
{
|
||||
disptime=crtc[0]+1;
|
||||
dispontime=crtc[1];
|
||||
_dispontime=crtc[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
disptime=(crtc[0]+1)<<1;
|
||||
dispontime=crtc[1]<<1;
|
||||
_dispontime=crtc[1]<<1;
|
||||
}
|
||||
dispofftime=disptime-dispontime;
|
||||
_dispofftime=disptime-_dispontime;
|
||||
// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
|
||||
dispontime*=CGACONST;
|
||||
dispofftime*=CGACONST;
|
||||
_dispontime*=CGACONST;
|
||||
_dispofftime*=CGACONST;
|
||||
// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
static int linepos,displine;
|
||||
|
|
@ -92,7 +102,7 @@ static int sc,vc;
|
|||
static int cgadispon;
|
||||
static int con,coff,cursoron,cgablink;
|
||||
static int vsynctime,vadj;
|
||||
static uint16_t ma,maback,ca;
|
||||
static uint16_t ma,maback;
|
||||
static int oddeven = 0;
|
||||
|
||||
static int ntsc_col[8][8]=
|
||||
|
|
@ -117,7 +127,7 @@ void cga_poll()
|
|||
int x,c;
|
||||
int oldvc;
|
||||
uint8_t chr,attr;
|
||||
uint16_t dat,dat2,dat3,dat4;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
|
|
@ -467,7 +477,7 @@ int cga_init()
|
|||
i_filt[c]=512.0*cos((3.14*(cga_tint+c*4)/16.0) - 33.0/180.0);
|
||||
q_filt[c]=512.0*sin((3.14*(cga_tint+c*4)/16.0) - 33.0/180.0);
|
||||
}
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
int cga_init();
|
||||
void cga_out(uint16_t addr, uint8_t val);
|
||||
uint8_t cga_in(uint16_t addr);
|
||||
void cga_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t cga_in(uint16_t addr, void *priv);
|
||||
void cga_poll();
|
||||
void cga_write(uint32_t addr, uint8_t val);
|
||||
uint8_t cga_read(uint32_t addr);
|
||||
void cga_write(uint32_t addr, uint8_t val, void *priv);
|
||||
uint8_t cga_read(uint32_t addr, void *priv);
|
||||
void cga_recalctimings();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
/*EGA emulation*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
|
||||
void ega_recalctimings();
|
||||
void ega_write(uint32_t addr, uint8_t val);
|
||||
uint8_t ega_read(uint32_t addr);
|
||||
#include "vid_ega.h"
|
||||
#include "vid_svga.h"
|
||||
|
||||
extern uint8_t edatlookup[4][4];
|
||||
|
||||
|
|
@ -16,7 +17,7 @@ static uint8_t ega_rotate[8][256];
|
|||
/*3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour)*/
|
||||
int egaswitchread,egaswitches=9; /*7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines)*/
|
||||
|
||||
void ega_out(uint16_t addr, uint8_t val)
|
||||
void ega_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int c;
|
||||
uint8_t o,old;
|
||||
|
|
@ -73,21 +74,21 @@ void ega_out(uint16_t addr, uint8_t val)
|
|||
case 4: readplane=val&3; break;
|
||||
case 5: writemode=val&3; readmode=val&8; break;
|
||||
case 6:
|
||||
mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL);
|
||||
mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
// pclog("Write mapping %02X\n", val);
|
||||
switch (val&0xC)
|
||||
{
|
||||
case 0x0: /*128k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL);
|
||||
mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
break;
|
||||
case 0x4: /*64k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL);
|
||||
mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
break;
|
||||
case 0x8: /*32k at B0000*/
|
||||
mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL);
|
||||
mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
break;
|
||||
case 0xC: /*32k at B8000*/
|
||||
mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -114,9 +115,8 @@ void ega_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t ega_in(uint16_t addr)
|
||||
uint8_t ega_in(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
if ((addr&0xFFF0) == 0x3B0) addr |= 0x20;
|
||||
switch (addr)
|
||||
{
|
||||
|
|
@ -161,8 +161,9 @@ static int scrollcache;
|
|||
|
||||
void ega_recalctimings()
|
||||
{
|
||||
float crtcconst;
|
||||
int temp;
|
||||
double _dispontime, _dispofftime;
|
||||
double crtcconst;
|
||||
|
||||
ega_vtotal=crtc[6];
|
||||
ega_dispend=crtc[0x12];
|
||||
ega_vsyncstart=crtc[0x10];
|
||||
|
|
@ -195,14 +196,16 @@ void ega_recalctimings()
|
|||
else crtcconst=(seqregs[1]&1)?(CGACONST*(8.0/9.0)):CGACONST;
|
||||
|
||||
disptime=crtc[0]+2;
|
||||
dispontime=crtc[1]+1;
|
||||
_dispontime=crtc[1]+1;
|
||||
|
||||
printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8);
|
||||
if (seqregs[1]&8) { disptime*=2; dispontime*=2; }
|
||||
dispofftime=disptime-dispontime;
|
||||
dispontime*=crtcconst;
|
||||
dispofftime*=crtcconst;
|
||||
printf("Disptime %f dispontime %f hdisp %i\n",disptime,_dispontime,crtc[1]*8);
|
||||
if (seqregs[1]&8) { disptime*=2; _dispontime*=2; }
|
||||
_dispofftime=disptime-_dispontime;
|
||||
_dispontime*=crtcconst;
|
||||
_dispofftime*=crtcconst;
|
||||
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
|
||||
// printf("EGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4));
|
||||
// printf("EGA vert total %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart);
|
||||
|
|
@ -525,11 +528,9 @@ void ega_poll()
|
|||
}
|
||||
|
||||
|
||||
void ega_write(uint32_t addr, uint8_t val)
|
||||
void ega_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int x,y;
|
||||
char s[2]={0,0};
|
||||
uint8_t vala,valb,valc,vald,wm=writemask;
|
||||
uint8_t vala,valb,valc,vald;
|
||||
|
||||
egawrites++;
|
||||
cycles -= video_timing_b;
|
||||
|
|
@ -647,10 +648,9 @@ void ega_write(uint32_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t ega_read(uint32_t addr)
|
||||
uint8_t ega_read(uint32_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp,temp2,temp3,temp4;
|
||||
uint32_t addr2;
|
||||
egareads++;
|
||||
cycles -= video_timing_b;
|
||||
cycles_lost += video_timing_b;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
int ega_init();
|
||||
void ega_out(uint16_t addr, uint8_t val);
|
||||
uint8_t ega_in(uint16_t addr);
|
||||
void ega_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t ega_in(uint16_t addr, void *priv);
|
||||
void ega_poll();
|
||||
void ega_recalctimings();
|
||||
void ega_write(uint32_t addr, uint8_t val);
|
||||
uint8_t ega_read(uint32_t addr);
|
||||
void ega_write(uint32_t addr, uint8_t val, void *priv);
|
||||
uint8_t ega_read(uint32_t addr, void *priv);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*ET4000 emulation*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_unk_ramdac.h"
|
||||
|
|
@ -7,7 +8,7 @@
|
|||
int et4k_b8000;
|
||||
|
||||
|
||||
void et4000_out(uint16_t addr, uint8_t val)
|
||||
void et4000_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old;
|
||||
|
||||
|
|
@ -18,7 +19,7 @@ void et4000_out(uint16_t addr, uint8_t val)
|
|||
switch (addr)
|
||||
{
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
unk_ramdac_out(addr,val);
|
||||
unk_ramdac_out(addr, val, NULL);
|
||||
return;
|
||||
|
||||
case 0x3CD: /*Banking*/
|
||||
|
|
@ -57,13 +58,11 @@ void et4000_out(uint16_t addr, uint8_t val)
|
|||
if (val==0x29) svgaon=0;
|
||||
break;
|
||||
}
|
||||
svga_out(addr,val);
|
||||
svga_out(addr, val, priv);
|
||||
}
|
||||
|
||||
uint8_t et4000_in(uint16_t addr)
|
||||
uint8_t et4000_in(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
|
||||
if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr);
|
||||
|
|
@ -75,7 +74,7 @@ uint8_t et4000_in(uint16_t addr)
|
|||
break;
|
||||
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
return unk_ramdac_in(addr);
|
||||
return unk_ramdac_in(addr, NULL);
|
||||
|
||||
case 0x3CD: /*Banking*/
|
||||
return svgaseg;
|
||||
|
|
@ -84,7 +83,7 @@ uint8_t et4000_in(uint16_t addr)
|
|||
case 0x3D5:
|
||||
return crtc[crtcreg];
|
||||
}
|
||||
return svga_in(addr);
|
||||
return svga_in(addr, priv);
|
||||
}
|
||||
|
||||
void et4000_recalctimings()
|
||||
|
|
@ -98,6 +97,7 @@ void et4000_recalctimings()
|
|||
// if (crtc[0x3F]&0x80) svga_rowoffset+=0x100;
|
||||
if (crtc[0x3F]&1) svga_htotal+=256;
|
||||
if (attrregs[0x16]&0x20) svga_hdisp<<=1;
|
||||
|
||||
// pclog("Rowoffset %i\n",svga_rowoffset);
|
||||
|
||||
switch (((svga_miscout >> 2) & 3) | ((crtc[0x34] << 1) & 4))
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
*/
|
||||
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "pci.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_icd2061.h"
|
||||
|
|
@ -15,14 +17,14 @@ int et4k_b8000;
|
|||
|
||||
void et4000w32p_recalcmapping();
|
||||
|
||||
uint8_t et4000w32p_mmu_read(uint32_t addr);
|
||||
void et4000w32p_mmu_write(uint32_t addr, uint8_t val);
|
||||
uint8_t et4000w32p_mmu_read(uint32_t addr, void *priv);
|
||||
void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv);
|
||||
|
||||
static int et4000w32p_index;
|
||||
static uint8_t et4000w32p_regs[256];
|
||||
static uint32_t et4000w32p_linearbase, et4000w32p_linearbase_old;
|
||||
|
||||
void et4000w32p_out(uint16_t addr, uint8_t val)
|
||||
void et4000w32p_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old;
|
||||
|
||||
|
|
@ -39,7 +41,7 @@ void et4000w32p_out(uint16_t addr, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
stg_ramdac_out(addr,val);
|
||||
stg_ramdac_out(addr, val, NULL);
|
||||
return;
|
||||
|
||||
case 0x3CB: /*Banking extension*/
|
||||
|
|
@ -111,10 +113,10 @@ void et4000w32p_out(uint16_t addr, uint8_t val)
|
|||
return;
|
||||
|
||||
}
|
||||
svga_out(addr,val);
|
||||
svga_out(addr, val, NULL);
|
||||
}
|
||||
|
||||
uint8_t et4000w32p_in(uint16_t addr)
|
||||
uint8_t et4000w32p_in(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// if (addr==0x3DA) pclog("In 3DA %04X(%06X):%04X\n",CS,cs,pc);
|
||||
|
|
@ -132,7 +134,7 @@ uint8_t et4000w32p_in(uint16_t addr)
|
|||
break;
|
||||
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
return stg_ramdac_in(addr);
|
||||
return stg_ramdac_in(addr, NULL);
|
||||
|
||||
case 0x3CB:
|
||||
return svgaseg2;
|
||||
|
|
@ -166,15 +168,14 @@ uint8_t et4000w32p_in(uint16_t addr)
|
|||
}
|
||||
return et4000w32p_regs[et4000w32p_index];
|
||||
}
|
||||
return svga_in(addr);
|
||||
return svga_in(addr, NULL);
|
||||
}
|
||||
|
||||
void et4000w32p_recalctimings()
|
||||
{
|
||||
double clk;
|
||||
// pclog("Recalc %08X ",svga_ma);
|
||||
svga_ma|=(crtc[0x33]&0x7)<<16;
|
||||
pclog("SVGA_MA %08X %i\n", svga_ma, (svga_miscout >> 2) & 3);
|
||||
// pclog("SVGA_MA %08X %i\n", svga_ma, (svga_miscout >> 2) & 3);
|
||||
if (crtc[0x35]&2) svga_vtotal+=0x400;
|
||||
if (crtc[0x35]&4) svga_dispend+=0x400;
|
||||
if (crtc[0x35]&8) svga_vsyncstart+=0x400;
|
||||
|
|
@ -205,12 +206,12 @@ void et4000w32p_recalcmapping()
|
|||
{
|
||||
int map;
|
||||
|
||||
mem_removehandler(et4000w32p_linearbase_old, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear);
|
||||
mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_removehandler(0xb0000, 0x10000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL);
|
||||
mem_removehandler(et4000w32p_linearbase_old, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
mem_removehandler( 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
mem_removehandler( 0xb0000, 0x10000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL);
|
||||
if (crtc[0x36] & 0x10) /*Linear frame buffer*/
|
||||
{
|
||||
mem_sethandler(et4000w32p_linearbase, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear);
|
||||
mem_sethandler(et4000w32p_linearbase, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -220,28 +221,28 @@ void et4000w32p_recalcmapping()
|
|||
switch (map)
|
||||
{
|
||||
case 0x0: case 0x4: case 0x8: case 0xC: /*128k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0x1: /*64k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0x2: /*32k at B0000*/
|
||||
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0x3: /*32k at B8000*/
|
||||
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0x5: case 0x9: case 0xD: /*64k at A0000, MMU at B8000*/
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xb8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL);
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL);
|
||||
break;
|
||||
case 0x6: case 0xA: case 0xE: /*32k at B0000, MMU at A8000*/
|
||||
mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL);
|
||||
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL);
|
||||
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0x7: case 0xB: case 0xF: /*32k at B8000, MMU at A8000*/
|
||||
mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
}
|
||||
// pclog("ET4K map %02X\n", map);
|
||||
|
|
@ -295,7 +296,7 @@ void et4000w32_reset()
|
|||
void et4000w32_blit_start();
|
||||
void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input);
|
||||
|
||||
void et4000w32p_mmu_write(uint32_t addr, uint8_t val)
|
||||
void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int bank;
|
||||
// pclog("ET4K write %08X %02X %02X %04X(%08X):%08X\n",addr,val,acl.status,acl.internal.ctrl_routing,CS,cs,pc);
|
||||
|
|
@ -402,7 +403,7 @@ void et4000w32p_mmu_write(uint32_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t et4000w32p_mmu_read(uint32_t addr)
|
||||
uint8_t et4000w32p_mmu_read(uint32_t addr, void *priv)
|
||||
{
|
||||
int bank;
|
||||
uint8_t temp;
|
||||
|
|
@ -482,6 +483,7 @@ uint8_t et4000w32p_mmu_read(uint32_t addr)
|
|||
}
|
||||
return 0xFF;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
int et4000w32_max_x[8]={0,0,4,8,16,32,64,0x70000000};
|
||||
|
|
@ -846,7 +848,7 @@ void et4000w32p_cursor_draw(int displine)
|
|||
svga_hwcursor_latch.addr += 16;
|
||||
}
|
||||
|
||||
uint8_t et4000w32p_pci_read(int func, int addr)
|
||||
uint8_t et4000w32p_pci_read(int func, int addr, void *priv)
|
||||
{
|
||||
pclog("ET4000 PCI read %08X\n", addr);
|
||||
switch (addr)
|
||||
|
|
@ -880,7 +882,7 @@ uint8_t et4000w32p_pci_read(int func, int addr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void et4000w32p_pci_write(int func, int addr, uint8_t val)
|
||||
void et4000w32p_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
|
|
@ -893,16 +895,16 @@ int et4000w32p_init()
|
|||
svga_recalctimings_ex = et4000w32p_recalctimings;
|
||||
svga_hwcursor_draw = et4000w32p_cursor_draw;
|
||||
|
||||
io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL);
|
||||
io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL);
|
||||
io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL);
|
||||
io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL);
|
||||
io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL);
|
||||
io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL);
|
||||
io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL);
|
||||
io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL);
|
||||
io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
|
||||
|
||||
pci_add(et4000w32p_pci_read, et4000w32p_pci_write);
|
||||
pci_add(et4000w32p_pci_read, et4000w32p_pci_write, NULL);
|
||||
|
||||
svga_vram_limit = 2 << 20; /*2mb - chip supports 4mb but can't map both 4mb linear frame buffer and accelerator registers*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
/*Hercules emulation*/
|
||||
#include "ibm.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
|
||||
void hercules_recalctimings();
|
||||
void hercules_write(uint32_t addr, uint8_t val);
|
||||
uint8_t hercules_read(uint32_t addr);
|
||||
void hercules_write(uint32_t addr, uint8_t val, void *priv);
|
||||
uint8_t hercules_read(uint32_t addr, void *priv);
|
||||
|
||||
static uint8_t hercules_ctrl, hercules_ctrl2, hercules_stat;
|
||||
uint8_t crtcm[32],crtcmreg;
|
||||
|
||||
void hercules_out(uint16_t addr, uint8_t val)
|
||||
void hercules_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("Herc out %04X %02X\n",addr,val);
|
||||
switch (addr)
|
||||
|
|
@ -37,7 +39,7 @@ void hercules_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t hercules_in(uint16_t addr)
|
||||
uint8_t hercules_in(uint16_t addr, void *priv)
|
||||
{
|
||||
// pclog("Herc in %04X %02X %04X:%04X %04X\n",addr,(hercules_stat & 0xF) | ((hercules_stat & 8) << 4),CS,pc,CX);
|
||||
switch (addr)
|
||||
|
|
@ -49,33 +51,37 @@ uint8_t hercules_in(uint16_t addr)
|
|||
case 0x3BA:
|
||||
return (hercules_stat & 0xF) | ((hercules_stat & 8) << 4);
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void hercules_write(uint32_t addr, uint8_t val)
|
||||
void hercules_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("Herc write %08X %02X\n",addr,val);
|
||||
vram[addr&0xFFFF]=val;
|
||||
}
|
||||
|
||||
uint8_t hercules_read(uint32_t addr)
|
||||
uint8_t hercules_read(uint32_t addr, void *priv)
|
||||
{
|
||||
return vram[addr&0xFFFF];
|
||||
}
|
||||
|
||||
void hercules_recalctimings()
|
||||
{
|
||||
double _dispontime, _dispofftime;
|
||||
disptime=crtc[0]+1;
|
||||
dispontime=crtc[1];
|
||||
dispofftime=disptime-dispontime;
|
||||
dispontime*=MDACONST;
|
||||
dispofftime*=MDACONST;
|
||||
_dispontime=crtc[1];
|
||||
_dispofftime=disptime-_dispontime;
|
||||
_dispontime*=MDACONST;
|
||||
_dispofftime*=MDACONST;
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
int mdacols[256][2][2];
|
||||
|
||||
static int linepos,displine;
|
||||
static int vc,sc;
|
||||
static uint16_t ma,maback,ca;
|
||||
static uint16_t ma,maback;
|
||||
static int con,coff,cursoron;
|
||||
static int cgadispon,cgablink;
|
||||
static int vsynctime,vadj;
|
||||
|
|
@ -87,9 +93,8 @@ void hercules_poll()
|
|||
int x,c;
|
||||
int oldvc;
|
||||
uint8_t chr,attr;
|
||||
uint16_t dat,dat2,dat3,dat4;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
int blink;
|
||||
if (!linepos)
|
||||
|
|
@ -264,7 +269,7 @@ void hercules_poll()
|
|||
|
||||
int hercules_init()
|
||||
{
|
||||
mem_sethandler(0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL);
|
||||
mem_sethandler(0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
/*MDA emulation*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
|
||||
void mda_recalctimings();
|
||||
|
|
@ -7,7 +10,7 @@ void mda_recalctimings();
|
|||
static uint8_t mda_ctrl,mda_stat;
|
||||
uint8_t crtcm[32],crtcmreg;
|
||||
|
||||
void mda_out(uint16_t addr, uint8_t val)
|
||||
void mda_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
|
|
@ -29,7 +32,7 @@ void mda_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t mda_in(uint16_t addr)
|
||||
uint8_t mda_in(uint16_t addr, void *priv)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
|
|
@ -40,32 +43,36 @@ uint8_t mda_in(uint16_t addr)
|
|||
case 0x3BA:
|
||||
return mda_stat | 0xF0;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void mda_write(uint32_t addr, uint8_t val)
|
||||
void mda_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
vram[addr&0xFFF]=val;
|
||||
}
|
||||
|
||||
uint8_t mda_read(uint32_t addr)
|
||||
uint8_t mda_read(uint32_t addr, void *priv)
|
||||
{
|
||||
return vram[addr&0xFFF];
|
||||
}
|
||||
|
||||
void mda_recalctimings()
|
||||
{
|
||||
double _dispontime, _dispofftime;
|
||||
disptime=crtc[0]+1;
|
||||
dispontime=crtc[1];
|
||||
dispofftime=disptime-dispontime;
|
||||
dispontime*=MDACONST;
|
||||
dispofftime*=MDACONST;
|
||||
_dispontime=crtc[1];
|
||||
_dispofftime=disptime-_dispontime;
|
||||
_dispontime*=MDACONST;
|
||||
_dispofftime*=MDACONST;
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
int mdacols[256][2][2];
|
||||
|
||||
static int linepos,displine;
|
||||
static int vc,sc;
|
||||
static uint16_t ma,maback,ca;
|
||||
static uint16_t ma,maback;
|
||||
static int con,coff,cursoron;
|
||||
static int cgadispon,cgablink;
|
||||
static int vsynctime,vadj;
|
||||
|
|
@ -77,9 +84,7 @@ void mda_poll()
|
|||
int x,c;
|
||||
int oldvc;
|
||||
uint8_t chr,attr;
|
||||
uint16_t dat,dat2,dat3,dat4;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
int blink;
|
||||
if (!linepos)
|
||||
|
|
@ -227,7 +232,7 @@ void mda_poll()
|
|||
|
||||
int mda_init()
|
||||
{
|
||||
mem_sethandler(0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL);
|
||||
mem_sethandler(0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
/*Olivetti M24 video emulation
|
||||
Essentially double-res CGA*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
|
||||
void m24_recalctimings();
|
||||
|
||||
static uint8_t m24_ctrl;
|
||||
static uint32_t m24_base;
|
||||
|
||||
void m24_out(uint16_t addr, uint8_t val)
|
||||
void m24_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old;
|
||||
switch (addr)
|
||||
|
|
@ -39,7 +44,7 @@ void m24_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t m24_in(uint16_t addr)
|
||||
uint8_t m24_in(uint16_t addr, void *priv)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
|
|
@ -55,35 +60,38 @@ uint8_t m24_in(uint16_t addr)
|
|||
|
||||
static uint8_t charbuffer[256];
|
||||
|
||||
void m24_write(uint32_t addr, uint8_t val)
|
||||
void m24_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
vram[addr & 0x7FFF]=val;
|
||||
charbuffer[ ((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val;
|
||||
charbuffer[(((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val;
|
||||
}
|
||||
|
||||
uint8_t m24_read(uint32_t addr)
|
||||
uint8_t m24_read(uint32_t addr, void *priv)
|
||||
{
|
||||
return vram[addr & 0x7FFF];
|
||||
}
|
||||
|
||||
void m24_recalctimings()
|
||||
{
|
||||
double _dispontime, _dispofftime;
|
||||
if (cgamode & 1)
|
||||
{
|
||||
disptime = crtc[0] + 1;
|
||||
dispontime = crtc[1];
|
||||
_dispontime = crtc[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
disptime = (crtc[0] + 1) << 1;
|
||||
dispontime = crtc[1] << 1;
|
||||
_dispontime = crtc[1] << 1;
|
||||
}
|
||||
dispofftime = disptime - dispontime;
|
||||
_dispofftime = disptime - _dispontime;
|
||||
// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
|
||||
dispontime *= CGACONST / 2;
|
||||
dispofftime *= CGACONST / 2;
|
||||
_dispontime *= CGACONST / 2;
|
||||
_dispofftime *= CGACONST / 2;
|
||||
// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
static int linepos,displine;
|
||||
|
|
@ -92,7 +100,7 @@ static int cgadispon;
|
|||
static int con,coff,cursoron,cgablink;
|
||||
static int vsynctime,vadj;
|
||||
static int m24_lineff = 0;
|
||||
static uint16_t ma,maback,ca;
|
||||
static uint16_t ma,maback;
|
||||
|
||||
void m24_poll()
|
||||
{
|
||||
|
|
@ -101,7 +109,7 @@ void m24_poll()
|
|||
int x,c;
|
||||
int oldvc;
|
||||
uint8_t chr,attr;
|
||||
uint16_t dat,dat2,dat3,dat4;
|
||||
uint16_t dat,dat2;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
|
|
@ -401,7 +409,7 @@ endblit();
|
|||
|
||||
int m24_init()
|
||||
{
|
||||
mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,19 @@
|
|||
/*Oak OTI067 emulation*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
|
||||
static int oti067_index;
|
||||
static uint8_t oti067_regs[32];
|
||||
|
||||
void oti067_out(uint16_t addr, uint8_t val)
|
||||
void oti067_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old;
|
||||
|
||||
if ((addr&0xFFF0) == 0x3B0) addr |= 0x20;
|
||||
|
||||
// pclog("oti067_out : %04X %02X %02X %i\n", addr, val, ram[0x489], ins);
|
||||
|
||||
if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
|
|
@ -46,28 +49,41 @@ void oti067_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
return;
|
||||
}
|
||||
svga_out(addr,val);
|
||||
svga_out(addr, val, NULL);
|
||||
}
|
||||
|
||||
uint8_t oti067_in(uint16_t addr)
|
||||
uint8_t oti067_in(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
if ((addr&0xFFF0) == 0x3B0) addr |= 0x20;
|
||||
// if (addr != 0x3da && addr != 0x3ba) pclog("oti067_in : %04X ", addr);
|
||||
|
||||
if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
return crtcreg;
|
||||
temp = crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
return crtc[crtcreg];
|
||||
case 0x3DE: return oti067_index|(2<<5);
|
||||
temp = crtc[crtcreg];
|
||||
break;
|
||||
|
||||
case 0x3DE:
|
||||
temp = oti067_index|(2<<5);
|
||||
break;
|
||||
case 0x3DF:
|
||||
if (oti067_index==0x10) return 0x40;
|
||||
if (oti067_index==0xD) return oti067_regs[oti067_index]|0xC0;
|
||||
return oti067_regs[oti067_index];
|
||||
if (oti067_index==0x10) temp = 0x18;
|
||||
else if (oti067_index==0xD) temp = oti067_regs[oti067_index]|0xC0;
|
||||
else temp = oti067_regs[oti067_index];
|
||||
break;
|
||||
|
||||
default:
|
||||
temp = svga_in(addr, NULL);
|
||||
break;
|
||||
}
|
||||
return svga_in(addr);
|
||||
// if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void oti067_recalctimings()
|
||||
|
|
@ -82,6 +98,8 @@ int oti067_init()
|
|||
svga_recalctimings_ex = oti067_recalctimings;
|
||||
svga_vram_limit = 1 << 19; /*512kb*/
|
||||
vrammask = 0x7ffff;
|
||||
bpp = 8;
|
||||
svga_miscout = 1;
|
||||
return svga_init();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,14 @@
|
|||
MegaPC uses W90C11A
|
||||
*/
|
||||
#include "ibm.h"
|
||||
#include "mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_unk_ramdac.h"
|
||||
|
||||
void paradise_write(uint32_t addr, uint8_t val);
|
||||
uint8_t paradise_read(uint32_t addr);
|
||||
void paradise_write(uint32_t addr, uint8_t val, void *priv);
|
||||
uint8_t paradise_read(uint32_t addr, void *priv);
|
||||
void paradise_remap();
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -21,7 +23,7 @@ static int paradise_type;
|
|||
|
||||
static uint32_t paradise_bank_r[4], paradise_bank_w[4];
|
||||
|
||||
void paradise_out(uint16_t addr, uint8_t val)
|
||||
void paradise_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old;
|
||||
|
||||
|
|
@ -52,21 +54,21 @@ void paradise_out(uint16_t addr, uint8_t val)
|
|||
{
|
||||
if ((gdcreg[6] & 0xc) != (val & 0xc))
|
||||
{
|
||||
mem_removehandler(0xa0000, 0x20000, paradise_read, NULL, NULL, svga_write, NULL, NULL);
|
||||
mem_removehandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL);
|
||||
// pclog("Write mapping %02X\n", val);
|
||||
switch (val&0xC)
|
||||
{
|
||||
case 0x0: /*128k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL);
|
||||
mem_sethandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL);
|
||||
break;
|
||||
case 0x4: /*64k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x10000, paradise_read, NULL, NULL, paradise_write, NULL, NULL);
|
||||
mem_sethandler(0xa0000, 0x10000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL);
|
||||
break;
|
||||
case 0x8: /*32k at B0000*/
|
||||
mem_sethandler(0xb0000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL);
|
||||
mem_sethandler(0xb0000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL);
|
||||
break;
|
||||
case 0xC: /*32k at B8000*/
|
||||
mem_sethandler(0xb8000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -114,13 +116,11 @@ void paradise_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr,val);
|
||||
svga_out(addr, val, NULL);
|
||||
}
|
||||
|
||||
uint8_t paradise_in(uint16_t addr)
|
||||
uint8_t paradise_in(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
|
||||
// if (addr != 0x3da) pclog("Paradise in %04X\n", addr);
|
||||
|
|
@ -157,7 +157,7 @@ uint8_t paradise_in(uint16_t addr)
|
|||
return 0xff;
|
||||
return crtc[crtcreg];
|
||||
}
|
||||
return svga_in(addr);
|
||||
return svga_in(addr, NULL);
|
||||
}
|
||||
|
||||
void paradise_remap()
|
||||
|
|
@ -185,8 +185,8 @@ void paradise_remap()
|
|||
// pclog("Remap 3\n");
|
||||
paradise_bank_r[0] = paradise_bank_w[0] = (gdcreg[0xa] & 0x7f) << 12;
|
||||
paradise_bank_r[1] = paradise_bank_w[1] = ((gdcreg[0xa] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise_bank_w[2] = paradise_bank_w[2] = (gdcreg[0x9] & 0x7f) << 12;
|
||||
paradise_bank_w[3] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise_bank_r[2] = paradise_bank_w[2] = (gdcreg[0x9] & 0x7f) << 12;
|
||||
paradise_bank_r[3] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -207,20 +207,20 @@ void paradise_recalctimings()
|
|||
|
||||
#define egacycles 1
|
||||
#define egacycles2 1
|
||||
void paradise_write(uint32_t addr, uint8_t val)
|
||||
void paradise_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("paradise_write : %05X %02X ", addr, val);
|
||||
addr = (addr & 0x7fff) + paradise_bank_w[(addr >> 15) & 3];
|
||||
// pclog("%08X\n", addr);
|
||||
svga_write_linear(addr, val);
|
||||
svga_write_linear(addr, val, priv);
|
||||
}
|
||||
|
||||
uint8_t paradise_read(uint32_t addr)
|
||||
uint8_t paradise_read(uint32_t addr, void *priv)
|
||||
{
|
||||
// pclog("paradise_read : %05X ", addr);
|
||||
addr = (addr & 0x7fff) + paradise_bank_r[(addr >> 15) & 3];
|
||||
// pclog("%08X\n", addr);
|
||||
return svga_read_linear(addr);
|
||||
return svga_read_linear(addr, priv);
|
||||
}
|
||||
|
||||
int paradise_init()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@
|
|||
and 46 cycles. PCem currently always uses the lower number.*/
|
||||
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
#include "vid_cga.h"
|
||||
|
||||
|
|
@ -15,7 +18,7 @@ static uint8_t pc1512_plane_write,pc1512_plane_read,pc1512_border;
|
|||
|
||||
void pc1512_recalctimings();
|
||||
|
||||
void pc1512_out(uint16_t addr, uint8_t val)
|
||||
void pc1512_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old;
|
||||
// pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
|
|
@ -59,7 +62,7 @@ void pc1512_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t pc1512_in(uint16_t addr)
|
||||
uint8_t pc1512_in(uint16_t addr, void *priv)
|
||||
{
|
||||
// pclog("PC1512 in %04X %02X %04X:%04X\n",addr,CS,pc);
|
||||
switch (addr)
|
||||
|
|
@ -74,7 +77,7 @@ uint8_t pc1512_in(uint16_t addr)
|
|||
return 0xFF;
|
||||
}
|
||||
|
||||
void pc1512_write(uint32_t addr, uint8_t val)
|
||||
void pc1512_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
/* if (CS==0x023E && pc==0x524E)
|
||||
{
|
||||
|
|
@ -95,7 +98,7 @@ void pc1512_write(uint32_t addr, uint8_t val)
|
|||
vram[addr]=val;
|
||||
}
|
||||
|
||||
uint8_t pc1512_read(uint32_t addr)
|
||||
uint8_t pc1512_read(uint32_t addr, void *priv)
|
||||
{
|
||||
// pclog("PC1512 read %08X %02X %01X\n",addr,cgamode&0x12,pc1512_plane_read);
|
||||
cycles-=12;
|
||||
|
|
@ -111,32 +114,23 @@ static int sc,vc;
|
|||
static int cgadispon;
|
||||
static int con,coff,cursoron,cgablink;
|
||||
static int vsynctime,vadj;
|
||||
static uint16_t ma,maback,ca;
|
||||
|
||||
static int ntsc_col[8][8]=
|
||||
{
|
||||
{0,0,0,0,0,0,0,0}, /*Black*/
|
||||
{0,0,1,1,1,1,0,0}, /*Blue*/
|
||||
{1,0,0,0,0,1,1,1}, /*Green*/
|
||||
{0,0,0,0,1,1,1,1}, /*Cyan*/
|
||||
{1,1,1,1,0,0,0,0}, /*Red*/
|
||||
{0,1,1,1,1,0,0,0}, /*Magenta*/
|
||||
{1,1,0,0,0,0,1,1}, /*Yellow*/
|
||||
{1,1,1,1,1,1,1,1} /*White*/
|
||||
};
|
||||
static uint16_t ma,maback;
|
||||
|
||||
int i_filt[8],q_filt[8];
|
||||
|
||||
|
||||
void pc1512_recalctimings()
|
||||
{
|
||||
double _dispontime, _dispofftime;
|
||||
disptime = 128; /*Fixed on PC1512*/
|
||||
dispontime = 80;
|
||||
dispofftime=disptime-dispontime;
|
||||
_dispontime = 80;
|
||||
_dispofftime=disptime-_dispontime;
|
||||
// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
|
||||
dispontime*=CGACONST;
|
||||
dispofftime*=CGACONST;
|
||||
_dispontime*=CGACONST;
|
||||
_dispofftime*=CGACONST;
|
||||
// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
void pc1512_poll()
|
||||
|
|
@ -417,7 +411,7 @@ endblit();
|
|||
|
||||
int pc1512_init()
|
||||
{
|
||||
mem_sethandler(0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,54 +1,56 @@
|
|||
/*PC1640 video emulation.
|
||||
Mostly standard EGA, but with CGA & Hercules emulation*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_cga.h"
|
||||
#include "vid_ega.h"
|
||||
|
||||
static int pc1640_cga=1;
|
||||
|
||||
void pc1640_out(uint16_t addr, uint8_t val)
|
||||
void pc1640_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3DB:
|
||||
pc1640_cga=val&0x40;
|
||||
mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL);
|
||||
mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL);
|
||||
mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
||||
if (pc1640_cga)
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
||||
else
|
||||
{
|
||||
switch (gdcreg[6] & 0xC)
|
||||
{
|
||||
case 0x0: /*128k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL);
|
||||
mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
break;
|
||||
case 0x4: /*64k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL);
|
||||
mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
break;
|
||||
case 0x8: /*32k at B0000*/
|
||||
mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL);
|
||||
mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
break;
|
||||
case 0xC: /*32k at B8000*/
|
||||
mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pclog("3DB write %02X\n", val);
|
||||
return;
|
||||
}
|
||||
if (pc1640_cga) cga_out(addr,val);
|
||||
else ega_out(addr,val);
|
||||
if (pc1640_cga) cga_out(addr, val, NULL);
|
||||
else ega_out(addr, val, NULL);
|
||||
}
|
||||
|
||||
uint8_t pc1640_in(uint16_t addr)
|
||||
uint8_t pc1640_in(uint16_t addr, void *priv)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
}
|
||||
if (pc1640_cga) return cga_in(addr);
|
||||
else return ega_in(addr);
|
||||
if (pc1640_cga) return cga_in(addr, NULL);
|
||||
else return ega_in(addr, NULL);
|
||||
}
|
||||
|
||||
void pc1640_recalctimings()
|
||||
|
|
@ -69,7 +71,7 @@ int pc1640_init()
|
|||
|
||||
pc1640_cga = 1;
|
||||
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
CGA with some NMI stuff. But we don't need that as it's only used for TV and
|
||||
LCD displays, and we're emulating a CRT*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_cga.h"
|
||||
|
||||
uint8_t pc200_3dd, pc200_3de, pc200_3df;
|
||||
|
||||
void pc200_out(uint16_t addr, uint8_t val)
|
||||
void pc200_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old;
|
||||
switch (addr)
|
||||
|
|
@ -48,10 +50,10 @@ void pc200_out(uint16_t addr, uint8_t val)
|
|||
if (val&0x80) pc200_3dd|=0x40;
|
||||
return;
|
||||
}
|
||||
cga_out(addr,val);
|
||||
cga_out(addr, val, NULL);
|
||||
}
|
||||
|
||||
uint8_t pc200_in(uint16_t addr)
|
||||
uint8_t pc200_in(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
switch (addr)
|
||||
|
|
@ -70,12 +72,12 @@ uint8_t pc200_in(uint16_t addr)
|
|||
case 0x3DF:
|
||||
return pc200_3df;
|
||||
}
|
||||
return cga_in(addr);
|
||||
return cga_in(addr, NULL);
|
||||
}
|
||||
|
||||
int pc200_init()
|
||||
{
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
||||
return cga_init();
|
||||
}
|
||||
|
||||
|
|
|
|||
149
src/vid_s3.c
149
src/vid_s3.c
|
|
@ -1,17 +1,19 @@
|
|||
/*S3 emulation*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "pci.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
#include "vid_sdac_ramdac.h"
|
||||
|
||||
void s3_updatemapping();
|
||||
|
||||
void s3_accel_write(uint32_t addr, uint8_t val);
|
||||
void s3_accel_write_w(uint32_t addr, uint16_t val);
|
||||
void s3_accel_write_l(uint32_t addr, uint32_t val);
|
||||
uint8_t s3_accel_read(uint32_t addr);
|
||||
void s3_accel_write(uint32_t addr, uint8_t val, void *priv);
|
||||
void s3_accel_write_w(uint32_t addr, uint16_t val, void *priv);
|
||||
void s3_accel_write_l(uint32_t addr, uint32_t val, void *priv);
|
||||
uint8_t s3_accel_read(uint32_t addr, void *priv);
|
||||
|
||||
static uint8_t s3_bank;
|
||||
static uint8_t s3_ma_ext;
|
||||
|
|
@ -20,7 +22,7 @@ static int s3_bpp = 0;
|
|||
|
||||
static uint8_t s3_id, s3_id_ext;
|
||||
|
||||
void s3_out(uint16_t addr, uint8_t val)
|
||||
void s3_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old;
|
||||
|
||||
|
|
@ -40,7 +42,7 @@ void s3_out(uint16_t addr, uint8_t val)
|
|||
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
// pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc);
|
||||
sdac_ramdac_out(addr,val);
|
||||
sdac_ramdac_out(addr, val, NULL);
|
||||
return;
|
||||
|
||||
case 0x3D4:
|
||||
|
|
@ -141,13 +143,11 @@ void s3_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr,val);
|
||||
svga_out(addr, val, NULL);
|
||||
}
|
||||
|
||||
uint8_t s3_in(uint16_t addr)
|
||||
uint8_t s3_in(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
|
||||
// if (addr != 0x3da) pclog("S3 in %04X\n", addr);
|
||||
|
|
@ -155,7 +155,7 @@ uint8_t s3_in(uint16_t addr)
|
|||
{
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
// pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc);
|
||||
return sdac_ramdac_in(addr);
|
||||
return sdac_ramdac_in(addr, NULL);
|
||||
|
||||
case 0x3D4:
|
||||
return crtcreg;
|
||||
|
|
@ -174,7 +174,7 @@ uint8_t s3_in(uint16_t addr)
|
|||
}
|
||||
return crtc[crtcreg];
|
||||
}
|
||||
return svga_in(addr);
|
||||
return svga_in(addr, NULL);
|
||||
}
|
||||
|
||||
void s3_recalctimings()
|
||||
|
|
@ -182,7 +182,27 @@ void s3_recalctimings()
|
|||
// pclog("recalctimings\n");
|
||||
svga_ma |= (s3_ma_ext << 16);
|
||||
// pclog("SVGA_MA %08X\n", svga_ma);
|
||||
if (gdcreg[5] & 0x40) svga_lowres = !(crtc[0x3a] & 0x10);
|
||||
if ((gdcreg[5] & 0x40) && (crtc[0x3a] & 0x10))
|
||||
{
|
||||
switch (bpp)
|
||||
{
|
||||
case 8:
|
||||
svga_render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 15:
|
||||
svga_render = svga_render_15bpp_highres;
|
||||
break;
|
||||
case 16:
|
||||
svga_render = svga_render_16bpp_highres;
|
||||
break;
|
||||
case 24:
|
||||
svga_render = svga_render_24bpp_highres;
|
||||
break;
|
||||
case 32:
|
||||
svga_render = svga_render_32bpp_highres;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (crtc[0x5d] & 0x01) svga_htotal += 0x100;
|
||||
if (crtc[0x5d] & 0x02) svga_hdisp += 0x100;
|
||||
if (crtc[0x5e] & 0x01) svga_vtotal += 0x400;
|
||||
|
|
@ -201,25 +221,25 @@ void s3_recalctimings()
|
|||
static uint32_t s3_linear_base = 0, s3_linear_size = 0;
|
||||
void s3_updatemapping()
|
||||
{
|
||||
mem_removehandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear);
|
||||
mem_removehandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
|
||||
// video_write_a000_w = video_write_a000_l = NULL;
|
||||
|
||||
mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
// pclog("Update mapping - bank %02X ", gdcreg[6] & 0xc);
|
||||
switch (gdcreg[6] & 0xc) /*Banked framebuffer*/
|
||||
{
|
||||
case 0x0: /*128k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0x4: /*64k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0x8: /*32k at B0000*/
|
||||
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0xC: /*32k at B8000*/
|
||||
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -246,15 +266,15 @@ void s3_updatemapping()
|
|||
// pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]);
|
||||
// pclog("Linear framebuffer at %08X size %08X\n", linear_base, linear_size);
|
||||
if (s3_linear_base == 0xa0000)
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
else
|
||||
mem_sethandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear);
|
||||
mem_sethandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
}
|
||||
|
||||
// pclog("Memory mapped IO %02X\n", crtc[0x53] & 0x10);
|
||||
if (crtc[0x53] & 0x10) /*Memory mapped IO*/
|
||||
{
|
||||
mem_sethandler(0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l);
|
||||
mem_sethandler(0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, NULL);
|
||||
/* video_write_a000 = s3_accel_write;
|
||||
video_write_a000_w = s3_accel_write_w;
|
||||
video_write_a000_l = s3_accel_write_l;
|
||||
|
|
@ -299,7 +319,7 @@ struct
|
|||
|
||||
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat);
|
||||
|
||||
void s3_accel_out(uint16_t port, uint8_t val)
|
||||
void s3_accel_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("Accel out %04X %02X\n", port, val);
|
||||
switch (port)
|
||||
|
|
@ -503,7 +523,7 @@ void s3_accel_out(uint16_t port, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
void s3_accel_out_w(uint16_t port, uint16_t val)
|
||||
void s3_accel_out_w(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
// pclog("Accel out w %04X %04X\n", port, val);
|
||||
if (s3_accel.cmd & 0x100)
|
||||
|
|
@ -519,7 +539,7 @@ void s3_accel_out_w(uint16_t port, uint16_t val)
|
|||
}
|
||||
}
|
||||
|
||||
void s3_accel_out_l(uint16_t port, uint32_t val)
|
||||
void s3_accel_out_l(uint16_t port, uint32_t val, void *priv)
|
||||
{
|
||||
// pclog("Accel out l %04X %08X\n", port, val);
|
||||
if (s3_accel.cmd & 0x100)
|
||||
|
|
@ -563,7 +583,7 @@ void s3_accel_out_l(uint16_t port, uint32_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t s3_accel_in(uint16_t port)
|
||||
uint8_t s3_accel_in(uint16_t port, void *priv)
|
||||
{
|
||||
int temp;
|
||||
// pclog("Accel in %04X\n", port);
|
||||
|
|
@ -682,11 +702,11 @@ uint8_t s3_accel_in(uint16_t port)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void s3_accel_write(uint32_t addr, uint8_t val)
|
||||
void s3_accel_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("Write S3 accel %08X %02X\n", addr, val);
|
||||
if (addr & 0x8000)
|
||||
s3_accel_out(addr & 0xffff, val);
|
||||
s3_accel_out(addr & 0xffff, val, priv);
|
||||
else
|
||||
{
|
||||
if (s3_accel.cmd & 0x100)
|
||||
|
|
@ -699,13 +719,13 @@ void s3_accel_write(uint32_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
void s3_accel_write_w(uint32_t addr, uint16_t val)
|
||||
void s3_accel_write_w(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
// pclog("Write S3 accel w %08X %04X\n", addr, val);
|
||||
if (addr & 0x8000)
|
||||
{
|
||||
s3_accel_out( addr & 0xffff, val);
|
||||
s3_accel_out((addr & 0xffff) + 1, val >> 8);
|
||||
s3_accel_out( addr & 0xffff, val, priv);
|
||||
s3_accel_out((addr & 0xffff) + 1, val >> 8, priv);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -723,15 +743,15 @@ void s3_accel_write_w(uint32_t addr, uint16_t val)
|
|||
}
|
||||
}
|
||||
|
||||
void s3_accel_write_l(uint32_t addr, uint32_t val)
|
||||
void s3_accel_write_l(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
// pclog("Write S3 accel l %08X %08X\n", addr, val);
|
||||
if (addr & 0x8000)
|
||||
{
|
||||
s3_accel_out( addr & 0xffff, val);
|
||||
s3_accel_out((addr & 0xffff) + 1, val >> 8);
|
||||
s3_accel_out((addr & 0xffff) + 2, val >> 16);
|
||||
s3_accel_out((addr & 0xffff) + 3, val >> 24);
|
||||
s3_accel_out( addr & 0xffff, val, priv);
|
||||
s3_accel_out((addr & 0xffff) + 1, val >> 8, priv);
|
||||
s3_accel_out((addr & 0xffff) + 2, val >> 16, priv);
|
||||
s3_accel_out((addr & 0xffff) + 3, val >> 24, priv);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -777,11 +797,11 @@ void s3_accel_write_l(uint32_t addr, uint32_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t s3_accel_read(uint32_t addr)
|
||||
uint8_t s3_accel_read(uint32_t addr, void *priv)
|
||||
{
|
||||
// pclog("Read S3 accel %08X\n", addr);
|
||||
if (addr & 0x8000)
|
||||
return s3_accel_in(addr & 0xffff);
|
||||
return s3_accel_in(addr & 0xffff, priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -828,12 +848,8 @@ uint8_t s3_accel_read(uint32_t addr)
|
|||
|
||||
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat)
|
||||
{
|
||||
uint32_t dest, destbak;
|
||||
int sx, sy, cx, cy;
|
||||
int x, y;
|
||||
uint32_t src_dat, dest_dat;
|
||||
int frgd_mix, bkgd_mix;
|
||||
int mix;
|
||||
int clip_t = s3_accel.multifunc[1] & 0xfff;
|
||||
int clip_l = s3_accel.multifunc[2] & 0xfff;
|
||||
int clip_b = s3_accel.multifunc[3] & 0xfff;
|
||||
|
|
@ -1390,6 +1406,7 @@ void s3_hwcursor_draw(int displine)
|
|||
int xx;
|
||||
int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff;
|
||||
|
||||
pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y);
|
||||
for (x = 0; x < 64; x += 16)
|
||||
{
|
||||
dat[0] = (vram[svga_hwcursor_latch.addr] << 8) | vram[svga_hwcursor_latch.addr + 1];
|
||||
|
|
@ -1414,9 +1431,9 @@ void s3_hwcursor_draw(int displine)
|
|||
}
|
||||
|
||||
|
||||
uint8_t s3_pci_read(int func, int addr)
|
||||
uint8_t s3_pci_read(int func, int addr, void *priv)
|
||||
{
|
||||
pclog("S3 PCI read %08X\n", addr);
|
||||
// pclog("S3 PCI read %08X\n", addr);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x00: return 0x33; /*'S3'*/
|
||||
|
|
@ -1448,7 +1465,7 @@ uint8_t s3_pci_read(int func, int addr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void s3_pci_write(int func, int addr, uint8_t val)
|
||||
void s3_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
|
|
@ -1482,28 +1499,28 @@ int s3_init()
|
|||
|
||||
vrammask = 0x3fffff;
|
||||
|
||||
io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0xa2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0xa6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0xaae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0xaee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL);
|
||||
io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l);
|
||||
io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0xa2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0xa6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0xaae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0xaee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL);
|
||||
io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, NULL);
|
||||
|
||||
pci_add(s3_pci_read, s3_pci_write);
|
||||
pci_add(s3_pci_read, s3_pci_write, NULL);
|
||||
|
||||
svga_vram_limit = 4 << 20; /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/
|
||||
return svga_init();
|
||||
|
|
|
|||
|
|
@ -15,9 +15,8 @@ struct
|
|||
int rs2;
|
||||
} sdac_ramdac;
|
||||
|
||||
void sdac_ramdac_out(uint16_t addr, uint8_t val)
|
||||
void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int didwrite;
|
||||
// /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i\n",addr,val,sdac_ramdac.magic_count,CS,pc, sdac_ramdac.rs2);
|
||||
switch (addr)
|
||||
{
|
||||
|
|
@ -68,10 +67,10 @@ void sdac_ramdac_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr,val);
|
||||
svga_out(addr, val, NULL);
|
||||
}
|
||||
|
||||
uint8_t sdac_ramdac_in(uint16_t addr)
|
||||
uint8_t sdac_ramdac_in(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i\n",addr,CS,pc, sdac_ramdac.rs2);
|
||||
|
|
@ -128,7 +127,7 @@ uint8_t sdac_ramdac_in(uint16_t addr)
|
|||
}
|
||||
break;
|
||||
}
|
||||
return svga_in(addr);
|
||||
return svga_in(addr, NULL);
|
||||
}
|
||||
|
||||
float sdac_getclock(int clock)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
void sdac_ramdac_out(uint16_t addr, uint8_t val);
|
||||
uint8_t sdac_ramdac_in(uint16_t addr);
|
||||
void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t sdac_ramdac_in(uint16_t addr, void *priv);
|
||||
|
||||
float sdac_getclock(int clock);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ struct
|
|||
int stg_state_read[2][8]={{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}};
|
||||
int stg_state_write[8]={0,0,0,0,0,6,7,7};
|
||||
|
||||
void stg_ramdac_out(uint16_t addr, uint8_t val)
|
||||
void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int didwrite;
|
||||
//if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc);
|
||||
|
|
@ -64,10 +64,10 @@ void stg_ramdac_out(uint16_t addr, uint8_t val)
|
|||
stg_ramdac.magic_count=0;
|
||||
break;
|
||||
}
|
||||
svga_out(addr,val);
|
||||
svga_out(addr, val, NULL);
|
||||
}
|
||||
|
||||
uint8_t stg_ramdac_in(uint16_t addr)
|
||||
uint8_t stg_ramdac_in(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
//if (CS!=0xC000) pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc);
|
||||
|
|
@ -100,5 +100,5 @@ uint8_t stg_ramdac_in(uint16_t addr)
|
|||
stg_ramdac.magic_count=0;
|
||||
break;
|
||||
}
|
||||
return svga_in(addr);
|
||||
return svga_in(addr, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
void stg_ramdac_out(uint16_t addr, uint8_t val);
|
||||
uint8_t stg_ramdac_in(uint16_t addr);
|
||||
void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t stg_ramdac_in(uint16_t addr, void *priv);
|
||||
|
|
|
|||
612
src/vid_svga.c
612
src/vid_svga.c
|
|
@ -1,9 +1,14 @@
|
|||
/*Generic SVGA handling*/
|
||||
/*This is intended to be used by another SVGA driver, and not as a card in it's own right*/
|
||||
#include "ibm.h"
|
||||
#include "mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
#include "io.h"
|
||||
#include "timer.h"
|
||||
|
||||
#define svga_output 0
|
||||
|
||||
uint32_t svga_vram_limit;
|
||||
|
||||
|
|
@ -11,15 +16,19 @@ extern uint8_t edatlookup[4][4];
|
|||
uint8_t svga_miscout;
|
||||
|
||||
static uint8_t la, lb, lc, ld;
|
||||
static uint8_t svga_rotate[8][256];
|
||||
uint8_t svga_rotate[8][256];
|
||||
|
||||
static int svga_fast;
|
||||
|
||||
void svga_out(uint16_t addr, uint8_t val)
|
||||
void (*svga_render)();
|
||||
|
||||
static uint8_t dacmask, dacstatus;
|
||||
|
||||
void svga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int c;
|
||||
uint8_t o;
|
||||
//printf("OUT SVGA %03X %02X %04X:%04X %i %08X\n",addr,val,CS,pc,TRIDENT,svgawbank);
|
||||
// printf("OUT SVGA %03X %02X %04X:%04X %i %08X\n",addr,val,CS,pc,TRIDENT,svgawbank);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C0:
|
||||
|
|
@ -45,10 +54,16 @@ void svga_out(uint16_t addr, uint8_t val)
|
|||
svga_miscout = val;
|
||||
vres = 0; pallook = pallook256;
|
||||
vidclock = val & 4; printf("3C2 write %02X\n",val);
|
||||
if (val&1)
|
||||
io_sethandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL);
|
||||
if (val & 1)
|
||||
{
|
||||
pclog("Remove mono handler\n");
|
||||
io_removehandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL, NULL);
|
||||
}
|
||||
else
|
||||
io_sethandler(0x03a0, 0x0020, video_in_null, NULL, NULL, video_out_null, NULL, NULL);
|
||||
{
|
||||
pclog("Set mono handler\n");
|
||||
io_sethandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
case 0x3C4: seqaddr=val; break;
|
||||
case 0x3C5:
|
||||
|
|
@ -58,7 +73,12 @@ void svga_out(uint16_t addr, uint8_t val)
|
|||
if (o!=val && (seqaddr&0xF)==1) svga_recalctimings();
|
||||
switch (seqaddr&0xF)
|
||||
{
|
||||
case 1: if (scrblank && !(val&0x20)) fullchange=3; scrblank=(scrblank&~0x20)|(val&0x20); break;
|
||||
case 1:
|
||||
if (scrblank && !(val&0x20))
|
||||
fullchange=3;
|
||||
scrblank=(scrblank&~0x20)|(val&0x20);
|
||||
svga_recalctimings();
|
||||
break;
|
||||
case 2: writemask=val&0xF; break;
|
||||
case 3:
|
||||
charset=val&0xF;
|
||||
|
|
@ -71,9 +91,16 @@ void svga_out(uint16_t addr, uint8_t val)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 0x3c6: dacmask=val; break;
|
||||
case 0x3C7: dacread=val; dacpos=0; break;
|
||||
case 0x3C8: dacwrite=val; dacpos=0; break;
|
||||
case 0x3C9:
|
||||
dacstatus = 0;
|
||||
/* if (pc == 0x68AD)
|
||||
{
|
||||
dumpregs();
|
||||
exit(-1);
|
||||
}*/
|
||||
palchange=1;
|
||||
fullchange=changeframecount;
|
||||
switch (dacpos)
|
||||
|
|
@ -85,6 +112,7 @@ void svga_out(uint16_t addr, uint8_t val)
|
|||
break;
|
||||
case 0x3CE: gdcaddr=val; break;
|
||||
case 0x3CF:
|
||||
o = gdcreg[gdcaddr & 15];
|
||||
switch (gdcaddr&15)
|
||||
{
|
||||
case 2: colourcompare=val; break;
|
||||
|
|
@ -93,21 +121,21 @@ void svga_out(uint16_t addr, uint8_t val)
|
|||
case 6:
|
||||
if ((gdcreg[6] & 0xc) != (val & 0xc))
|
||||
{
|
||||
mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
// pclog("Write mapping %02X\n", val);
|
||||
mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
pclog("Write mapping %02X\n", val);
|
||||
switch (val&0xC)
|
||||
{
|
||||
case 0x0: /*128k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0x4: /*64k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0x8: /*32k at B0000*/
|
||||
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0xC: /*32k at B8000*/
|
||||
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -116,11 +144,13 @@ void svga_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
gdcreg[gdcaddr&15]=val;
|
||||
svga_fast = (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) && chain4;
|
||||
if (((gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((gdcaddr & 15) == 6 && (val ^ o) & 1))
|
||||
svga_recalctimings();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t svga_in(uint16_t addr)
|
||||
uint8_t svga_in(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// if (addr!=0x3da) pclog("Read port %04X\n",addr);
|
||||
|
|
@ -128,12 +158,20 @@ uint8_t svga_in(uint16_t addr)
|
|||
{
|
||||
case 0x3C0: return attraddr;
|
||||
case 0x3C1: return attrregs[attraddr];
|
||||
case 0x3C2: return 0x10;
|
||||
case 0x3c2:
|
||||
if ((vgapal[0].r + vgapal[0].g + vgapal[0].b) >= 0x50)
|
||||
temp = 0;
|
||||
else
|
||||
temp = 0x10;
|
||||
return temp;
|
||||
case 0x3C4: return seqaddr;
|
||||
case 0x3C5:
|
||||
return seqregs[seqaddr&0xF];
|
||||
case 0x3c6: return dacmask;
|
||||
case 0x3c7: return dacstatus;
|
||||
case 0x3C8: return dacwrite;
|
||||
case 0x3C9:
|
||||
dacstatus=3;
|
||||
palchange=1;
|
||||
switch (dacpos)
|
||||
{
|
||||
|
|
@ -156,8 +194,9 @@ uint8_t svga_in(uint16_t addr)
|
|||
}
|
||||
|
||||
int svga_vtotal, svga_dispend, svga_vsyncstart, svga_split;
|
||||
int svga_hdisp, svga_htotal, svga_rowoffset;
|
||||
int svga_hdisp, svga_htotal, svga_hdisp_time, svga_rowoffset;
|
||||
int svga_lowres, svga_interlace;
|
||||
int svga_linedbl, svga_rowcount;
|
||||
double svga_clock;
|
||||
uint32_t svga_ma;
|
||||
void (*svga_recalctimings_ex)() = NULL;
|
||||
|
|
@ -166,7 +205,8 @@ void (*svga_hwcursor_draw)(int displine) = NULL;
|
|||
void svga_recalctimings()
|
||||
{
|
||||
double crtcconst;
|
||||
int temp;
|
||||
double _dispontime, _dispofftime;
|
||||
|
||||
svga_vtotal=crtc[6];
|
||||
svga_dispend=crtc[0x12];
|
||||
svga_vsyncstart=crtc[0x10];
|
||||
|
|
@ -204,32 +244,131 @@ void svga_recalctimings()
|
|||
svga_interlace = 0;
|
||||
|
||||
svga_ma = (crtc[0xC]<<8)|crtc[0xD];
|
||||
|
||||
svga_hdisp_time = svga_hdisp;
|
||||
svga_render = svga_render_blank;
|
||||
if (!scrblank)
|
||||
{
|
||||
if (!(gdcreg[6]&1)) /*Text mode*/
|
||||
{
|
||||
if (seqregs[1]&8) /*40 column*/
|
||||
{
|
||||
svga_render = svga_render_text_40;
|
||||
svga_hdisp *= (seqregs[1] & 1) ? 16 : 18;
|
||||
}
|
||||
else
|
||||
{
|
||||
svga_render = svga_render_text_80;
|
||||
svga_hdisp *= (seqregs[1] & 1) ? 8 : 9;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
svga_hdisp *= (seqregs[1] & 8) ? 16 : 8;
|
||||
|
||||
switch (gdcreg[5]&0x60)
|
||||
{
|
||||
case 0x00: /*16 colours*/
|
||||
if (seqregs[1]&8) /*Low res (320)*/
|
||||
svga_render = svga_render_4bpp_lowres;
|
||||
else
|
||||
svga_render = svga_render_4bpp_highres;
|
||||
break;
|
||||
case 0x20: /*4 colours*/
|
||||
svga_render = svga_render_2bpp_lowres;
|
||||
break;
|
||||
case 0x40: case 0x60: /*256+ colours*/
|
||||
switch (bpp)
|
||||
{
|
||||
case 8:
|
||||
if (svga_lowres)
|
||||
svga_render = svga_render_8bpp_lowres;
|
||||
else
|
||||
{
|
||||
svga_render = svga_render_8bpp_highres;
|
||||
// svga_hdisp <<= 1;
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
if (svga_lowres)
|
||||
svga_render = svga_render_15bpp_lowres;
|
||||
else
|
||||
{
|
||||
svga_render = svga_render_15bpp_highres;
|
||||
svga_hdisp <<= 1;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (svga_lowres)
|
||||
svga_render = svga_render_16bpp_lowres;
|
||||
else
|
||||
{
|
||||
svga_render = svga_render_16bpp_highres;
|
||||
svga_hdisp <<= 1;
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
if (svga_lowres)
|
||||
{
|
||||
svga_render = svga_render_24bpp_lowres;
|
||||
svga_hdisp = ((svga_hdisp<<3)/3);
|
||||
}
|
||||
else
|
||||
{
|
||||
svga_render = svga_render_24bpp_highres;
|
||||
svga_hdisp = ((svga_hdisp<<3)/3);
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
if (svga_lowres)
|
||||
svga_render = svga_render_32bpp_lowres;
|
||||
else
|
||||
{
|
||||
svga_render = svga_render_32bpp_highres;
|
||||
svga_hdisp <<= 1;
|
||||
}
|
||||
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);
|
||||
|
||||
svga_linedbl = crtc[9] & 0x80;
|
||||
svga_rowcount = crtc[9] & 31;
|
||||
if (svga_recalctimings_ex) svga_recalctimings_ex();
|
||||
|
||||
crtcconst=(seqregs[1]&1)?(svga_clock*8.0):(svga_clock*9.0);
|
||||
|
||||
disptime =svga_htotal;
|
||||
dispontime=svga_hdisp;
|
||||
|
||||
_dispontime = svga_hdisp_time;
|
||||
|
||||
// printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8);
|
||||
if (seqregs[1]&8) { disptime*=2; dispontime*=2; }
|
||||
dispofftime=disptime-dispontime;
|
||||
dispontime*=crtcconst;
|
||||
dispofftime*=crtcconst;
|
||||
if (seqregs[1]&8) { disptime*=2; _dispontime*=2; }
|
||||
_dispofftime=disptime-_dispontime;
|
||||
_dispontime*=crtcconst;
|
||||
_dispofftime*=crtcconst;
|
||||
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
// printf("SVGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4));
|
||||
// printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga_vtotal,svga_dispend,(crtc[9]&31)+1,svga_vsyncstart);
|
||||
// printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*svga_vtotal,(dispontime+dispofftime)*svga_vtotal*70,seqregs[1]);
|
||||
|
||||
// pclog("svga_render %08X\n", svga_render);
|
||||
}
|
||||
|
||||
void (*svga_render)();
|
||||
|
||||
static uint32_t ma,maback,ca;
|
||||
static int vc,sc;
|
||||
static int linepos, displine, vslines, linecountff, oddeven;
|
||||
uint32_t ma, maback, ca;
|
||||
static int vc;
|
||||
int sc;
|
||||
static int linepos, vslines, linecountff, oddeven;
|
||||
static int svga_dispon;
|
||||
static int con, coff, cursoron, cgablink;
|
||||
static int scrollcache;
|
||||
int con, coff, cursoron, cgablink;
|
||||
int scrollcache;
|
||||
|
||||
int svga_hwcursor_on;
|
||||
|
||||
|
|
@ -237,17 +376,13 @@ SVGA_HWCURSOR svga_hwcursor, svga_hwcursor_latch;
|
|||
|
||||
int svga_hdisp_on;
|
||||
|
||||
static int firstline_draw = 2000, lastline_draw = 0;
|
||||
int firstline_draw = 2000, lastline_draw = 0;
|
||||
int displine;
|
||||
|
||||
void svga_poll()
|
||||
{
|
||||
uint8_t chr,dat,attr;
|
||||
uint32_t charaddr;
|
||||
int x,xx;
|
||||
uint32_t fg,bg;
|
||||
int offset;
|
||||
uint8_t edat[4];
|
||||
int drawcursor=0;
|
||||
int x;
|
||||
|
||||
if (!linepos)
|
||||
{
|
||||
// if (!(vc & 15)) pclog("VC %i %i\n", vc, GetTickCount());
|
||||
|
|
@ -264,305 +399,17 @@ void svga_poll()
|
|||
|
||||
ma&=vrammask;
|
||||
if (firstline==2000) firstline=displine;
|
||||
if (scrblank)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
for (x=0;x<svga_hdisp;x++)
|
||||
{
|
||||
switch (seqregs[1]&9)
|
||||
{
|
||||
case 0:
|
||||
for (xx=0;xx<9;xx++) ((uint32_t *)buffer32->line[displine])[(x*9)+xx+32]=0;
|
||||
break;
|
||||
case 1:
|
||||
for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[(x*8)+xx+32]=0;
|
||||
break;
|
||||
case 8:
|
||||
for (xx=0;xx<18;xx++) ((uint32_t *)buffer32->line[displine])[(x*18)+xx+32]=0;
|
||||
break;
|
||||
case 9:
|
||||
for (xx=0;xx<16;xx++) ((uint32_t *)buffer32->line[displine])[(x*16)+xx+32]=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(gdcreg[6]&1)) /*Text mode*/
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (fullchange)
|
||||
{
|
||||
for (x=0;x<svga_hdisp;x++)
|
||||
{
|
||||
drawcursor=((ma==ca) && con && cursoron);
|
||||
chr=vram[(ma<<1)];
|
||||
attr=vram[(ma<<1)+4];
|
||||
if (attr&8) charaddr=charsetb+(chr*128);
|
||||
else charaddr=charseta+(chr*128);
|
||||
|
||||
if (drawcursor) { bg=pallook[egapal[attr&15]]; fg=pallook[egapal[attr>>4]]; }
|
||||
else
|
||||
{
|
||||
fg=pallook[egapal[attr&15]];
|
||||
bg=pallook[egapal[attr>>4]];
|
||||
if (attr&0x80 && attrregs[0x10]&8)
|
||||
{
|
||||
bg=pallook[egapal[(attr>>4)&7]];
|
||||
if (cgablink&16) fg=bg;
|
||||
}
|
||||
}
|
||||
|
||||
dat=vram[charaddr+(sc<<2)];
|
||||
if (seqregs[1]&8) /*40 column*/
|
||||
{
|
||||
if (seqregs[1]&1) { for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x<<4)+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[((x<<4)+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; }
|
||||
else
|
||||
{
|
||||
for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x*18)+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg;
|
||||
if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) ((uint32_t *)buffer32->line[displine])[((x*18)+32+16)&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+32+17)&2047]=bg;
|
||||
else ((uint32_t *)buffer32->line[displine])[((x*18)+32+16)&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+32+17)&2047]=(dat&1)?fg:bg;
|
||||
}
|
||||
}
|
||||
else /*80 column*/
|
||||
{
|
||||
if (seqregs[1]&1) { for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x<<3)+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; }
|
||||
else
|
||||
{
|
||||
for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x*9)+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg;
|
||||
if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) ((uint32_t *)buffer32->line[displine])[((x*9)+32+8)&2047]=bg;
|
||||
else ((uint32_t *)buffer32->line[displine])[((x*9)+32+8)&2047]=(dat&1)?fg:bg;
|
||||
}
|
||||
}
|
||||
ma+=4; ma&=vrammask;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if (hwcursor_on) changedvram[ma>>10]=changedvram[(ma>>10)+1]=2;
|
||||
switch (gdcreg[5]&0x60)
|
||||
{
|
||||
case 0x00: /*16 colours*/
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (seqregs[1]&8) /*Low res (320)*/
|
||||
{
|
||||
offset=((8-scrollcache)<<1)+16;
|
||||
for (x=0;x<=svga_hdisp;x++)
|
||||
{
|
||||
edat[0]=vram[ma];
|
||||
edat[1]=vram[ma|0x1];
|
||||
edat[2]=vram[ma|0x2];
|
||||
edat[3]=vram[ma|0x3];
|
||||
ma+=4; ma&=vrammask;
|
||||
|
||||
dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+14+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+15+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+12+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+13+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+10+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+11+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+8+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+9+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+7+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+5+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+3+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+1+offset]=pallook[egapal[dat>>4]];
|
||||
}
|
||||
}
|
||||
else /*High res (640)*/
|
||||
{
|
||||
offset=(8-scrollcache)+24;
|
||||
for (x=0;x<=svga_hdisp;x++)
|
||||
{
|
||||
edat[0]=vram[ma];
|
||||
edat[1]=vram[ma|0x1];
|
||||
edat[2]=vram[ma|0x2];
|
||||
edat[3]=vram[ma|0x3];
|
||||
ma+=4; ma&=vrammask;
|
||||
|
||||
dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+7+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+6+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+5+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+4+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+3+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+2+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+1+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+offset]= pallook[egapal[dat>>4]];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x20: /*4 colours*/
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
offset=((8-scrollcache)<<1)+16;
|
||||
/*Low res (320) only, though high res (640) should be possible*/
|
||||
for (x=0;x<=svga_hdisp;x++)
|
||||
{
|
||||
if (sc&1 && !(crtc[0x17]&1))
|
||||
{
|
||||
edat[0]=vram[(ma<<1)+0x8000];
|
||||
edat[1]=vram[(ma<<1)+0x8004];
|
||||
}
|
||||
else
|
||||
{
|
||||
edat[0]=vram[(ma<<1)];
|
||||
edat[1]=vram[(ma<<1)+4];
|
||||
}
|
||||
ma+=4; ma&=vrammask;
|
||||
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+14+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+15+offset]=pallook[egapal[edat[1]&3]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+12+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+13+offset]=pallook[egapal[(edat[1]>>2)&3]];
|
||||
dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+10+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+11+offset]=pallook[egapal[(edat[1]>>4)&3]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+8+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+9+offset]=pallook[egapal[(edat[1]>>6)&3]];
|
||||
dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+7+offset]=pallook[egapal[(edat[0]>>0)&3]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+5+offset]=pallook[egapal[(edat[0]>>2)&3]];
|
||||
dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+3+offset]=pallook[egapal[(edat[0]>>4)&3]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<4)+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+1+offset]=pallook[egapal[(edat[0]>>6)&3]];
|
||||
}
|
||||
break;
|
||||
case 0x40: case 0x60: /*256 colours (and more, with high/true colour RAMDAC)*/
|
||||
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga_lowres) /*Low res (320)*/
|
||||
{
|
||||
// if (!displine) pclog("Lo res %i %i %i\n",bpp,svga_hdisp,(svga_hdisp<<3)/3);
|
||||
offset=(8-(scrollcache&6))+24;
|
||||
if (bpp==8) /*Regular 8 bpp palette mode*/
|
||||
{
|
||||
for (x=0;x<=svga_hdisp;x++)
|
||||
{
|
||||
edat[0]=vram[ma];
|
||||
edat[1]=vram[ma|0x1];
|
||||
edat[2]=vram[ma|0x2];
|
||||
edat[3]=vram[ma|0x3];
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+7+offset]=pallook[edat[3]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+5+offset]=pallook[edat[2]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+3+offset]=pallook[edat[1]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<3)+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+1+offset]=pallook[edat[0]];
|
||||
}
|
||||
}
|
||||
else if (bpp==16) /*16 bpp 565 mode*/
|
||||
{
|
||||
for (x=0;x<=svga_hdisp;x++)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma|0x1]<<8);
|
||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[(x<<2)+2+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+3+offset]=((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<2)+0+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+1+offset]=((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19);
|
||||
}
|
||||
}
|
||||
else if (bpp==15) /*15 bpp 555 mode*/
|
||||
{
|
||||
for (x=0;x<=svga_hdisp;x++)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma|0x1]<<8);
|
||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[(x<<1)+2+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+3+offset]=((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<1)+0+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+1+offset]=((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19);
|
||||
}
|
||||
}
|
||||
else if (bpp==24) /*24 bpp 888 mode*/
|
||||
{
|
||||
for (x=0;x<=((svga_hdisp<<3)/3);x++)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
|
||||
ma+=3; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[(x<<1)+offset]=((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=fg;
|
||||
}
|
||||
}
|
||||
else if (bpp==32) /*32 bpp 8888 mode*/
|
||||
{
|
||||
for (x = 0; x <= svga_hdisp; x++)
|
||||
{
|
||||
fg = vram[ma] | (vram[ma + 1] << 8) | (vram[ma + 2] << 16);
|
||||
ma += 4; ma &= vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[displine])[(x << 1) + 1 + offset] = fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /*High res (SVGA only)*/
|
||||
{
|
||||
// if (!displine) pclog("Hi res %i %i %i\n",bpp,svga_hdisp,(svga_hdisp<<3)/3);
|
||||
offset=(8-((scrollcache&6)>>1))+24;
|
||||
if (bpp==8)
|
||||
{
|
||||
for (x=0;x<=(svga_hdisp<<1);x++)
|
||||
{
|
||||
edat[0]=vram[ma];
|
||||
edat[1]=vram[ma|0x1];
|
||||
edat[2]=vram[ma|0x2];
|
||||
edat[3]=vram[ma|0x3];
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[(x<<2)+3+offset]=pallook[edat[3]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<2)+2+offset]=pallook[edat[2]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<2)+1+offset]=pallook[edat[1]];
|
||||
((uint32_t *)buffer32->line[displine])[(x<<2)+offset]= pallook[edat[0]];
|
||||
}
|
||||
}
|
||||
else if (bpp==16)
|
||||
{
|
||||
for (x=0;x<=(svga_hdisp<<1);x++)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma|0x1]<<8);
|
||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<1)+0+offset]=((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19);
|
||||
}
|
||||
}
|
||||
else if (bpp==15)
|
||||
{
|
||||
for (x=0;x<=(svga_hdisp<<1);x++)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma|0x1]<<8);
|
||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19);
|
||||
((uint32_t *)buffer32->line[displine])[(x<<1)+0+offset]=((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19);
|
||||
}
|
||||
}
|
||||
else if (bpp==24)
|
||||
{
|
||||
for (x=0;x<=((svga_hdisp<<3)/3);x++)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
|
||||
ma+=3; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[x+offset]=fg;
|
||||
}
|
||||
}
|
||||
else if (bpp==32)
|
||||
{
|
||||
for (x = 0; x <= (svga_hdisp<<2); x++)
|
||||
{
|
||||
fg = vram[ma] | (vram[ma + 1] << 8) | (vram[ma + 2] << 16);
|
||||
ma += 4; ma &= vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[x + offset] = fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (svga_hwcursor_on) changedvram[ma >> 10] = changedvram[(ma >> 10) + 1] = 2;
|
||||
|
||||
svga_render();
|
||||
|
||||
if (svga_hwcursor_on)
|
||||
{
|
||||
svga_hwcursor_draw(displine);
|
||||
svga_hwcursor_on--;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastline<displine) lastline=displine;
|
||||
}
|
||||
|
||||
|
|
@ -592,12 +439,12 @@ void svga_poll()
|
|||
if (sc==(crtc[11]&31)) con = 0;
|
||||
if (svga_dispon)
|
||||
{
|
||||
if ((crtc[9]&0x80) && !linecountff)
|
||||
if (svga_linedbl && !linecountff)
|
||||
{
|
||||
linecountff=1;
|
||||
ma=maback;
|
||||
}
|
||||
else if (sc==(crtc[9]&31))
|
||||
else if (sc == svga_rowcount)
|
||||
{
|
||||
linecountff=0;
|
||||
sc=0;
|
||||
|
|
@ -642,11 +489,11 @@ void svga_poll()
|
|||
// pclog("VC vsync %i %i\n", firstline_draw, lastline_draw);
|
||||
svga_dispon=0;
|
||||
cgastat|=8;
|
||||
if (seqregs[1]&8) x=svga_hdisp*((seqregs[1]&1)?8:9)*2;
|
||||
else x=svga_hdisp*((seqregs[1]&1)?8:9);
|
||||
/*if (seqregs[1]&8) x=(svga_hdisp*((seqregs[1]&1)?8:9))*2;
|
||||
else */x = svga_hdisp;//*((seqregs[1]&1)?8:9);
|
||||
|
||||
if (bpp == 16 || bpp == 15) x /= 2;
|
||||
if (bpp == 24) x /= 3;
|
||||
// if (bpp == 24) x /= 3;
|
||||
if (bpp == 32) x /= 4;
|
||||
if (svga_interlace && !oddeven) lastline++;
|
||||
if (svga_interlace && oddeven) firstline--;
|
||||
|
|
@ -704,7 +551,7 @@ void svga_poll()
|
|||
case 0x40: case 0x60: video_bpp = bpp; break;
|
||||
}
|
||||
}
|
||||
|
||||
video_bpp = bpp;
|
||||
// if (svga_interlace && oddeven) ma=maback=ma+(svga_rowoffset<<2);
|
||||
|
||||
// pclog("Addr %08X vson %03X vsoff %01X %02X %02X %02X %i %i\n",ma,svga_vsyncstart,crtc[0x11]&0xF,crtc[0xD],crtc[0xC],crtc[0x33], svga_interlace, oddeven);
|
||||
|
|
@ -751,20 +598,17 @@ int svga_init()
|
|||
|
||||
#define egacycles 1
|
||||
#define egacycles2 1
|
||||
void svga_write(uint32_t addr, uint8_t val)
|
||||
void svga_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int x,y;
|
||||
char s[2]={0,0};
|
||||
uint8_t vala,valb,valc,vald,wm=writemask;
|
||||
int writemask2 = writemask;
|
||||
int bankaddr;
|
||||
|
||||
egawrites++;
|
||||
|
||||
cycles -= video_timing_b;
|
||||
cycles_lost += video_timing_b;
|
||||
|
||||
// pclog("Writeega %06X ",addr);
|
||||
if (svga_output) pclog("Writeega %06X ",addr);
|
||||
if (addr>=0xB0000) addr&=0x7FFF;
|
||||
else
|
||||
{
|
||||
|
|
@ -783,8 +627,8 @@ void svga_write(uint32_t addr, uint8_t val)
|
|||
{
|
||||
addr<<=2;
|
||||
}
|
||||
// pclog("%08X %02X %i %i %i\n", addr, val, writemask2, writemode, chain4);
|
||||
addr&=0x7FFFFF;
|
||||
if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i\n", addr, addr & 1023, addr >> 10, val, writemask2, writemode, chain4);
|
||||
changedvram[addr>>10]=changeframecount;
|
||||
|
||||
switch (writemode)
|
||||
|
|
@ -929,10 +773,9 @@ void svga_write(uint32_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t svga_read(uint32_t addr)
|
||||
uint8_t svga_read(uint32_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp,temp2,temp3,temp4;
|
||||
uint32_t addr2;
|
||||
|
||||
cycles -= video_timing_b;
|
||||
cycles_lost += video_timing_b;
|
||||
|
|
@ -985,20 +828,17 @@ uint8_t svga_read(uint32_t addr)
|
|||
return vram[addr|readplane];
|
||||
}
|
||||
|
||||
void svga_write_linear(uint32_t addr, uint8_t val)
|
||||
void svga_write_linear(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int x,y;
|
||||
char s[2]={0,0};
|
||||
uint8_t vala,valb,valc,vald,wm=writemask;
|
||||
int writemask2 = writemask;
|
||||
int bankaddr;
|
||||
|
||||
cycles -= video_timing_b;
|
||||
cycles_lost += video_timing_b;
|
||||
|
||||
egawrites++;
|
||||
|
||||
// pclog("Write LFB %08X %02X ", addr, val);
|
||||
if (svga_output) pclog("Write LFB %08X %02X ", addr, val);
|
||||
if (!(gdcreg[6]&1)) fullchange=2;
|
||||
if (chain4)
|
||||
{
|
||||
|
|
@ -1010,7 +850,7 @@ void svga_write_linear(uint32_t addr, uint8_t val)
|
|||
addr<<=2;
|
||||
}
|
||||
addr &= 0x7fffff;
|
||||
// pclog("%08X\n", addr);
|
||||
if (svga_output) pclog("%08X\n", addr);
|
||||
changedvram[addr>>10]=changeframecount;
|
||||
|
||||
switch (writemode)
|
||||
|
|
@ -1155,7 +995,7 @@ void svga_write_linear(uint32_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t svga_read_linear(uint32_t addr)
|
||||
uint8_t svga_read_linear(uint32_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp,temp2,temp3,temp4;
|
||||
|
||||
|
|
@ -1220,8 +1060,16 @@ void svga_doblit(int y1, int y2)
|
|||
ysize=wy+1;
|
||||
if (xsize<64) xsize=656;
|
||||
if (ysize<32) ysize=200;
|
||||
if (vres) updatewindowsize(xsize,ysize<<1);
|
||||
else updatewindowsize(xsize,ysize);
|
||||
/* if (bpp > 8)
|
||||
{
|
||||
if (vres) updatewindowsize(xsize<<1,ysize<<1);
|
||||
else updatewindowsize(xsize<<1,ysize);
|
||||
}
|
||||
else
|
||||
{*/
|
||||
if (vres) updatewindowsize(xsize,ysize<<1);
|
||||
else updatewindowsize(xsize,ysize);
|
||||
// }
|
||||
}
|
||||
if (vid_resize)
|
||||
{
|
||||
|
|
@ -1234,12 +1082,12 @@ void svga_doblit(int y1, int y2)
|
|||
|
||||
}
|
||||
|
||||
void svga_writew(uint32_t addr, uint16_t val)
|
||||
void svga_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
if (!svga_fast)
|
||||
{
|
||||
svga_write(addr, val);
|
||||
svga_write(addr + 1, val >> 8);
|
||||
svga_write(addr, val, priv);
|
||||
svga_write(addr + 1, val >> 8, priv);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1248,22 +1096,22 @@ void svga_writew(uint32_t addr, uint16_t val)
|
|||
cycles -= video_timing_w;
|
||||
cycles_lost += video_timing_w;
|
||||
|
||||
// pclog("Writew %05X ", addr);
|
||||
if (svga_output) pclog("Writew %05X ", addr);
|
||||
addr = (addr & 0xffff) + svgawbank;
|
||||
addr &= 0x7FFFFF;
|
||||
// pclog("%08X %04X\n", addr, val);
|
||||
if (svga_output) pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val);
|
||||
changedvram[addr >> 10] = changeframecount;
|
||||
*(uint16_t *)&vram[addr] = val;
|
||||
}
|
||||
|
||||
void svga_writel(uint32_t addr, uint32_t val)
|
||||
void svga_writel(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
if (!svga_fast)
|
||||
{
|
||||
svga_write(addr, val);
|
||||
svga_write(addr + 1, val >> 8);
|
||||
svga_write(addr + 2, val >> 16);
|
||||
svga_write(addr + 3, val >> 24);
|
||||
svga_write(addr, val, priv);
|
||||
svga_write(addr + 1, val >> 8, priv);
|
||||
svga_write(addr + 2, val >> 16, priv);
|
||||
svga_write(addr + 3, val >> 24, priv);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1272,19 +1120,19 @@ void svga_writel(uint32_t addr, uint32_t val)
|
|||
cycles -= video_timing_l;
|
||||
cycles_lost += video_timing_l;
|
||||
|
||||
// pclog("Writel %05X ", addr);
|
||||
if (svga_output) pclog("Writel %05X ", addr);
|
||||
addr = (addr & 0xffff) + svgawbank;
|
||||
addr &= 0x7FFFFF;
|
||||
// pclog("%08X %08X\n", addr, val);
|
||||
if (svga_output) pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val);
|
||||
|
||||
changedvram[addr >> 10] = changeframecount;
|
||||
*(uint32_t *)&vram[addr] = val;
|
||||
}
|
||||
|
||||
uint16_t svga_readw(uint32_t addr)
|
||||
uint16_t svga_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
if (!svga_fast)
|
||||
return svga_read(addr) | (svga_read(addr + 1) << 8);
|
||||
return svga_read(addr, priv) | (svga_read(addr + 1, priv) << 8);
|
||||
|
||||
egareads += 2;
|
||||
|
||||
|
|
@ -1300,10 +1148,10 @@ uint16_t svga_readw(uint32_t addr)
|
|||
return *(uint16_t *)&vram[addr];
|
||||
}
|
||||
|
||||
uint32_t svga_readl(uint32_t addr)
|
||||
uint32_t svga_readl(uint32_t addr, void *priv)
|
||||
{
|
||||
if (!svga_fast)
|
||||
return svga_read(addr) | (svga_read(addr + 1) << 8) | (svga_read(addr + 2) << 16) | (svga_read(addr + 3) << 24);
|
||||
return svga_read(addr, priv) | (svga_read(addr + 1, priv) << 8) | (svga_read(addr + 2, priv) << 16) | (svga_read(addr + 3, priv) << 24);
|
||||
|
||||
egareads += 4;
|
||||
|
||||
|
|
@ -1319,12 +1167,12 @@ uint32_t svga_readl(uint32_t addr)
|
|||
return *(uint32_t *)&vram[addr];
|
||||
}
|
||||
|
||||
void svga_writew_linear(uint32_t addr, uint16_t val)
|
||||
void svga_writew_linear(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
if (!svga_fast)
|
||||
{
|
||||
svga_write_linear(addr, val);
|
||||
svga_write_linear(addr + 1, val >> 8);
|
||||
svga_write_linear(addr, val, priv);
|
||||
svga_write_linear(addr + 1, val >> 8, priv);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1333,19 +1181,20 @@ void svga_writew_linear(uint32_t addr, uint16_t val)
|
|||
cycles -= video_timing_w;
|
||||
cycles_lost += video_timing_w;
|
||||
|
||||
if (svga_output) pclog("Write LFBw %08X %04X\n", addr, val);
|
||||
addr &= 0x7FFFFF;
|
||||
changedvram[addr >> 10] = changeframecount;
|
||||
*(uint16_t *)&vram[addr] = val;
|
||||
}
|
||||
|
||||
void svga_writel_linear(uint32_t addr, uint32_t val)
|
||||
void svga_writel_linear(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
if (!svga_fast)
|
||||
{
|
||||
svga_write_linear(addr, val);
|
||||
svga_write_linear(addr + 1, val >> 8);
|
||||
svga_write_linear(addr + 2, val >> 16);
|
||||
svga_write_linear(addr + 3, val >> 24);
|
||||
svga_write_linear(addr, val, priv);
|
||||
svga_write_linear(addr + 1, val >> 8, priv);
|
||||
svga_write_linear(addr + 2, val >> 16, priv);
|
||||
svga_write_linear(addr + 3, val >> 24, priv);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1354,15 +1203,16 @@ void svga_writel_linear(uint32_t addr, uint32_t val)
|
|||
cycles -= video_timing_l;
|
||||
cycles_lost += video_timing_l;
|
||||
|
||||
if (svga_output) pclog("Write LFBl %08X %08X\n", addr, val);
|
||||
addr &= 0x7fffff;
|
||||
changedvram[addr >> 10] = changeframecount;
|
||||
*(uint32_t *)&vram[addr] = val;
|
||||
}
|
||||
|
||||
uint16_t svga_readw_linear(uint32_t addr)
|
||||
uint16_t svga_readw_linear(uint32_t addr, void *priv)
|
||||
{
|
||||
if (!svga_fast)
|
||||
return svga_read_linear(addr) | (svga_read_linear(addr + 1) << 8);
|
||||
return svga_read_linear(addr, priv) | (svga_read_linear(addr + 1, priv) << 8);
|
||||
|
||||
egareads += 2;
|
||||
|
||||
|
|
@ -1375,10 +1225,10 @@ uint16_t svga_readw_linear(uint32_t addr)
|
|||
return *(uint16_t *)&vram[addr];
|
||||
}
|
||||
|
||||
uint32_t svga_readl_linear(uint32_t addr)
|
||||
uint32_t svga_readl_linear(uint32_t addr, void *priv)
|
||||
{
|
||||
if (!svga_fast)
|
||||
return svga_read_linear(addr) | (svga_read_linear(addr + 1) << 8) | (svga_read_linear(addr + 2) << 16) | (svga_read_linear(addr + 3) << 24);
|
||||
return svga_read_linear(addr, priv) | (svga_read_linear(addr + 1, priv) << 8) | (svga_read_linear(addr + 2, priv) << 16) | (svga_read_linear(addr + 3, priv) << 24);
|
||||
|
||||
egareads += 4;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
/*Vertical timings*/
|
||||
extern int svga_vtotal, svga_dispend, svga_vsyncstart, svga_split;
|
||||
/*Horizontal timings*/
|
||||
extern int svga_hdisp, svga_htotal, svga_rowoffset;
|
||||
extern int svga_hdisp, svga_htotal, svga_hdisp_time, svga_rowoffset;
|
||||
/*Flags - svga_lowres = 1/2 clock in 256+ colour modes, svga_interlace = interlace mode enabled*/
|
||||
extern int svga_lowres, svga_interlace;
|
||||
|
||||
extern int svga_linedbl, svga_rowcount;
|
||||
|
||||
/*Status of display on*/
|
||||
extern int svga_hdisp_on;
|
||||
|
||||
|
|
@ -35,19 +37,24 @@ extern SVGA_HWCURSOR svga_hwcursor, svga_hwcursor_latch;
|
|||
extern int svga_hwcursor_on;
|
||||
extern void (*svga_hwcursor_draw)(int displine);
|
||||
|
||||
uint8_t svga_read(uint32_t addr);
|
||||
uint16_t svga_readw(uint32_t addr);
|
||||
uint32_t svga_readl(uint32_t addr);
|
||||
void svga_write(uint32_t addr, uint8_t val);
|
||||
void svga_writew(uint32_t addr, uint16_t val);
|
||||
void svga_writel(uint32_t addr, uint32_t val);
|
||||
uint8_t svga_read_linear(uint32_t addr);
|
||||
uint16_t svga_readw_linear(uint32_t addr);
|
||||
uint32_t svga_readl_linear(uint32_t addr);
|
||||
void svga_write_linear(uint32_t addr, uint8_t val);
|
||||
void svga_writew_linear(uint32_t addr, uint16_t val);
|
||||
void svga_writel_linear(uint32_t addr, uint32_t val);
|
||||
uint8_t svga_read(uint32_t addr, void *priv);
|
||||
uint16_t svga_readw(uint32_t addr, void *priv);
|
||||
uint32_t svga_readl(uint32_t addr, void *priv);
|
||||
void svga_write(uint32_t addr, uint8_t val, void *priv);
|
||||
void svga_writew(uint32_t addr, uint16_t val, void *priv);
|
||||
void svga_writel(uint32_t addr, uint32_t val, void *priv);
|
||||
uint8_t svga_read_linear(uint32_t addr, void *priv);
|
||||
uint16_t svga_readw_linear(uint32_t addr, void *priv);
|
||||
uint32_t svga_readl_linear(uint32_t addr, void *priv);
|
||||
void svga_write_linear(uint32_t addr, uint8_t val, void *priv);
|
||||
void svga_writew_linear(uint32_t addr, uint16_t val, void *priv);
|
||||
void svga_writel_linear(uint32_t addr, uint32_t val, void *priv);
|
||||
|
||||
void svga_doblit(int y1, int y2);
|
||||
|
||||
extern uint32_t svga_vram_limit;
|
||||
|
||||
extern uint8_t svga_rotate[8][256];
|
||||
|
||||
void svga_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t svga_in(uint16_t addr, void *priv);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "video.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
|
||||
static int tandy_array_index;
|
||||
static uint8_t tandy_array[32];
|
||||
|
|
@ -14,7 +15,7 @@ static uint8_t *tandy_vram, *tandy_b8000;
|
|||
void tandy_recalcaddress();
|
||||
void tandy_recalctimings();
|
||||
|
||||
void tandy_out(uint16_t addr, uint8_t val)
|
||||
void tandy_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old;
|
||||
// pclog("Tandy OUT %04X %02X\n",addr,val);
|
||||
|
|
@ -59,7 +60,7 @@ void tandy_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t tandy_in(uint16_t addr)
|
||||
uint8_t tandy_in(uint16_t addr, void *priv)
|
||||
{
|
||||
// if (addr!=0x3DA) pclog("Tandy IN %04X\n",addr);
|
||||
switch (addr)
|
||||
|
|
@ -90,14 +91,14 @@ void tandy_recalcaddress()
|
|||
}
|
||||
}
|
||||
|
||||
void tandy_write(uint32_t addr, uint8_t val)
|
||||
void tandy_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (tandy_memctrl==-1) return;
|
||||
// pclog("Tandy VRAM write %05X %02X %04X:%04X %04X:%04X\n",addr,val,CS,pc,DS,SI);
|
||||
tandy_b8000[addr&0x7FFF]=val;
|
||||
}
|
||||
|
||||
uint8_t tandy_read(uint32_t addr)
|
||||
uint8_t tandy_read(uint32_t addr, void *priv)
|
||||
{
|
||||
if (tandy_memctrl==-1) return 0xFF;
|
||||
// pclog("Tandy VRAM read %05X %02X %04X:%04X\n",addr,tandy_b8000[addr&0x7FFF],CS,pc);
|
||||
|
|
@ -106,19 +107,22 @@ uint8_t tandy_read(uint32_t addr)
|
|||
|
||||
void tandy_recalctimings()
|
||||
{
|
||||
double _dispontime, _dispofftime;
|
||||
if (tandy_mode&1)
|
||||
{
|
||||
disptime=crtc[0]+1;
|
||||
dispontime=crtc[1];
|
||||
_dispontime=crtc[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
disptime=(crtc[0]+1)<<1;
|
||||
dispontime=crtc[1]<<1;
|
||||
_dispontime=crtc[1]<<1;
|
||||
}
|
||||
dispofftime=disptime-dispontime;
|
||||
dispontime*=CGACONST;
|
||||
dispofftime*=CGACONST;
|
||||
_dispofftime=disptime-_dispontime;
|
||||
_dispontime*=CGACONST;
|
||||
_dispofftime*=CGACONST;
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -127,7 +131,7 @@ static int sc,vc;
|
|||
static int cgadispon;
|
||||
static int con,coff,cursoron,cgablink;
|
||||
static int vsynctime,vadj;
|
||||
static uint16_t ma,maback,ca;
|
||||
static uint16_t ma,maback;
|
||||
|
||||
static int ntsc_col[8][8]=
|
||||
{
|
||||
|
|
@ -157,7 +161,7 @@ void tandy_poll()
|
|||
int x,c;
|
||||
int oldvc;
|
||||
uint8_t chr,attr;
|
||||
uint16_t dat,dat2,dat3,dat4;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
|
|
@ -582,8 +586,8 @@ void tandy_poll()
|
|||
|
||||
int tandy_init()
|
||||
{
|
||||
mem_sethandler(0xb8000, 0x8000, tandy_read, NULL, NULL, tandy_write, NULL, NULL);
|
||||
io_sethandler(0x00a0, 0x0002, tandy_in, NULL, NULL, tandy_out, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x8000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x00a0, 0x0002, tandy_in, NULL, NULL, tandy_out, NULL, NULL, NULL);
|
||||
tandy_memctrl = -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
static int tkd8001_state=0;
|
||||
static uint8_t tkd8001_ctrl;
|
||||
|
||||
void tkd8001_ramdac_out(uint16_t addr, uint8_t val)
|
||||
void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("OUT RAMDAC %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
switch (addr)
|
||||
|
|
@ -40,10 +40,10 @@ void tkd8001_ramdac_out(uint16_t addr, uint8_t val)
|
|||
tkd8001_state = 0;
|
||||
break;
|
||||
}
|
||||
svga_out(addr,val);
|
||||
svga_out(addr, val, NULL);
|
||||
}
|
||||
|
||||
uint8_t tkd8001_ramdac_in(uint16_t addr)
|
||||
uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv)
|
||||
{
|
||||
// pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc);
|
||||
switch (addr)
|
||||
|
|
@ -60,5 +60,5 @@ uint8_t tkd8001_ramdac_in(uint16_t addr)
|
|||
tkd8001_state = 0;
|
||||
break;
|
||||
}
|
||||
return svga_in(addr);
|
||||
return svga_in(addr, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
void tkd8001_ramdac_out(uint16_t addr, uint8_t val);
|
||||
uint8_t tkd8001_ramdac_in(uint16_t addr);
|
||||
void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv);
|
||||
|
|
|
|||
809
src/vid_tvga.c
809
src/vid_tvga.c
|
|
@ -1,18 +1,37 @@
|
|||
/*Trident TVGA (8900D) emulation*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
#include "vid_tkd8001_ramdac.h"
|
||||
|
||||
void tvga_recalcmapping();
|
||||
|
||||
uint8_t trident3d8,trident3d9;
|
||||
int tridentoldmode;
|
||||
uint8_t tridentoldctrl2,tridentnewctrl2;
|
||||
uint8_t tridentdac;
|
||||
|
||||
void tvga_out(uint16_t addr, uint8_t val)
|
||||
uint32_t tvga_linear_base, tvga_linear_size;
|
||||
|
||||
uint8_t tvga_accel_read(uint32_t addr, void *priv);
|
||||
uint16_t tvga_accel_read_w(uint32_t addr, void *priv);
|
||||
uint32_t tvga_accel_read_l(uint32_t addr, void *priv);
|
||||
|
||||
void tvga_accel_write(uint32_t addr, uint8_t val, void *priv);
|
||||
void tvga_accel_write_w(uint32_t addr, uint16_t val, void *priv);
|
||||
void tvga_accel_write_l(uint32_t addr, uint32_t val, void *priv);
|
||||
|
||||
|
||||
void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv);
|
||||
|
||||
void tvga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old;
|
||||
|
||||
// pclog("tvga_out : %04X %02X %04X:%04X %i\n", addr, val, CS,pc, bpp);
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
|
|
@ -32,12 +51,24 @@ void tvga_out(uint16_t addr, uint8_t val)
|
|||
break;
|
||||
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
tkd8001_ramdac_out(addr,val);
|
||||
return;
|
||||
if (gfxcard != GFX_TGUI9440)
|
||||
{
|
||||
tkd8001_ramdac_out(addr, val, NULL);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3CF:
|
||||
switch (gdcaddr&15)
|
||||
{
|
||||
case 0x6:
|
||||
if (gdcreg[6] != val)
|
||||
{
|
||||
gdcreg[6] = val;
|
||||
tvga_recalcmapping();
|
||||
}
|
||||
return;
|
||||
|
||||
case 0xE:
|
||||
gdcreg[0xE]=val^2;
|
||||
if ((gdcreg[0xF]&1)==1)
|
||||
|
|
@ -51,7 +82,8 @@ void tvga_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
break;
|
||||
case 0x3D4:
|
||||
crtcreg=val&63;
|
||||
if (gfxcard == GFX_TGUI9440) crtcreg = val & 0x7f;
|
||||
else crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
||||
|
|
@ -66,6 +98,37 @@ void tvga_out(uint16_t addr, uint8_t val)
|
|||
svga_recalctimings();
|
||||
}
|
||||
}
|
||||
switch (crtcreg)
|
||||
{
|
||||
case 0x21:
|
||||
if (old != val)
|
||||
tvga_recalcmapping();
|
||||
break;
|
||||
|
||||
|
||||
case 0x38: /*Pixel bus register*/
|
||||
// pclog("Pixel bus register %02X\n", val);
|
||||
if (gfxcard != GFX_TGUI9440)
|
||||
break;
|
||||
|
||||
if ((val & 0xc) == 4) bpp = 16;
|
||||
else if (!(val & 0xc)) bpp = 8;
|
||||
else bpp = 24;
|
||||
break;
|
||||
|
||||
case 0x40: case 0x41: case 0x42: case 0x43:
|
||||
case 0x44: case 0x45: case 0x46: case 0x47:
|
||||
svga_hwcursor.x = (crtc[0x40] | (crtc[0x41] << 8)) & 0x7ff;
|
||||
svga_hwcursor.y = (crtc[0x42] | (crtc[0x43] << 8)) & 0x7ff;
|
||||
svga_hwcursor.xoff = crtc[0x46] & 0x3f;
|
||||
svga_hwcursor.yoff = crtc[0x47] & 0x3f;
|
||||
svga_hwcursor.addr = (crtc[0x44] << 10) | ((crtc[0x45] & 0x7) << 18) | (svga_hwcursor.yoff * 8);
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
svga_hwcursor.ena = val & 0x80;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case 0x3D8:
|
||||
trident3d8=val;
|
||||
|
|
@ -89,12 +152,12 @@ void tvga_out(uint16_t addr, uint8_t val)
|
|||
}
|
||||
return;
|
||||
}
|
||||
svga_out(addr,val);
|
||||
svga_out(addr, val, priv);
|
||||
}
|
||||
|
||||
uint8_t tvga_in(uint16_t addr)
|
||||
uint8_t tvga_in(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// if (addr != 0x3da) pclog("tvga_in : %04X %04X:%04X\n", addr, CS,pc);
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
|
||||
|
|
@ -105,7 +168,8 @@ uint8_t tvga_in(uint16_t addr)
|
|||
{
|
||||
// printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP));
|
||||
tridentoldmode=0;
|
||||
return 0x33; /*TVGA8900D*/
|
||||
if (gfxcard == GFX_TVGA) return 0x33; /*TVGA8900D*/
|
||||
else return 0xe3; /*TGUI9440AGi*/
|
||||
}
|
||||
if ((seqaddr&0xF)==0xC)
|
||||
{
|
||||
|
|
@ -119,15 +183,21 @@ uint8_t tvga_in(uint16_t addr)
|
|||
}
|
||||
break;
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
return tkd8001_ramdac_in(addr);
|
||||
if (gfxcard != GFX_TGUI9440)
|
||||
return tkd8001_ramdac_in(addr, NULL);
|
||||
break;
|
||||
case 0x3CD: /*Banking*/
|
||||
return svgaseg;
|
||||
case 0x3D4:
|
||||
return crtcreg;
|
||||
case 0x3D5:
|
||||
return crtc[crtcreg];
|
||||
case 0x3d8:
|
||||
return trident3d8;
|
||||
case 0x3d9:
|
||||
return trident3d9;
|
||||
}
|
||||
return svga_in(addr);
|
||||
return svga_in(addr, priv);
|
||||
}
|
||||
|
||||
void tvga_recalctimings()
|
||||
|
|
@ -147,7 +217,9 @@ void tvga_recalctimings()
|
|||
}
|
||||
if (tridentoldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/
|
||||
svga_lowres=0;
|
||||
|
||||
if (gfxcard == GFX_TGUI9440)
|
||||
svga_lowres = !(crtc[0x2a] & 0x40);
|
||||
|
||||
if (gdcreg[0xF] & 8)
|
||||
{
|
||||
svga_htotal<<=1;
|
||||
|
|
@ -166,16 +238,703 @@ void tvga_recalctimings()
|
|||
case 6: svga_clock = cpuclock/50350000.0; break;
|
||||
case 7: svga_clock = cpuclock/40000000.0; break;
|
||||
}
|
||||
|
||||
if ((tridentoldctrl2 & 0x10) || (gfxcard == GFX_TGUI9440 && (crtc[0x2a] & 0x40)))
|
||||
{
|
||||
switch (bpp)
|
||||
{
|
||||
case 8:
|
||||
svga_render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 15:
|
||||
svga_render = svga_render_15bpp_highres;
|
||||
break;
|
||||
case 16:
|
||||
svga_render = svga_render_16bpp_highres;
|
||||
break;
|
||||
case 24:
|
||||
svga_render = svga_render_24bpp_highres;
|
||||
break;
|
||||
case 32:
|
||||
svga_render = svga_render_32bpp_highres;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tvga_recalcmapping()
|
||||
{
|
||||
pclog("tvga_recalcmapping : %02X %02X\n", crtc[0x21], gdcreg[6]);
|
||||
mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
mem_removehandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL, NULL);
|
||||
|
||||
if (crtc[0x21] & 0x20)
|
||||
{
|
||||
tvga_linear_base = ((crtc[0x21] & 0xf) | ((crtc[0x21] >> 2) & 0x30)) << 20;
|
||||
tvga_linear_size = (crtc[0x21] & 0x10) ? 0x200000 : 0x100000;
|
||||
mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
pclog("Trident linear framebuffer at %08X - size %06X\n", tvga_linear_base, tvga_linear_size);
|
||||
mem_sethandler(0xbc000, 0x4000, tvga_accel_read, tvga_accel_read_w, tvga_accel_read_l, tvga_accel_write, tvga_accel_write_w, tvga_accel_write_l, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("Write mapping %02X\n", val);
|
||||
switch (gdcreg[6] & 0xC)
|
||||
{
|
||||
case 0x0: /*128k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0x4: /*64k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
mem_sethandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL, NULL);
|
||||
break;
|
||||
case 0x8: /*32k at B0000*/
|
||||
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
case 0xC: /*32k at B8000*/
|
||||
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tvga_hwcursor_draw(int displine)
|
||||
{
|
||||
// int x;
|
||||
uint32_t dat[2];
|
||||
int xx;
|
||||
int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff;
|
||||
|
||||
// pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y);
|
||||
// for (x = 0; x < 32; x += 32)
|
||||
// {
|
||||
dat[0] = (vram[svga_hwcursor_latch.addr] << 24) | (vram[svga_hwcursor_latch.addr + 1] << 16) | (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3];
|
||||
dat[1] = (vram[svga_hwcursor_latch.addr + 4] << 24) | (vram[svga_hwcursor_latch.addr + 5] << 16) | (vram[svga_hwcursor_latch.addr + 6] << 8) | vram[svga_hwcursor_latch.addr + 7];
|
||||
for (xx = 0; xx < 32; xx++)
|
||||
{
|
||||
if (offset >= svga_hwcursor_latch.x)
|
||||
{
|
||||
if (!(dat[0] & 0x80000000))
|
||||
((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x80000000) ? 0xffffff : 0;
|
||||
else if (dat[1] & 0x80000000)
|
||||
((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff;
|
||||
// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]);
|
||||
}
|
||||
|
||||
offset++;
|
||||
dat[0] <<= 1;
|
||||
dat[1] <<= 1;
|
||||
}
|
||||
svga_hwcursor_latch.addr += 8;
|
||||
// }
|
||||
}
|
||||
|
||||
int tvga_init()
|
||||
{
|
||||
svga_recalctimings_ex = tvga_recalctimings;
|
||||
svga_vram_limit = 1 << 20; /*1mb - chip supports 2mb, but drivers are buggy*/
|
||||
vrammask = 0xfffff;
|
||||
svga_hwcursor_draw = tvga_hwcursor_draw;
|
||||
if (gfxcard == GFX_TVGA)
|
||||
{
|
||||
vrammask = 0xfffff;
|
||||
svga_vram_limit = 1 << 20; /*1mb - chip supports 2mb, but drivers are buggy*/
|
||||
}
|
||||
else
|
||||
{
|
||||
vrammask = 0x1fffff;
|
||||
svga_vram_limit = 1 << 21; /*2mb*/
|
||||
}
|
||||
return svga_init();
|
||||
}
|
||||
|
||||
struct tvga_accel
|
||||
{
|
||||
uint16_t src_x, src_y;
|
||||
uint16_t dst_x, dst_y;
|
||||
uint16_t size_x, size_y;
|
||||
uint16_t fg_col, bg_col;
|
||||
uint8_t rop;
|
||||
uint16_t flags;
|
||||
uint8_t pattern[0x80];
|
||||
int command;
|
||||
int offset;
|
||||
uint8_t ger22;
|
||||
|
||||
int x, y;
|
||||
uint32_t src, dst, src_old, dst_old;
|
||||
int pat_x, pat_y;
|
||||
int use_src;
|
||||
|
||||
int pitch, bpp;
|
||||
} tvga_accel;
|
||||
|
||||
enum
|
||||
{
|
||||
TGUI_BITBLT = 1
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TGUI_SRCCPU = 0,
|
||||
|
||||
TGUI_SRCDISP = 0x04, /*Source is from display*/
|
||||
TGUI_PATMONO = 0x20, /*Pattern is monochrome and needs expansion*/
|
||||
TGUI_SRCMONO = 0x40, /*Source is monochrome from CPU and needs expansion*/
|
||||
TGUI_TRANSENA = 0x1000, /*Transparent (no draw when source == bg col)*/
|
||||
TGUI_TRANSREV = 0x2000, /*Reverse fg/bg for transparent*/
|
||||
TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/
|
||||
};
|
||||
|
||||
#define READ(addr, dat) if (tvga_accel.bpp == 0) dat = vram[addr & 0x1fffff]; \
|
||||
else dat = vram_w[addr & 0xfffff];
|
||||
|
||||
#define MIX() do \
|
||||
{ \
|
||||
out = 0; \
|
||||
for (c=0;c<16;c++) \
|
||||
{ \
|
||||
d=(dst_dat & (1<<c)) ? 1:0; \
|
||||
if (src_dat & (1<<c)) d|=2; \
|
||||
if (pat_dat & (1<<c)) d|=4; \
|
||||
if (tvga_accel.rop & (1<<d)) out|=(1<<c); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WRITE(addr, dat) if (tvga_accel.bpp == 0) \
|
||||
{ \
|
||||
vram[addr & 0x1fffff] = dat; \
|
||||
changedvram[((addr) & 0x1fffff) >> 10] = changeframecount; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
vram_w[addr & 0xfffff] = dat; \
|
||||
changedvram[((addr) & 0xfffff) >> 9] = changeframecount; \
|
||||
}
|
||||
|
||||
static uint16_t tvga_pattern[8][8];
|
||||
|
||||
void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv);
|
||||
void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv);
|
||||
|
||||
void tvga_accel_command(int count, uint32_t cpu_dat)
|
||||
{
|
||||
int x, y;
|
||||
int c, d;
|
||||
uint16_t src_dat, dst_dat, pat_dat;
|
||||
uint16_t out;
|
||||
int xdir = (tvga_accel.flags & 0x200) ? -1 : 1;
|
||||
int ydir = (tvga_accel.flags & 0x100) ? -1 : 1;
|
||||
uint16_t trans_col = (tvga_accel.flags & TGUI_TRANSREV) ? tvga_accel.fg_col : tvga_accel.bg_col;
|
||||
uint16_t *vram_w = (uint16_t *)vram;
|
||||
|
||||
if (tvga_accel.bpp == 0)
|
||||
trans_col &= 0xff;
|
||||
|
||||
if (count != -1 && !tvga_accel.x)
|
||||
{
|
||||
count -= tvga_accel.offset;
|
||||
cpu_dat <<= tvga_accel.offset;
|
||||
}
|
||||
if (count == -1)
|
||||
{
|
||||
tvga_accel.x = tvga_accel.y = 0;
|
||||
}
|
||||
if (tvga_accel.flags & TGUI_SOLIDFILL)
|
||||
{
|
||||
// pclog("SOLIDFILL\n");
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
for (x = 0; x < 8; x++)
|
||||
{
|
||||
tvga_pattern[y][x] = tvga_accel.fg_col;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tvga_accel.flags & TGUI_PATMONO)
|
||||
{
|
||||
// pclog("PATMONO\n");
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
for (x = 0; x < 8; x++)
|
||||
{
|
||||
tvga_pattern[y][x] = (tvga_accel.pattern[y] & (1 << x)) ? tvga_accel.fg_col : tvga_accel.bg_col;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("OTHER\n");
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
for (x = 0; x < 8; x++)
|
||||
{
|
||||
tvga_pattern[y][x] = tvga_accel.pattern[x + y*8];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, tvga_pattern[y][0], tvga_pattern[y][1], tvga_pattern[y][2], tvga_pattern[y][3], tvga_pattern[y][4], tvga_pattern[y][5], tvga_pattern[y][6], tvga_pattern[y][7]);
|
||||
}
|
||||
if (count == -1) pclog("Command %i %i\n", tvga_accel.command, TGUI_BITBLT);
|
||||
switch (tvga_accel.command)
|
||||
{
|
||||
case TGUI_BITBLT:
|
||||
if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tvga_accel.src_x, tvga_accel.src_y, tvga_accel.dst_x, tvga_accel.dst_y, tvga_accel.size_x, tvga_accel.size_y, tvga_accel.flags);
|
||||
if (count == -1)
|
||||
{
|
||||
tvga_accel.src = tvga_accel.src_old = tvga_accel.src_x + (tvga_accel.src_y * tvga_accel.pitch);
|
||||
tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_x + (tvga_accel.dst_y * tvga_accel.pitch);
|
||||
tvga_accel.pat_x = tvga_accel.dst_x;
|
||||
tvga_accel.pat_y = tvga_accel.dst_y;
|
||||
}
|
||||
|
||||
switch (tvga_accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP))
|
||||
{
|
||||
case TGUI_SRCCPU:
|
||||
if (count == -1)
|
||||
{
|
||||
// pclog("Blit start\n");
|
||||
if (crtc[0x21] & 0x20)
|
||||
{
|
||||
mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL);
|
||||
}
|
||||
if (tvga_accel.use_src)
|
||||
return;
|
||||
}
|
||||
else
|
||||
count >>= 3;
|
||||
while (count)
|
||||
{
|
||||
if (tvga_accel.bpp == 0)
|
||||
{
|
||||
src_dat = cpu_dat >> 24;
|
||||
cpu_dat <<= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00);
|
||||
cpu_dat <<= 16;
|
||||
count--;
|
||||
}
|
||||
READ(tvga_accel.dst, dst_dat);
|
||||
pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7];
|
||||
|
||||
if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
|
||||
{
|
||||
MIX();
|
||||
|
||||
WRITE(tvga_accel.dst, out);
|
||||
}
|
||||
|
||||
// pclog(" %i,%i %02X %02X %02X %02X\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out);
|
||||
|
||||
tvga_accel.src += xdir;
|
||||
tvga_accel.dst += xdir;
|
||||
tvga_accel.pat_x += xdir;
|
||||
|
||||
tvga_accel.x++;
|
||||
if (tvga_accel.x > tvga_accel.size_x)
|
||||
{
|
||||
tvga_accel.x = 0;
|
||||
tvga_accel.y++;
|
||||
|
||||
tvga_accel.pat_x = tvga_accel.dst_x;
|
||||
|
||||
tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch);
|
||||
tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch);
|
||||
tvga_accel.pat_y += ydir;
|
||||
|
||||
if (tvga_accel.y > tvga_accel.size_y)
|
||||
{
|
||||
if (crtc[0x21] & 0x20)
|
||||
{
|
||||
// pclog("Blit end\n");
|
||||
mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL);
|
||||
mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (tvga_accel.use_src)
|
||||
return;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
break;
|
||||
|
||||
case TGUI_SRCMONO | TGUI_SRCCPU:
|
||||
if (count == -1)
|
||||
{
|
||||
// pclog("Blit start\n");
|
||||
if (crtc[0x21] & 0x20)
|
||||
{
|
||||
mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL);
|
||||
}
|
||||
if (tvga_accel.use_src)
|
||||
return;
|
||||
}
|
||||
// pclog("TGUI_SRCMONO | TGUI_SRCCPU\n");
|
||||
while (count)
|
||||
{
|
||||
src_dat = ((cpu_dat >> 31) ? tvga_accel.fg_col : tvga_accel.bg_col);
|
||||
if (tvga_accel.bpp == 0)
|
||||
src_dat &= 0xff;
|
||||
|
||||
READ(tvga_accel.dst, dst_dat);
|
||||
pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7];
|
||||
|
||||
if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
|
||||
{
|
||||
MIX();
|
||||
|
||||
WRITE(tvga_accel.dst, out);
|
||||
}
|
||||
// pclog(" %i,%i %02X %02X %02X %02X %i\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out, (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col));
|
||||
cpu_dat <<= 1;
|
||||
tvga_accel.src += xdir;
|
||||
tvga_accel.dst += xdir;
|
||||
tvga_accel.pat_x += xdir;
|
||||
|
||||
tvga_accel.x++;
|
||||
if (tvga_accel.x > tvga_accel.size_x)
|
||||
{
|
||||
tvga_accel.x = 0;
|
||||
tvga_accel.y++;
|
||||
|
||||
tvga_accel.pat_x = tvga_accel.dst_x;
|
||||
|
||||
tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch);
|
||||
tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch);
|
||||
tvga_accel.pat_y += ydir;
|
||||
|
||||
if (tvga_accel.y > tvga_accel.size_y)
|
||||
{
|
||||
if (crtc[0x21] & 0x20)
|
||||
{
|
||||
// pclog("Blit end\n");
|
||||
mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL);
|
||||
mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (tvga_accel.use_src)
|
||||
return;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
while (count)
|
||||
{
|
||||
READ(tvga_accel.src, src_dat);
|
||||
READ(tvga_accel.dst, dst_dat);
|
||||
pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7];
|
||||
|
||||
if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
|
||||
{
|
||||
MIX();
|
||||
|
||||
WRITE(tvga_accel.dst, out);
|
||||
}
|
||||
// pclog(" %i,%i %02X %02X %02X %02X\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out);
|
||||
|
||||
tvga_accel.src += xdir;
|
||||
tvga_accel.dst += xdir;
|
||||
tvga_accel.pat_x += xdir;
|
||||
|
||||
tvga_accel.x++;
|
||||
if (tvga_accel.x > tvga_accel.size_x)
|
||||
{
|
||||
tvga_accel.x = 0;
|
||||
tvga_accel.y++;
|
||||
|
||||
tvga_accel.pat_x = tvga_accel.dst_x;
|
||||
|
||||
tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch);
|
||||
tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch);
|
||||
tvga_accel.pat_y += ydir;
|
||||
|
||||
if (tvga_accel.y > tvga_accel.size_y)
|
||||
return;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void tvga_accel_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
pclog("tvga_accel_write : %08X %02X %04X(%08X):%08X %02X\n", addr, val, CS,cs,pc, opcode);
|
||||
if ((addr & ~0xff) != 0xbff00)
|
||||
return;
|
||||
switch (addr & 0xff)
|
||||
{
|
||||
case 0x22:
|
||||
tvga_accel.ger22 = val;
|
||||
tvga_accel.pitch = 512 << ((val >> 2) & 3);
|
||||
tvga_accel.bpp = (val & 3) ? 1 : 0;
|
||||
tvga_accel.pitch >>= tvga_accel.bpp;
|
||||
break;
|
||||
|
||||
case 0x24: /*Command*/
|
||||
tvga_accel.command = val;
|
||||
tvga_accel_command(-1, 0);
|
||||
break;
|
||||
|
||||
case 0x27: /*ROP*/
|
||||
tvga_accel.rop = val;
|
||||
tvga_accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33);
|
||||
pclog("Write ROP %02X %i\n", val, tvga_accel.use_src);
|
||||
break;
|
||||
|
||||
case 0x28: /*Flags*/
|
||||
tvga_accel.flags = (tvga_accel.flags & 0xff00) | val;
|
||||
break;
|
||||
case 0x29: /*Flags*/
|
||||
tvga_accel.flags = (tvga_accel.flags & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x2b:
|
||||
tvga_accel.offset = val & 7;
|
||||
break;
|
||||
|
||||
case 0x2c: /*Foreground colour*/
|
||||
tvga_accel.fg_col = (tvga_accel.fg_col & 0xff00) | val;
|
||||
break;
|
||||
case 0x2d: /*Foreground colour*/
|
||||
tvga_accel.fg_col = (tvga_accel.fg_col & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x30: /*Background colour*/
|
||||
tvga_accel.bg_col = (tvga_accel.bg_col & 0xff00) | val;
|
||||
break;
|
||||
case 0x31: /*Background colour*/
|
||||
tvga_accel.bg_col = (tvga_accel.bg_col & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x38: /*Dest X*/
|
||||
tvga_accel.dst_x = (tvga_accel.dst_x & 0xff00) | val;
|
||||
break;
|
||||
case 0x39: /*Dest X*/
|
||||
tvga_accel.dst_x = (tvga_accel.dst_x & 0xff) | (val << 8);
|
||||
break;
|
||||
case 0x3a: /*Dest Y*/
|
||||
tvga_accel.dst_y = (tvga_accel.dst_y & 0xff00) | val;
|
||||
break;
|
||||
case 0x3b: /*Dest Y*/
|
||||
tvga_accel.dst_y = (tvga_accel.dst_y & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x3c: /*Src X*/
|
||||
tvga_accel.src_x = (tvga_accel.src_x & 0xff00) | val;
|
||||
break;
|
||||
case 0x3d: /*Src X*/
|
||||
tvga_accel.src_x = (tvga_accel.src_x & 0xff) | (val << 8);
|
||||
break;
|
||||
case 0x3e: /*Src Y*/
|
||||
tvga_accel.src_y = (tvga_accel.src_y & 0xff00) | val;
|
||||
break;
|
||||
case 0x3f: /*Src Y*/
|
||||
tvga_accel.src_y = (tvga_accel.src_y & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x40: /*Size X*/
|
||||
tvga_accel.size_x = (tvga_accel.size_x & 0xff00) | val;
|
||||
break;
|
||||
case 0x41: /*Size X*/
|
||||
tvga_accel.size_x = (tvga_accel.size_x & 0xff) | (val << 8);
|
||||
break;
|
||||
case 0x42: /*Size Y*/
|
||||
tvga_accel.size_y = (tvga_accel.size_y & 0xff00) | val;
|
||||
break;
|
||||
case 0x43: /*Size Y*/
|
||||
tvga_accel.size_y = (tvga_accel.size_y & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x80: case 0x81: case 0x82: case 0x83:
|
||||
case 0x84: case 0x85: case 0x86: case 0x87:
|
||||
case 0x88: case 0x89: case 0x8a: case 0x8b:
|
||||
case 0x8c: case 0x8d: case 0x8e: case 0x8f:
|
||||
case 0x90: case 0x91: case 0x92: case 0x93:
|
||||
case 0x94: case 0x95: case 0x96: case 0x97:
|
||||
case 0x98: case 0x99: case 0x9a: case 0x9b:
|
||||
case 0x9c: case 0x9d: case 0x9e: case 0x9f:
|
||||
case 0xa0: case 0xa1: case 0xa2: case 0xa3:
|
||||
case 0xa4: case 0xa5: case 0xa6: case 0xa7:
|
||||
case 0xa8: case 0xa9: case 0xaa: case 0xab:
|
||||
case 0xac: case 0xad: case 0xae: case 0xaf:
|
||||
case 0xb0: case 0xb1: case 0xb2: case 0xb3:
|
||||
case 0xb4: case 0xb5: case 0xb6: case 0xb7:
|
||||
case 0xb8: case 0xb9: case 0xba: case 0xbb:
|
||||
case 0xbc: case 0xbd: case 0xbe: case 0xbf:
|
||||
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
|
||||
case 0xc4: case 0xc5: case 0xc6: case 0xc7:
|
||||
case 0xc8: case 0xc9: case 0xca: case 0xcb:
|
||||
case 0xcc: case 0xcd: case 0xce: case 0xcf:
|
||||
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||
case 0xd4: case 0xd5: case 0xd6: case 0xd7:
|
||||
case 0xd8: case 0xd9: case 0xda: case 0xdb:
|
||||
case 0xdc: case 0xdd: case 0xde: case 0xdf:
|
||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
|
||||
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
||||
case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
||||
case 0xec: case 0xed: case 0xee: case 0xef:
|
||||
case 0xf0: case 0xf1: case 0xf2: case 0xf3:
|
||||
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
|
||||
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
|
||||
case 0xfc: case 0xfd: case 0xfe: case 0xff:
|
||||
tvga_accel.pattern[addr & 0x7f] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void tvga_accel_write_w(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
pclog("tvga_accel_write_w %08X %04X\n", addr, val);
|
||||
tvga_accel_write(addr, val, NULL);
|
||||
tvga_accel_write(addr + 1, val >> 8, NULL);
|
||||
}
|
||||
|
||||
void tvga_accel_write_l(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
pclog("tvga_accel_write_l %08X %08X\n", addr, val);
|
||||
tvga_accel_write(addr, val, NULL);
|
||||
tvga_accel_write(addr + 1, val >> 8, NULL);
|
||||
tvga_accel_write(addr + 2, val >> 16, NULL);
|
||||
tvga_accel_write(addr + 3, val >> 24, NULL);
|
||||
}
|
||||
|
||||
uint8_t tvga_accel_read(uint32_t addr, void *priv)
|
||||
{
|
||||
// pclog("tvga_accel_read : %08X\n", addr);
|
||||
if ((addr & ~0xff) != 0xbff00)
|
||||
return 0xff;
|
||||
switch (addr & 0xff)
|
||||
{
|
||||
case 0x20: /*Status*/
|
||||
return 0;
|
||||
|
||||
case 0x27: /*ROP*/
|
||||
return tvga_accel.rop;
|
||||
|
||||
case 0x28: /*Flags*/
|
||||
return tvga_accel.flags & 0xff;
|
||||
case 0x29: /*Flags*/
|
||||
return tvga_accel.flags >> 8;
|
||||
|
||||
case 0x2b:
|
||||
return tvga_accel.offset;
|
||||
|
||||
case 0x2c: /*Background colour*/
|
||||
return tvga_accel.bg_col & 0xff;
|
||||
case 0x2d: /*Background colour*/
|
||||
return tvga_accel.bg_col >> 8;
|
||||
|
||||
case 0x30: /*Foreground colour*/
|
||||
return tvga_accel.fg_col & 0xff;
|
||||
case 0x31: /*Foreground colour*/
|
||||
return tvga_accel.fg_col >> 8;
|
||||
|
||||
case 0x38: /*Dest X*/
|
||||
return tvga_accel.dst_x & 0xff;
|
||||
case 0x39: /*Dest X*/
|
||||
return tvga_accel.dst_x >> 8;
|
||||
case 0x3a: /*Dest Y*/
|
||||
return tvga_accel.dst_y & 0xff;
|
||||
case 0x3b: /*Dest Y*/
|
||||
return tvga_accel.dst_y >> 8;
|
||||
|
||||
case 0x3c: /*Src X*/
|
||||
return tvga_accel.src_x & 0xff;
|
||||
case 0x3d: /*Src X*/
|
||||
return tvga_accel.src_x >> 8;
|
||||
case 0x3e: /*Src Y*/
|
||||
return tvga_accel.src_y & 0xff;
|
||||
case 0x3f: /*Src Y*/
|
||||
return tvga_accel.src_y >> 8;
|
||||
|
||||
case 0x40: /*Size X*/
|
||||
return tvga_accel.size_x & 0xff;
|
||||
case 0x41: /*Size X*/
|
||||
return tvga_accel.size_x >> 8;
|
||||
case 0x42: /*Size Y*/
|
||||
return tvga_accel.size_y & 0xff;
|
||||
case 0x43: /*Size Y*/
|
||||
return tvga_accel.size_y >> 8;
|
||||
|
||||
case 0x80: case 0x81: case 0x82: case 0x83:
|
||||
case 0x84: case 0x85: case 0x86: case 0x87:
|
||||
case 0x88: case 0x89: case 0x8a: case 0x8b:
|
||||
case 0x8c: case 0x8d: case 0x8e: case 0x8f:
|
||||
case 0x90: case 0x91: case 0x92: case 0x93:
|
||||
case 0x94: case 0x95: case 0x96: case 0x97:
|
||||
case 0x98: case 0x99: case 0x9a: case 0x9b:
|
||||
case 0x9c: case 0x9d: case 0x9e: case 0x9f:
|
||||
case 0xa0: case 0xa1: case 0xa2: case 0xa3:
|
||||
case 0xa4: case 0xa5: case 0xa6: case 0xa7:
|
||||
case 0xa8: case 0xa9: case 0xaa: case 0xab:
|
||||
case 0xac: case 0xad: case 0xae: case 0xaf:
|
||||
case 0xb0: case 0xb1: case 0xb2: case 0xb3:
|
||||
case 0xb4: case 0xb5: case 0xb6: case 0xb7:
|
||||
case 0xb8: case 0xb9: case 0xba: case 0xbb:
|
||||
case 0xbc: case 0xbd: case 0xbe: case 0xbf:
|
||||
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
|
||||
case 0xc4: case 0xc5: case 0xc6: case 0xc7:
|
||||
case 0xc8: case 0xc9: case 0xca: case 0xcb:
|
||||
case 0xcc: case 0xcd: case 0xce: case 0xcf:
|
||||
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||
case 0xd4: case 0xd5: case 0xd6: case 0xd7:
|
||||
case 0xd8: case 0xd9: case 0xda: case 0xdb:
|
||||
case 0xdc: case 0xdd: case 0xde: case 0xdf:
|
||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
|
||||
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
||||
case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
||||
case 0xec: case 0xed: case 0xee: case 0xef:
|
||||
case 0xf0: case 0xf1: case 0xf2: case 0xf3:
|
||||
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
|
||||
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
|
||||
case 0xfc: case 0xfd: case 0xfe: case 0xff:
|
||||
return tvga_accel.pattern[addr & 0x7f];
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
uint16_t tvga_accel_read_w(uint32_t addr, void *priv)
|
||||
{
|
||||
pclog("tvga_accel_read_w %08X\n", addr);
|
||||
return tvga_accel_read(addr, NULL) | (tvga_accel_read(addr + 1, NULL) << 8);
|
||||
}
|
||||
|
||||
uint32_t tvga_accel_read_l(uint32_t addr, void *priv)
|
||||
{
|
||||
pclog("tvga_accel_read_l %08X\n", addr);
|
||||
return tvga_accel_read_w(addr, NULL) | (tvga_accel_read_w(addr + 2, NULL) << 16);
|
||||
}
|
||||
|
||||
void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("tvga_accel_write_fb_b %08X %02X\n", addr, val);
|
||||
tvga_accel_command(8, val << 24);
|
||||
}
|
||||
|
||||
void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
// pclog("tvga_accel_write_fb_w %08X %04X\n", addr, val);
|
||||
tvga_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16);
|
||||
}
|
||||
|
||||
void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
// pclog("tvga_accel_write_fb_l %08X %08X\n", addr, val);
|
||||
tvga_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
|
||||
}
|
||||
|
||||
GFXCARD vid_tvga =
|
||||
{
|
||||
tvga_init,
|
||||
|
|
@ -197,3 +956,27 @@ GFXCARD vid_tvga =
|
|||
video_read_null,
|
||||
video_read_null
|
||||
};
|
||||
|
||||
GFXCARD vid_tgui9440 =
|
||||
{
|
||||
tvga_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
tvga_out,
|
||||
tvga_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
|
||||
svga_poll,
|
||||
svga_recalctimings,
|
||||
|
||||
svga_write,
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
|
||||
svga_read,
|
||||
video_read_null,
|
||||
video_read_null
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
static int unk_state=0;
|
||||
static uint8_t unk_ctrl;
|
||||
|
||||
void unk_ramdac_out(uint16_t addr, uint8_t val)
|
||||
void unk_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
//pclog("OUT RAMDAC %04X %02X\n",addr,val);
|
||||
switch (addr)
|
||||
|
|
@ -42,10 +42,10 @@ void unk_ramdac_out(uint16_t addr, uint8_t val)
|
|||
unk_state = 0;
|
||||
break;
|
||||
}
|
||||
svga_out(addr,val);
|
||||
svga_out(addr, val, NULL);
|
||||
}
|
||||
|
||||
uint8_t unk_ramdac_in(uint16_t addr)
|
||||
uint8_t unk_ramdac_in(uint16_t addr, void *priv)
|
||||
{
|
||||
//pclog("IN RAMDAC %04X\n",addr);
|
||||
switch (addr)
|
||||
|
|
@ -62,5 +62,5 @@ uint8_t unk_ramdac_in(uint16_t addr)
|
|||
unk_state = 0;
|
||||
break;
|
||||
}
|
||||
return svga_in(addr);
|
||||
return svga_in(addr, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
void unk_ramdac_out(uint16_t addr, uint8_t val);
|
||||
uint8_t unk_ramdac_in(uint16_t addr);
|
||||
void unk_ramdac_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t unk_ramdac_in(uint16_t addr, void *priv);
|
||||
|
|
|
|||
90
src/video.c
90
src/video.c
|
|
@ -5,6 +5,9 @@
|
|||
#include "vid_svga.h"
|
||||
#include "io.h"
|
||||
#include "cpu.h"
|
||||
#include "timer.h"
|
||||
|
||||
int video_timer;
|
||||
|
||||
/*Video timing settings -
|
||||
|
||||
|
|
@ -81,46 +84,46 @@ int video_res_x, video_res_y, video_bpp;
|
|||
void (*video_blit_memtoscreen)(int x, int y, int y1, int y2, int w, int h);
|
||||
void (*video_blit_memtoscreen_8)(int x, int y, int w, int h);
|
||||
|
||||
void (*video_out) (uint16_t addr, uint8_t val);
|
||||
void (*video_mono_out)(uint16_t addr, uint8_t val);
|
||||
uint8_t (*video_in) (uint16_t addr);
|
||||
uint8_t (*video_mono_in)(uint16_t addr);
|
||||
void (*video_out) (uint16_t addr, uint8_t val, void *priv);
|
||||
void (*video_mono_out)(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t (*video_in) (uint16_t addr, void *priv);
|
||||
uint8_t (*video_mono_in)(uint16_t addr, void *priv);
|
||||
|
||||
void (*video_write_a000)(uint32_t addr, uint8_t val);
|
||||
void (*video_write_b000)(uint32_t addr, uint8_t val);
|
||||
void (*video_write_b800)(uint32_t addr, uint8_t val);
|
||||
void (*video_write_a000)(uint32_t addr, uint8_t val, void *priv);
|
||||
void (*video_write_b000)(uint32_t addr, uint8_t val, void *priv);
|
||||
void (*video_write_b800)(uint32_t addr, uint8_t val, void *priv);
|
||||
|
||||
void (*video_write_a000_w)(uint32_t addr, uint16_t val);
|
||||
void (*video_write_a000_l)(uint32_t addr, uint32_t val);
|
||||
void (*video_write_a000_w)(uint32_t addr, uint16_t val, void *priv);
|
||||
void (*video_write_a000_l)(uint32_t addr, uint32_t val, void *priv);
|
||||
|
||||
uint8_t (*video_read_a000)(uint32_t addr);
|
||||
uint8_t (*video_read_b000)(uint32_t addr);
|
||||
uint8_t (*video_read_b800)(uint32_t addr);
|
||||
uint8_t (*video_read_a000)(uint32_t addr, void *priv);
|
||||
uint8_t (*video_read_b000)(uint32_t addr, void *priv);
|
||||
uint8_t (*video_read_b800)(uint32_t addr, void *priv);
|
||||
|
||||
void (*video_recalctimings)();
|
||||
|
||||
void video_out_null(uint16_t addr, uint8_t val)
|
||||
void video_out_null(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t video_in_null(uint16_t addr)
|
||||
uint8_t video_in_null(uint16_t addr, void *priv)
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void video_write_null(uint32_t addr, uint8_t val)
|
||||
void video_write_null(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t video_read_null(uint32_t addr)
|
||||
uint8_t video_read_null(uint32_t addr, void *priv)
|
||||
{
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void video_load(GFXCARD g)
|
||||
{
|
||||
io_sethandler(0x03a0, 0x0020, g.mono_in, NULL, NULL, g.mono_out, NULL, NULL);
|
||||
io_sethandler(0x03c0, 0x0020, g.in, NULL, NULL, g.out, NULL, NULL);
|
||||
io_sethandler(0x03a0, 0x0020, g.mono_in, NULL, NULL, g.mono_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x03c0, 0x0020, g.in, NULL, NULL, g.out, NULL, NULL, NULL);
|
||||
|
||||
video_out = g.out;
|
||||
video_in = g.in;
|
||||
|
|
@ -141,6 +144,8 @@ void video_load(GFXCARD g)
|
|||
video_write_a000_w = video_write_a000_l = NULL;
|
||||
|
||||
g.init();
|
||||
|
||||
video_timer = timer_add(pollvideo, &vidtime, TIMER_ALWAYS_ENABLED, NULL);
|
||||
}
|
||||
|
||||
void video_init()
|
||||
|
|
@ -221,6 +226,38 @@ void video_init()
|
|||
video_load(vid_s3);
|
||||
break;
|
||||
|
||||
case GFX_VIRGE:
|
||||
video_load(vid_s3_virge);
|
||||
break;
|
||||
|
||||
case GFX_TGUI9440:
|
||||
video_load(vid_tgui9440);
|
||||
break;
|
||||
|
||||
case GFX_VGA:
|
||||
video_load(vid_vga);
|
||||
break;
|
||||
|
||||
case GFX_VGAEDGE16:
|
||||
video_load(vid_ati18800);
|
||||
break;
|
||||
|
||||
case GFX_VGACHARGER:
|
||||
video_load(vid_ati28800);
|
||||
break;
|
||||
|
||||
case GFX_OTI067:
|
||||
video_load(vid_oti067);
|
||||
return;
|
||||
|
||||
case GFX_MACH64GX:
|
||||
video_load(vid_mach64);
|
||||
return;
|
||||
|
||||
case GFX_CL_GD5429:
|
||||
video_load(vid_gd5429);
|
||||
return;
|
||||
|
||||
default:
|
||||
fatal("Bad gfx card %i\n",gfxcard);
|
||||
}
|
||||
|
|
@ -235,7 +272,8 @@ int speshul=0;
|
|||
uint8_t fontdat[256][8];
|
||||
uint8_t fontdatm[256][16];
|
||||
|
||||
float dispontime,dispofftime,disptime;
|
||||
int dispontime,dispofftime;
|
||||
double disptime;
|
||||
int svgaon;
|
||||
uint8_t cgamode=1,cgastat,cgacol=7,ocgamode;
|
||||
int linepos=0;
|
||||
|
|
@ -404,7 +442,7 @@ PALETTE comppal=
|
|||
|
||||
void initvideo()
|
||||
{
|
||||
int c,d;
|
||||
int c;
|
||||
// set_color_depth(desktop_color_depth());
|
||||
// if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,2048,2048,0,0))
|
||||
// set_gfx_mode(GFX_AUTODETECT_WINDOWED,1024,768,0,0);
|
||||
|
|
@ -473,18 +511,6 @@ void resetvideo()
|
|||
mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16;
|
||||
mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16;
|
||||
mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16;
|
||||
/* switch (gfxcard)
|
||||
{
|
||||
case GFX_CGA: pollvideo=pollcga; break;
|
||||
case GFX_MDA:
|
||||
case GFX_HERCULES: pollvideo=pollmda; break;
|
||||
}
|
||||
if (TANDY) pollvideo=polltandy;
|
||||
if (EGA) pollvideo=pollega;
|
||||
if (romset==ROM_PC1512 || romset==ROM_PC200) pollvideo=pollcga;*/
|
||||
// tandyvram=&ram[0x9C000];
|
||||
// printf("Tandy VRAM %08X\n",tandyvram);
|
||||
// tandyb8000=&ram[0x9C000];
|
||||
}
|
||||
|
||||
void closevideo()
|
||||
|
|
|
|||
69
src/video.h
69
src/video.h
|
|
@ -10,7 +10,7 @@ extern uint8_t gdcreg[16];
|
|||
extern int gdcaddr;
|
||||
extern uint8_t attrregs[32];
|
||||
extern int attraddr,attrff;
|
||||
extern uint8_t seqregs[32];
|
||||
extern uint8_t seqregs[64];
|
||||
extern int seqaddr;
|
||||
extern int svgaon;
|
||||
|
||||
|
|
@ -34,31 +34,34 @@ extern int changeframecount;
|
|||
|
||||
extern int firstline,lastline;
|
||||
extern int ega_hdisp,ega_rowoffset,ega_split,ega_dispend,ega_vsyncstart,ega_vtotal;
|
||||
extern float dispontime,dispofftime,disptime;
|
||||
extern int dispontime,dispofftime;
|
||||
extern double disptime;
|
||||
|
||||
extern void (*video_out) (uint16_t addr, uint8_t val);
|
||||
extern void (*video_mono_out)(uint16_t addr, uint8_t val);
|
||||
extern uint8_t (*video_in) (uint16_t addr);
|
||||
extern uint8_t (*video_mono_in)(uint16_t addr);
|
||||
extern void (*video_out) (uint16_t addr, uint8_t val, void *priv);
|
||||
extern void (*video_mono_out)(uint16_t addr, uint8_t val, void *priv);
|
||||
extern uint8_t (*video_in) (uint16_t addr, void *priv);
|
||||
extern uint8_t (*video_mono_in)(uint16_t addr, void *priv);
|
||||
|
||||
extern void (*video_write_a000)(uint32_t addr, uint8_t val);
|
||||
extern void (*video_write_b000)(uint32_t addr, uint8_t val);
|
||||
extern void (*video_write_b800)(uint32_t addr, uint8_t val);
|
||||
extern void (*video_write_a000)(uint32_t addr, uint8_t val, void *priv);
|
||||
extern void (*video_write_b000)(uint32_t addr, uint8_t val, void *priv);
|
||||
extern void (*video_write_b800)(uint32_t addr, uint8_t val, void *priv);
|
||||
|
||||
extern uint8_t (*video_read_a000)(uint32_t addr);
|
||||
extern uint8_t (*video_read_b000)(uint32_t addr);
|
||||
extern uint8_t (*video_read_b800)(uint32_t addr);
|
||||
extern uint8_t (*video_read_a000)(uint32_t addr, void *priv);
|
||||
extern uint8_t (*video_read_b000)(uint32_t addr, void *priv);
|
||||
extern uint8_t (*video_read_b800)(uint32_t addr, void *priv);
|
||||
|
||||
extern void (*video_write_a000_w)(uint32_t addr, uint16_t val);
|
||||
extern void (*video_write_a000_l)(uint32_t addr, uint32_t val);
|
||||
extern void (*video_write_a000_w)(uint32_t addr, uint16_t val, void *priv);
|
||||
extern void (*video_write_a000_l)(uint32_t addr, uint32_t val, void *priv);
|
||||
|
||||
extern void video_out_null(uint16_t addr, uint8_t val);
|
||||
extern uint8_t video_in_null(uint16_t addr);
|
||||
extern void video_out_null(uint16_t addr, uint8_t val, void *priv);
|
||||
extern uint8_t video_in_null(uint16_t addr, void *priv);
|
||||
|
||||
extern void video_write_null(uint32_t addr, uint8_t val);
|
||||
extern uint8_t video_read_null (uint32_t addr);
|
||||
extern void video_write_null(uint32_t addr, uint8_t val, void *priv);
|
||||
extern uint8_t video_read_null (uint32_t addr, void *priv);
|
||||
|
||||
|
||||
extern int video_timer;
|
||||
|
||||
extern uint8_t tridentoldctrl2,tridentnewctrl2;
|
||||
extern int rowdbl;
|
||||
|
||||
|
|
@ -73,6 +76,8 @@ extern BITMAP *buffer,*buffer32,*vbuf;
|
|||
|
||||
extern BITMAP *screen;
|
||||
|
||||
BITMAP *create_bitmap(int w, int h);
|
||||
|
||||
extern int wx,wy;
|
||||
|
||||
extern uint8_t fontdat[256][8];
|
||||
|
|
@ -98,18 +103,18 @@ extern uint32_t vrammask;
|
|||
typedef struct
|
||||
{
|
||||
int (*init)();
|
||||
void (*out)(uint16_t addr, uint8_t val);
|
||||
uint8_t (*in)(uint16_t addr);
|
||||
void (*mono_out)(uint16_t addr, uint8_t val);
|
||||
uint8_t (*mono_in)(uint16_t addr);
|
||||
void (*out)(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t (*in)(uint16_t addr, void *priv);
|
||||
void (*mono_out)(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t (*mono_in)(uint16_t addr, void *priv);
|
||||
void (*poll)();
|
||||
void (*recalctimings)();
|
||||
void (*write_a000)(uint32_t addr, uint8_t val);
|
||||
void (*write_b000)(uint32_t addr, uint8_t val);
|
||||
void (*write_b800)(uint32_t addr, uint8_t val);
|
||||
uint8_t (*read_a000)(uint32_t addr);
|
||||
uint8_t (*read_b000)(uint32_t addr);
|
||||
uint8_t (*read_b800)(uint32_t addr);
|
||||
void (*write_a000)(uint32_t addr, uint8_t val, void *priv);
|
||||
void (*write_b000)(uint32_t addr, uint8_t val, void *priv);
|
||||
void (*write_b800)(uint32_t addr, uint8_t val, void *priv);
|
||||
uint8_t (*read_a000)(uint32_t addr, void *priv);
|
||||
uint8_t (*read_b000)(uint32_t addr, void *priv);
|
||||
uint8_t (*read_b800)(uint32_t addr, void *priv);
|
||||
} GFXCARD;
|
||||
|
||||
extern GFXCARD vid_cga;
|
||||
|
|
@ -127,7 +132,13 @@ extern GFXCARD vid_tvga;
|
|||
extern GFXCARD vid_et4000;
|
||||
extern GFXCARD vid_et4000w32p;
|
||||
extern GFXCARD vid_s3;
|
||||
|
||||
extern GFXCARD vid_s3_virge;
|
||||
extern GFXCARD vid_tgui9440;
|
||||
extern GFXCARD vid_vga;
|
||||
extern GFXCARD vid_ati18800;
|
||||
extern GFXCARD vid_ati28800;
|
||||
extern GFXCARD vid_mach64;
|
||||
extern GFXCARD vid_gd5429;
|
||||
|
||||
extern float cpuclock;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ static uint16_t wd76c10_2072;
|
|||
static uint16_t wd76c10_2872;
|
||||
static uint16_t wd76c10_5872;
|
||||
|
||||
uint16_t wd76c10_read(uint16_t port)
|
||||
uint16_t wd76c10_read(uint16_t port, void *priv)
|
||||
{
|
||||
switch (port)
|
||||
{
|
||||
|
|
@ -29,7 +29,7 @@ uint16_t wd76c10_read(uint16_t port)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void wd76c10_write(uint16_t port, uint16_t val)
|
||||
void wd76c10_write(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
pclog("WD76C10 write %04X %04X\n", port, val);
|
||||
switch (port)
|
||||
|
|
@ -68,7 +68,7 @@ void wd76c10_write(uint16_t port, uint16_t val)
|
|||
|
||||
fdc_remove();
|
||||
if (!(val & 1))
|
||||
fdc_init();
|
||||
fdc_add();
|
||||
break;
|
||||
|
||||
case 0x5872:
|
||||
|
|
@ -77,26 +77,26 @@ void wd76c10_write(uint16_t port, uint16_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t wd76c10_readb(uint16_t port)
|
||||
uint8_t wd76c10_readb(uint16_t port, void *priv)
|
||||
{
|
||||
if (port & 1)
|
||||
return wd76c10_read(port & ~1) >> 8;
|
||||
return wd76c10_read(port) & 0xff;
|
||||
return wd76c10_read(port & ~1, priv) >> 8;
|
||||
return wd76c10_read(port, priv) & 0xff;
|
||||
}
|
||||
|
||||
void wd76c10_writeb(uint16_t port, uint8_t val)
|
||||
void wd76c10_writeb(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
uint16_t temp = wd76c10_read(port);
|
||||
uint16_t temp = wd76c10_read(port, priv);
|
||||
if (port & 1)
|
||||
wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8));
|
||||
wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8), priv);
|
||||
else
|
||||
wd76c10_write(port , (temp & 0xff00) | val);
|
||||
wd76c10_write(port , (temp & 0xff00) | val, priv);
|
||||
}
|
||||
|
||||
void wd76c10_init()
|
||||
{
|
||||
io_sethandler(0x0092, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL);
|
||||
io_sethandler(0x2072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL);
|
||||
io_sethandler(0x2872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL);
|
||||
io_sethandler(0x5872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL);
|
||||
io_sethandler(0x0092, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL);
|
||||
io_sethandler(0x2072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL);
|
||||
io_sethandler(0x2872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL);
|
||||
io_sethandler(0x5872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "video.h"
|
||||
|
||||
BITMAP *screen;
|
||||
|
|
|
|||
227
src/win.c
227
src/win.c
|
|
@ -15,6 +15,8 @@
|
|||
#include "video.h"
|
||||
#include "resources.h"
|
||||
#include "ide.h"
|
||||
#include "nvr.h"
|
||||
#include "sound.h"
|
||||
|
||||
#include "plat-keyboard.h"
|
||||
|
||||
|
|
@ -25,7 +27,7 @@
|
|||
#define TIMER_1SEC 1
|
||||
|
||||
int winsizex=640,winsizey=480;
|
||||
int svgapresent, et4000w32_present, bahamas64_present, n9_9fx_present;
|
||||
int gfx_present[18];
|
||||
int wakeups,wokeups;
|
||||
#undef cs
|
||||
CRITICAL_SECTION cs;
|
||||
|
|
@ -44,8 +46,6 @@ void endmainthread();
|
|||
void endsoundthread();
|
||||
void silencesound();
|
||||
void restoresound();
|
||||
static HANDLE soundobject;
|
||||
|
||||
static HANDLE frameobject;
|
||||
|
||||
int infocus=1;
|
||||
|
|
@ -61,7 +61,7 @@ void vsyncint()
|
|||
// }
|
||||
}
|
||||
|
||||
int romspresent[25];
|
||||
int romspresent[26];
|
||||
int quited=0;
|
||||
|
||||
RECT oldclip,pcclip;
|
||||
|
|
@ -99,11 +99,6 @@ void releasemouse()
|
|||
}
|
||||
}
|
||||
|
||||
static LARGE_INTEGER counter_base;
|
||||
static LARGE_INTEGER counter_freq;
|
||||
static LARGE_INTEGER counter_pos;
|
||||
static LARGE_INTEGER counter_posold;
|
||||
|
||||
void setrefresh(int rate)
|
||||
{
|
||||
return;
|
||||
|
|
@ -155,6 +150,7 @@ int pause=0;
|
|||
void mainthread(LPVOID param)
|
||||
{
|
||||
int t = 0;
|
||||
int frames = 0;
|
||||
DWORD old_time, new_time;
|
||||
mainthreadon=1;
|
||||
// Sleep(500);
|
||||
|
|
@ -190,12 +186,19 @@ void mainthread(LPVOID param)
|
|||
runpc();
|
||||
// ddraw_draw();
|
||||
endblit();
|
||||
frames++;
|
||||
if (frames >= 200 && nvr_dosave)
|
||||
{
|
||||
frames = 0;
|
||||
nvr_dosave = 0;
|
||||
savenvr();
|
||||
}
|
||||
//#if 0
|
||||
//#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sleep(1);
|
||||
Sleep(1);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
|
@ -246,9 +249,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
|||
HWND hwnd; /* This is the handle for our window */
|
||||
MSG messages; /* Here messages to the application are saved */
|
||||
WNDCLASSEX wincl; /* Data structure for the windowclass */
|
||||
int c,d;
|
||||
FILE *f;
|
||||
int oldinfocus=0;
|
||||
int c, d;
|
||||
|
||||
hinstance=hThisInstance;
|
||||
/* The Window structure */
|
||||
|
|
@ -317,19 +318,19 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
|||
// set_display_switch_mode(SWITCH_BACKGROUND);
|
||||
|
||||
d=romset;
|
||||
for (c=0;c<25;c++)
|
||||
for (c=0;c<26;c++)
|
||||
{
|
||||
romset=c;
|
||||
romspresent[c]=loadbios();
|
||||
pclog("romset %i - %i\n", c, romspresent[c]);
|
||||
}
|
||||
|
||||
for (c = 0; c < 25; c++)
|
||||
for (c = 0; c < 26; c++)
|
||||
{
|
||||
if (romspresent[c])
|
||||
break;
|
||||
}
|
||||
if (c == 25)
|
||||
if (c == 26)
|
||||
{
|
||||
MessageBox(hwnd,"No ROMs present!\nYou must have at least one romset to use PCem.","PCem fatal error",MB_OK);
|
||||
return 0;
|
||||
|
|
@ -340,8 +341,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
|||
|
||||
if (!c)
|
||||
{
|
||||
if (romset!=-1) MessageBox(hwnd,"Configured romset not available.\nDefaulting to available romset.","PCemu error",MB_OK);
|
||||
for (c=0;c<25;c++)
|
||||
if (romset!=-1) MessageBox(hwnd,"Configured romset not available.\nDefaulting to available romset.","PCem error",MB_OK);
|
||||
for (c=0;c<26;c++)
|
||||
{
|
||||
if (romspresent[c])
|
||||
{
|
||||
|
|
@ -352,60 +353,26 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
|||
}
|
||||
}
|
||||
|
||||
f=romfopen("roms/trident.bin","rb");
|
||||
if (f)
|
||||
d = gfxcard;
|
||||
for (c = 0; c < 18; c++)
|
||||
{
|
||||
fclose(f);
|
||||
vgapresent=1;
|
||||
gfxcard = c;
|
||||
gfx_present[c] = mem_load_video_bios();
|
||||
}
|
||||
else
|
||||
gfxcard = d;
|
||||
c = mem_load_video_bios();
|
||||
if (!c)
|
||||
{
|
||||
vgapresent=0;
|
||||
if (gfxcard==GFX_TVGA) gfxcard=GFX_CGA;
|
||||
}
|
||||
f=romfopen("roms/et4000.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fclose(f);
|
||||
svgapresent=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
svgapresent=0;
|
||||
if (gfxcard==GFX_ET4000) gfxcard=(svgapresent)?GFX_TVGA:GFX_CGA;
|
||||
}
|
||||
f=romfopen("roms/et4000w32.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fclose(f);
|
||||
et4000w32_present=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
et4000w32_present=0;
|
||||
if (gfxcard==GFX_ET4000W32) gfxcard=(svgapresent)?GFX_TVGA:GFX_CGA;
|
||||
}
|
||||
f=romfopen("roms/bahamas64.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fclose(f);
|
||||
bahamas64_present=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bahamas64_present=0;
|
||||
if (gfxcard==GFX_BAHAMAS64) gfxcard=(svgapresent)?GFX_TVGA:GFX_CGA;
|
||||
}
|
||||
f=romfopen("roms/s3_764.bin","rb");
|
||||
if (f)
|
||||
{
|
||||
fclose(f);
|
||||
n9_9fx_present=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
n9_9fx_present=0;
|
||||
if (gfxcard==GFX_N9_9FX) gfxcard=(svgapresent)?GFX_TVGA:GFX_CGA;
|
||||
if (romset!=-1) MessageBox(hwnd,"Configured video BIOS not available.\nDefaulting to available romset.","PCem error",MB_OK);
|
||||
for (c=0;c<18;c++)
|
||||
{
|
||||
if (gfx_present[c])
|
||||
{
|
||||
gfxcard = c;
|
||||
mem_load_video_bios();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
timeBeginPeriod(1);
|
||||
// soundobject=CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
|
@ -505,7 +472,6 @@ char openfilestring[260];
|
|||
int getfile(HWND hwnd, char *f, char *fn)
|
||||
{
|
||||
OPENFILENAME ofn; // common dialog box structure
|
||||
char szFile[260]; // buffer for file name
|
||||
BOOL r;
|
||||
DWORD err;
|
||||
|
||||
|
|
@ -546,7 +512,6 @@ int getfile(HWND hwnd, char *f, char *fn)
|
|||
int getsfile(HWND hwnd, char *f, char *fn)
|
||||
{
|
||||
OPENFILENAME ofn; // common dialog box structure
|
||||
char szFile[260]; // buffer for file name
|
||||
BOOL r;
|
||||
DWORD err;
|
||||
|
||||
|
|
@ -585,12 +550,18 @@ int getsfile(HWND hwnd, char *f, char *fn)
|
|||
}
|
||||
|
||||
extern int is486;
|
||||
int romstolist[25], listtomodel[23], romstomodel[25], modeltolist[23];
|
||||
int vidtolist[10],listtovid[10];
|
||||
int romstolist[26], listtomodel[26], romstomodel[26], modeltolist[26];
|
||||
int vidtolist[20],listtovid[20];
|
||||
|
||||
int mem_list_to_size[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,32,48,64};
|
||||
int mem_list_to_size[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,32,48,64,256};
|
||||
int mem_size_to_list[]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,
|
||||
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,18};
|
||||
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,18,
|
||||
19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
|
||||
19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
|
||||
19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
|
||||
19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
|
||||
19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
|
||||
19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 19};
|
||||
|
||||
#include "cpu.h"
|
||||
#include "model.h"
|
||||
|
|
@ -601,13 +572,14 @@ BOOL CALLBACK configdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
int c, d;
|
||||
int rom,gfx,mem,fpu;
|
||||
int temp_cpu, temp_cpu_m, temp_model;
|
||||
int temp_GAMEBLASTER, temp_GUS, temp_sound_card_current;
|
||||
// pclog("Dialog msg %i %08X\n",message,message);
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
pause=1;
|
||||
h=GetDlgItem(hdlg,IDC_COMBO1);
|
||||
for (c=0;c<25;c++) romstolist[c]=0;
|
||||
for (c=0;c<26;c++) romstolist[c]=0;
|
||||
c = d = 0;
|
||||
while (models[c].id != -1)
|
||||
{
|
||||
|
|
@ -632,11 +604,19 @@ BOOL CALLBACK configdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"MDA"); vidtolist[GFX_MDA]=1; listtovid[1]=1;
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Hercules"); vidtolist[GFX_HERCULES]=2; listtovid[2]=2;
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"EGA"); vidtolist[GFX_EGA]=3; listtovid[3]=3;
|
||||
if (vgapresent) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Trident 8900D"); vidtolist[GFX_TVGA]=c; listtovid[c]=GFX_TVGA; c++; }
|
||||
if (svgapresent) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Tseng ET4000AX"); vidtolist[GFX_ET4000]=c; listtovid[c]=GFX_ET4000; c++; }
|
||||
if (et4000w32_present) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Diamond Stealth 32"); vidtolist[GFX_ET4000W32]=c; listtovid[c]=GFX_ET4000W32; c++; }
|
||||
if (bahamas64_present) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Paradise Bahamas 64"); vidtolist[GFX_BAHAMAS64]=c; listtovid[c]=GFX_BAHAMAS64; c++; }
|
||||
if (n9_9fx_present) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Number Nine 9FX"); vidtolist[GFX_N9_9FX]=c; listtovid[c]=GFX_N9_9FX; c++; }
|
||||
if (gfx_present[GFX_TVGA]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Trident 8900D"); vidtolist[GFX_TVGA]=c; listtovid[c]=GFX_TVGA; c++; }
|
||||
if (gfx_present[GFX_ET4000]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Tseng ET4000AX"); vidtolist[GFX_ET4000]=c; listtovid[c]=GFX_ET4000; c++; }
|
||||
if (gfx_present[GFX_ET4000W32]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Diamond Stealth 32"); vidtolist[GFX_ET4000W32]=c; listtovid[c]=GFX_ET4000W32; c++; }
|
||||
if (gfx_present[GFX_BAHAMAS64]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Paradise Bahamas 64"); vidtolist[GFX_BAHAMAS64]=c; listtovid[c]=GFX_BAHAMAS64; c++; }
|
||||
if (gfx_present[GFX_N9_9FX]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Number Nine 9FX"); vidtolist[GFX_N9_9FX]=c; listtovid[c]=GFX_N9_9FX; c++; }
|
||||
if (gfx_present[GFX_VIRGE]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"S3 VIRGE"); vidtolist[GFX_VIRGE]=c; listtovid[c]=GFX_VIRGE; c++; }
|
||||
if (gfx_present[GFX_TGUI9440]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Trident TGUI9440"); vidtolist[GFX_TGUI9440]=c; listtovid[c]=GFX_TGUI9440; c++; }
|
||||
if (gfx_present[GFX_VGA]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"VGA"); vidtolist[GFX_VGA]=c; listtovid[c]=GFX_VGA; c++; }
|
||||
if (gfx_present[GFX_VGAEDGE16]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"ATI VGA Edge-16"); vidtolist[GFX_VGAEDGE16]=c; listtovid[c]=GFX_VGAEDGE16; c++; }
|
||||
if (gfx_present[GFX_VGACHARGER]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"ATI VGA Charger"); vidtolist[GFX_VGACHARGER]=c; listtovid[c]=GFX_VGACHARGER; c++; }
|
||||
if (gfx_present[GFX_OTI067]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Oak OTI-067"); vidtolist[GFX_OTI067]=c; listtovid[c]=GFX_OTI067; c++; }
|
||||
if (gfx_present[GFX_MACH64GX]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"ATI Graphics Pro Turbo"); vidtolist[GFX_MACH64GX]=c; listtovid[c]=GFX_MACH64GX; c++; }
|
||||
if (gfx_present[GFX_CL_GD5429]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Cirrus Logic CL-GD5429"); vidtolist[GFX_CL_GD5429]=c; listtovid[c]=GFX_CL_GD5429; c++; }
|
||||
SendMessage(h,CB_SETCURSEL,vidtolist[gfxcard],0);
|
||||
if (models[model].fixed_gfxcard) EnableWindow(h,FALSE);
|
||||
|
||||
|
|
@ -663,30 +643,30 @@ BOOL CALLBACK configdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
SendMessage(h, CB_SETCURSEL, cpu, 0);
|
||||
|
||||
h=GetDlgItem(hdlg,IDC_COMBOSND);
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"None");
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"AdLib");
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SoundBlaster v1.0");
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SoundBlaster v1.5");
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SoundBlaster v2.0");
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SB Pro v1");
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SB Pro v2");
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SoundBlaster 16");
|
||||
SendMessage(h,CB_SETCURSEL,sbtype,0);
|
||||
c = 0;
|
||||
while (1)
|
||||
{
|
||||
char *s = sound_card_getname(c);
|
||||
|
||||
// h=GetDlgItem(hdlg,IDC_CHECK2);
|
||||
// SendMessage(h,BM_SETCHECK,ADLIB,0);
|
||||
if (!s[0])
|
||||
break;
|
||||
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
|
||||
c++;
|
||||
}
|
||||
SendMessage(h, CB_SETCURSEL, sound_card_current, 0);
|
||||
|
||||
h=GetDlgItem(hdlg, IDC_CHECK3);
|
||||
SendMessage(h, BM_SETCHECK, GAMEBLASTER, 0);
|
||||
|
||||
h=GetDlgItem(hdlg, IDC_CHECKGUS);
|
||||
SendMessage(h, BM_SETCHECK, GUS, 0);
|
||||
|
||||
h=GetDlgItem(hdlg,IDC_CHECK3);
|
||||
SendMessage(h,BM_SETCHECK,GAMEBLASTER,0);
|
||||
|
||||
h=GetDlgItem(hdlg,IDC_CHECK1);
|
||||
SendMessage(h,BM_SETCHECK,FASTDISC,0);
|
||||
h=GetDlgItem(hdlg, IDC_CHECK2);
|
||||
SendMessage(h, BM_SETCHECK, slowega, 0);
|
||||
|
||||
h=GetDlgItem(hdlg,IDC_CHECK2);
|
||||
SendMessage(h,BM_SETCHECK,slowega,0);
|
||||
|
||||
h=GetDlgItem(hdlg,IDC_CHECK4);
|
||||
SendMessage(h,BM_SETCHECK,cga_comp,0);
|
||||
h=GetDlgItem(hdlg, IDC_CHECK4);
|
||||
SendMessage(h, BM_SETCHECK, cga_comp, 0);
|
||||
|
||||
h=GetDlgItem(hdlg,IDC_COMBOCHC);
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"A little");
|
||||
|
|
@ -725,6 +705,7 @@ BOOL CALLBACK configdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"32 MB");
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"48 MB");
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"64 MB");
|
||||
SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"256 MB");
|
||||
SendMessage(h,CB_SETCURSEL,mem_size_to_list[mem_size-1],0);
|
||||
|
||||
pclog("Init cpuspeed %i\n",cpuspeed);
|
||||
|
|
@ -750,7 +731,16 @@ BOOL CALLBACK configdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
fpu = (models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type >= CPU_i486DX) ? 1 : 0;
|
||||
pclog("newcpu - %i %i %i %i\n",temp_cpu_m,temp_cpu,fpu,models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type);
|
||||
|
||||
if (temp_model != model || gfx!=gfxcard || mem!=mem_size || fpu!=hasfpu)
|
||||
h = GetDlgItem(hdlg, IDC_CHECK3);
|
||||
temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CHECKGUS);
|
||||
temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBOSND);
|
||||
temp_sound_card_current = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
|
||||
if (temp_model != model || gfx != gfxcard || mem != mem_size || fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || temp_sound_card_current != sound_card_current)
|
||||
{
|
||||
if (MessageBox(NULL,"This will reset PCem!\nOkay to continue?","PCem",MB_OKCANCEL)==IDOK)
|
||||
{
|
||||
|
|
@ -760,9 +750,13 @@ BOOL CALLBACK configdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
mem_size=mem;
|
||||
cpu_manufacturer = temp_cpu_m;
|
||||
cpu = temp_cpu;
|
||||
GAMEBLASTER = temp_GAMEBLASTER;
|
||||
GUS = temp_GUS;
|
||||
sound_card_current = temp_sound_card_current;
|
||||
|
||||
mem_resize();
|
||||
loadbios();
|
||||
mem_load_video_bios();
|
||||
resetpchard();
|
||||
}
|
||||
else
|
||||
|
|
@ -776,12 +770,6 @@ BOOL CALLBACK configdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
h=GetDlgItem(hdlg,IDC_COMBOSPD);
|
||||
video_speed = SendMessage(h,CB_GETCURSEL,0,0);
|
||||
|
||||
h=GetDlgItem(hdlg,IDC_CHECK3);
|
||||
GAMEBLASTER=SendMessage(h,BM_GETCHECK,0,0);
|
||||
|
||||
h=GetDlgItem(hdlg,IDC_CHECK1);
|
||||
FASTDISC=SendMessage(h,BM_GETCHECK,0,0);
|
||||
|
||||
h=GetDlgItem(hdlg,IDC_CHECK4);
|
||||
cga_comp=SendMessage(h,BM_GETCHECK,0,0);
|
||||
|
||||
|
|
@ -789,9 +777,6 @@ BOOL CALLBACK configdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
cpu = temp_cpu;
|
||||
cpu_set();
|
||||
|
||||
h=GetDlgItem(hdlg,IDC_COMBOSND);
|
||||
sbtype=SendMessage(h,CB_GETCURSEL,0,0);
|
||||
|
||||
h=GetDlgItem(hdlg,IDC_COMBOCHC);
|
||||
cache=SendMessage(h,CB_GETCURSEL,0,0);
|
||||
mem_updatecache();
|
||||
|
|
@ -890,7 +875,6 @@ BOOL CALLBACK hdnewdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam
|
|||
HWND h;
|
||||
int c;
|
||||
PcemHDC hd[2];
|
||||
int changeddrv=0;
|
||||
FILE *f;
|
||||
uint8_t buf[512];
|
||||
switch (message)
|
||||
|
|
@ -1004,11 +988,7 @@ BOOL CALLBACK hdsizedlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
{
|
||||
char s[260];
|
||||
HWND h;
|
||||
int c;
|
||||
PcemHDC hd[2];
|
||||
int changeddrv=0;
|
||||
FILE *f;
|
||||
uint8_t buf[512];
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
|
|
@ -1090,9 +1070,7 @@ BOOL CALLBACK hdconfdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
{
|
||||
char s[260];
|
||||
HWND h;
|
||||
int c;
|
||||
PcemHDC hd[2];
|
||||
int changeddrv=0;
|
||||
FILE *f;
|
||||
off64_t sz;
|
||||
switch (message)
|
||||
|
|
@ -1344,8 +1322,6 @@ BOOL CALLBACK hdconfdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
|
||||
BOOL CALLBACK statusdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HWND h;
|
||||
int c;
|
||||
int egasp;
|
||||
char s[256];
|
||||
switch (message)
|
||||
|
|
@ -1374,12 +1350,12 @@ BOOL CALLBACK statusdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
if (chain4) sprintf(s,"VGA chained (possibly mode 13h)");
|
||||
else sprintf(s,"VGA unchained (possibly mode-X)");
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT9,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
if (!video_bpp) sprintf(s,"VGA in text mode");
|
||||
else sprintf(s,"VGA colour depth : %i bpp", video_bpp);
|
||||
/* if (!video_bpp) sprintf(s,"VGA in text mode");
|
||||
else */sprintf(s,"VGA colour depth : %i bpp", video_bpp);
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT10,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
sprintf(s,"VGA resolution : %i x %i", video_res_x, video_res_y);
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT11,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
sprintf(s,"SB frequency : %i Hz",sb_freq);
|
||||
sprintf(s,"SB frequency : %i Hz",0);
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT12,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
sprintf(s,"Video refresh rate : %i Hz", emu_fps);
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT13,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
|
|
@ -1421,9 +1397,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
{
|
||||
HMENU hmenu;
|
||||
RECT rect;
|
||||
int c;
|
||||
int x, y;
|
||||
POINT po;
|
||||
// pclog("Message %i %08X\n",message,message);
|
||||
switch (message)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
uint32_t old8,old82,old83;
|
||||
uint16_t oldcs;
|
||||
uint32_t oldpc;
|
||||
extern uint32_t rmdat32;
|
||||
|
|
@ -16,11 +15,9 @@ int skipnextprint;
|
|||
int inhlt;
|
||||
|
||||
uint8_t opcode;
|
||||
int ins,noint,notpresent;
|
||||
int inint;
|
||||
int ins,noint;
|
||||
|
||||
uint16_t lastcs,lastpc;
|
||||
int lldt;
|
||||
int timetolive,keyboardtimer;
|
||||
|
||||
#define setznp168 setznp16
|
||||
|
|
@ -96,3 +93,7 @@ extern uint8_t opcode2;
|
|||
|
||||
extern uint16_t rds;
|
||||
extern uint32_t rmdat32;
|
||||
|
||||
extern int inscounts[256];
|
||||
|
||||
void x86illegal();
|
||||
|
|
|
|||
386
src/x86_flags.h
386
src/x86_flags.h
|
|
@ -1,17 +1,387 @@
|
|||
static inline void setznp8(uint8_t val)
|
||||
enum
|
||||
{
|
||||
flags&=~0x8d5;
|
||||
flags|=znptable8[val];
|
||||
FLAGS_UNKNOWN,
|
||||
|
||||
FLAGS_ZN8,
|
||||
FLAGS_ZN16,
|
||||
FLAGS_ZN32,
|
||||
|
||||
FLAGS_ADD8,
|
||||
FLAGS_ADD16,
|
||||
FLAGS_ADD32,
|
||||
|
||||
FLAGS_SUB8,
|
||||
FLAGS_SUB16,
|
||||
FLAGS_SUB32
|
||||
};
|
||||
|
||||
static int flags_op;
|
||||
static uint32_t flags_res;
|
||||
static uint32_t flags_op1, flags_op2;
|
||||
|
||||
static inline int ZF_SET()
|
||||
{
|
||||
switch (flags_op)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
return !flags_res;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & Z_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int NF_SET()
|
||||
{
|
||||
switch (flags_op)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_SUB8:
|
||||
return flags_res & 0x80;
|
||||
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_SUB16:
|
||||
return flags_res & 0x8000;
|
||||
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB32:
|
||||
return flags_res & 0x80000000;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & N_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int PF_SET()
|
||||
{
|
||||
switch (flags_op)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
return znptable8[flags_res & 0xff] & P_FLAG;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & P_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int VF_SET()
|
||||
{
|
||||
switch (flags_op)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
return 0;
|
||||
|
||||
case FLAGS_ADD8:
|
||||
return !((flags_op1 ^ flags_op2) & 0x80) && ((flags_op1 ^ flags_res) & 0x80);
|
||||
case FLAGS_ADD16:
|
||||
return !((flags_op1 ^ flags_op2) & 0x8000) && ((flags_op1 ^ flags_res) & 0x8000);
|
||||
case FLAGS_ADD32:
|
||||
return !((flags_op1 ^ flags_op2) & 0x80000000) && ((flags_op1 ^ flags_res) & 0x80000000);
|
||||
|
||||
case FLAGS_SUB8:
|
||||
return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x80);
|
||||
case FLAGS_SUB16:
|
||||
return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x8000);
|
||||
case FLAGS_SUB32:
|
||||
return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x80000000);
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & V_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int AF_SET()
|
||||
{
|
||||
switch (flags_op)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
return 0;
|
||||
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_ADD32:
|
||||
return ((flags_op1 & 0xF) + (flags_op2 & 0xF)) & 0x10;
|
||||
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
return ((flags_op1 & 0xF) - (flags_op2 & 0xF)) & 0x10;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & A_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline int CF_SET()
|
||||
{
|
||||
switch (flags_op)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
return flags & C_FLAG; /*Temporary*/
|
||||
|
||||
case FLAGS_ADD8:
|
||||
return (flags_op1 + flags_op2) & 0x100;
|
||||
case FLAGS_ADD16:
|
||||
// return (flags_op1 + flags_op2) & 0x10000;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & C_FLAG;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//#define ZF_SET() (flags & Z_FLAG)
|
||||
//#define NF_SET() (flags & N_FLAG)
|
||||
//#define PF_SET() (flags & P_FLAG)
|
||||
//#define VF_SET() (flags & V_FLAG)
|
||||
#define CF_SET() (flags & C_FLAG)
|
||||
//#define AF_SET() (flags & A_FLAG)
|
||||
|
||||
static inline void flags_rebuild()
|
||||
{
|
||||
if (flags_op != FLAGS_UNKNOWN)
|
||||
{
|
||||
uint16_t tempf = 0;
|
||||
if (CF_SET()) tempf |= C_FLAG;
|
||||
if (PF_SET()) tempf |= P_FLAG;
|
||||
if (AF_SET()) tempf |= A_FLAG;
|
||||
if (ZF_SET()) tempf |= Z_FLAG;
|
||||
if (NF_SET()) tempf |= N_FLAG;
|
||||
if (VF_SET()) tempf |= V_FLAG;
|
||||
flags = (flags & ~0x8d5) | tempf;
|
||||
flags_op = FLAGS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void flags_extract()
|
||||
{
|
||||
flags_op = FLAGS_UNKNOWN;
|
||||
}
|
||||
|
||||
static inline void flags_rebuild_c()
|
||||
{
|
||||
if (flags_op != FLAGS_UNKNOWN)
|
||||
{
|
||||
if (CF_SET())
|
||||
flags |= C_FLAG;
|
||||
else
|
||||
flags &= ~C_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void setznp8(uint8_t val)
|
||||
{
|
||||
flags_op = FLAGS_ZN8;
|
||||
flags_res = val;
|
||||
flags &= ~C_FLAG;
|
||||
}
|
||||
static inline void setznp16(uint16_t val)
|
||||
{
|
||||
flags&=~0x8d5;
|
||||
flags|=znptable16[val];
|
||||
flags_op = FLAGS_ZN16;
|
||||
flags_res = val;
|
||||
flags &= ~C_FLAG;
|
||||
}
|
||||
static inline void setznp32(uint32_t val)
|
||||
{
|
||||
flags&=~0x8d5;
|
||||
flags|=((val&0x80000000)?N_FLAG:((!val)?Z_FLAG:0));
|
||||
flags|=znptable8[val&0xFF]&P_FLAG;
|
||||
flags_op = FLAGS_ZN32;
|
||||
flags_res = val;
|
||||
flags &= ~C_FLAG;
|
||||
}
|
||||
|
||||
static inline void setadd8(uint8_t a, uint8_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = (a + b) & 0xff;
|
||||
flags_op = FLAGS_ADD8;
|
||||
|
||||
if ((a + b) & 0x100) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
}
|
||||
static inline void setadd16(uint16_t a, uint16_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = (a + b) & 0xffff;
|
||||
flags_op = FLAGS_ADD16;
|
||||
|
||||
if ((a + b) & 0x10000) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
}
|
||||
static inline void setadd32(uint32_t a, uint32_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = a + b;
|
||||
flags_op = FLAGS_ADD32;
|
||||
|
||||
if (flags_res < a) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
}
|
||||
static inline void setadd8nc(uint8_t a, uint8_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = (a + b) & 0xff;
|
||||
flags_op = FLAGS_ADD8;
|
||||
}
|
||||
static inline void setadd16nc(uint16_t a, uint16_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = (a + b) & 0xffff;
|
||||
flags_op = FLAGS_ADD16;
|
||||
}
|
||||
static inline void setadd32nc(uint32_t a, uint32_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = a + b;
|
||||
flags_op = FLAGS_ADD32;
|
||||
}
|
||||
|
||||
static inline void setsub8(uint8_t a, uint8_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = (a - b) & 0xff;
|
||||
flags_op = FLAGS_SUB8;
|
||||
|
||||
if (a < b) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
}
|
||||
static inline void setsub16(uint16_t a, uint16_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = (a - b) & 0xffff;
|
||||
flags_op = FLAGS_SUB16;
|
||||
|
||||
if (a < b) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
}
|
||||
static inline void setsub32(uint32_t a, uint32_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = a - b;
|
||||
flags_op = FLAGS_SUB32;
|
||||
|
||||
if (a < b) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
}
|
||||
|
||||
static inline void setsub8nc(uint8_t a, uint8_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = (a - b) & 0xff;
|
||||
flags_op = FLAGS_SUB8;
|
||||
}
|
||||
static inline void setsub16nc(uint16_t a, uint16_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = (a - b) & 0xffff;
|
||||
flags_op = FLAGS_SUB16;
|
||||
}
|
||||
static inline void setsub32nc(uint32_t a, uint32_t b)
|
||||
{
|
||||
flags_op1 = a;
|
||||
flags_op2 = b;
|
||||
flags_res = a - b;
|
||||
flags_op = FLAGS_SUB32;
|
||||
}
|
||||
|
||||
static inline void setadc8(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint16_t c=(uint16_t)a+(uint16_t)b+tempc;
|
||||
flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=znptable8[c&0xFF];
|
||||
if (c&0x100) flags|=C_FLAG;
|
||||
if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
|
||||
}
|
||||
static inline void setadc16(uint16_t a, uint16_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
|
||||
flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=znptable16[c&0xFFFF];
|
||||
if (c&0x10000) flags|=C_FLAG;
|
||||
if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
|
||||
}
|
||||
|
||||
static inline void setsbc8(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc);
|
||||
flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=znptable8[c&0xFF];
|
||||
if (c&0x100) flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
|
||||
if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
|
||||
}
|
||||
static inline void setsbc16(uint16_t a, uint16_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
|
||||
flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=(znptable16[c&0xFFFF]&~4);
|
||||
flags|=(znptable8[c&0xFF]&4);
|
||||
if (c&0x10000) flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
|
||||
if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
|
||||
}
|
||||
|
||||
static inline void setadc32(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
|
||||
flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
|
||||
flags|=(znptable8[c&0xFF]&P_FLAG);
|
||||
if ((c<a) || (c==a && tempc)) flags|=C_FLAG;
|
||||
if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF)+tempc)&0x10) flags|=A_FLAG;
|
||||
}
|
||||
static inline void setsbc32(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
|
||||
flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
|
||||
flags|=(znptable8[c&0xFF]&P_FLAG);
|
||||
if ((c>a) || (c==a && tempc)) flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x80000000) flags|=V_FLAG;
|
||||
if (((a&0xF)-((b&0xF)+tempc))&0x10) flags|=A_FLAG;
|
||||
}
|
||||
|
||||
|
|
|
|||
45
src/x86seg.c
45
src/x86seg.c
|
|
@ -1,8 +1,11 @@
|
|||
//#if 0
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "mem.h"
|
||||
#include "x86.h"
|
||||
#include "386.h"
|
||||
|
||||
/*Controls whether the accessed bit in a descriptor is set when CS is loaded. The
|
||||
386 PRM is ambiguous on this subject, but BOCHS doesn't set it and Windows 98
|
||||
|
|
@ -29,7 +32,6 @@ int intgatesize;
|
|||
void taskswitch286(uint16_t seg, uint16_t *segdat, int is32);
|
||||
void taskswitch386(uint16_t seg, uint16_t *segdat);
|
||||
|
||||
int notpresent=0;
|
||||
int output;
|
||||
void pmodeint(int num, int soft);
|
||||
/*NOT PRESENT is INT 0B
|
||||
|
|
@ -125,8 +127,6 @@ void x86ts(char *s, uint16_t error)
|
|||
void x86np(char *s, uint16_t error)
|
||||
{
|
||||
// pclog("NP %04X : %s\n", error, s);
|
||||
// dumpregs();
|
||||
// exit(-1);
|
||||
abrt = ABRT_NP;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
|
@ -325,8 +325,6 @@ void loadcs(uint16_t seg)
|
|||
{
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
int count;
|
||||
uint16_t oldss,oldsp;
|
||||
if (output) pclog("Load CS %04X\n",seg);
|
||||
if (msw&1 && !(eflags&VM_FLAG))
|
||||
{
|
||||
|
|
@ -452,10 +450,9 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
int count;
|
||||
uint16_t oldss,oldsp;
|
||||
uint16_t type,seg2;
|
||||
uint32_t newpc;
|
||||
if (output) pclog("Load CS JMP %04X\n",seg);
|
||||
// pclog("Load CS JMP %04X\n",seg);
|
||||
if (msw&1 && !(eflags&VM_FLAG))
|
||||
{
|
||||
if (!(seg&~3))
|
||||
|
|
@ -495,6 +492,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||
if (output) pclog("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]);
|
||||
if (segdat[2]&0x1000) /*Normal code segment*/
|
||||
{
|
||||
// pclog("Normal CS\n");
|
||||
if (!(segdat[2]&0x400)) /*Not conforming*/
|
||||
{
|
||||
if ((seg&3)>CPL)
|
||||
|
|
@ -528,7 +526,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||
#endif
|
||||
|
||||
CS = (seg & ~3) | CPL;
|
||||
segdat[2] = (segdat[2] & ~(3 << 5+8)) | (CPL << 5+8);
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8));
|
||||
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
|
|
@ -541,6 +539,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||
}
|
||||
else /*System segment*/
|
||||
{
|
||||
// pclog("System CS\n");
|
||||
if (!(segdat[2]&0x8000))
|
||||
{
|
||||
x86np("Load CS JMP system selector not present\n", seg & 0xfffc);
|
||||
|
|
@ -553,6 +552,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||
{
|
||||
case 0x400: /*Call gate*/
|
||||
case 0xC00:
|
||||
// pclog("Call gate\n");
|
||||
cgate32=(type&0x800);
|
||||
cgate16=!cgate32;
|
||||
oldcs=CS;
|
||||
|
|
@ -654,6 +654,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||
|
||||
|
||||
case 0x900: /*386 Task gate*/
|
||||
// pclog("Task gate\n");
|
||||
pc=oxpc;
|
||||
cpl_override=1;
|
||||
taskswitch286(seg,segdat,segdat[2]&0x800);
|
||||
|
|
@ -853,7 +854,7 @@ void loadcscall(uint16_t seg)
|
|||
if (segdat[2]&0x400)
|
||||
{
|
||||
seg = (seg & ~3) | CPL;
|
||||
segdat[2] = (segdat[2] & ~(3 << 5+8)) | (CPL << 5+8);
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8));
|
||||
}
|
||||
else /*On non-conforming segments, set RPL = CPL*/
|
||||
seg = (seg & ~3) | CPL;
|
||||
|
|
@ -1332,7 +1333,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||
|
||||
pc=newpc;
|
||||
if (segdat[2] & 0x400)
|
||||
segdat[2] = (segdat[2] & ~(3 << 5+8)) | ((seg & 3) << 5+8);
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
|
||||
CS = seg;
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
|
|
@ -1493,7 +1494,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||
#endif
|
||||
/*Conforming segments don't change CPL, so CPL = RPL*/
|
||||
if (segdat[2]&0x400)
|
||||
segdat[2] = (segdat[2] & ~(3 << 5+8)) | ((seg & 3) << 5+8);
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
|
||||
|
||||
pc=newpc;
|
||||
CS=seg;
|
||||
|
|
@ -1521,14 +1522,11 @@ void pmodeint(int num, int soft)
|
|||
{
|
||||
uint16_t segdat[4],segdat2[4],segdat3[4];
|
||||
uint32_t addr, oaddr;
|
||||
int dpl;
|
||||
uint16_t oldcs=CPL,oldcs2,newss;
|
||||
uint16_t newss;
|
||||
uint32_t oldss,oldsp;
|
||||
uint8_t oldaccess;
|
||||
int type;
|
||||
uint32_t newsp;
|
||||
uint16_t seg;
|
||||
int v86int=eflags&VM_FLAG;
|
||||
int stack_changed=0;
|
||||
// if (!num) pclog("Pmode int 0 at %04X(%06X):%08X\n",CS,cs,pc);
|
||||
// pclog("Pmode int %02X %i %04X:%08X %04X:%08X %i\n",num,soft,CS,pc, SS, ESP, abrt);
|
||||
|
|
@ -1910,12 +1908,10 @@ void pmodeint(int num, int soft)
|
|||
}
|
||||
}
|
||||
|
||||
int inint;
|
||||
void pmodeiret(int is32)
|
||||
{
|
||||
uint32_t newsp;
|
||||
uint16_t oldcs=CPL,newss;
|
||||
uint16_t tempw,tempw2;
|
||||
uint16_t newss;
|
||||
uint32_t tempflags,flagmask;
|
||||
uint32_t newpc;
|
||||
uint16_t segdat[4],segdat2[4];
|
||||
|
|
@ -1991,7 +1987,6 @@ void pmodeiret(int is32)
|
|||
cpl_override=0;
|
||||
return;
|
||||
}
|
||||
inint=0;
|
||||
oxpc=pc;
|
||||
flagmask=0xFFFF;
|
||||
if (CPL) flagmask&=~0x3000;
|
||||
|
|
@ -2254,7 +2249,7 @@ void pmodeiret(int is32)
|
|||
#endif
|
||||
/*Conforming segments don't change CPL, so CPL = RPL*/
|
||||
if (segdat[2]&0x400)
|
||||
segdat[2] = (segdat[2] & ~(3 << 5+8)) | ((seg & 3) << 5+8);
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
|
||||
|
||||
CS=seg;
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
|
|
@ -2295,12 +2290,10 @@ void pmodeiret(int is32)
|
|||
|
||||
void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
{
|
||||
uint32_t base,obase=tr.base;
|
||||
uint32_t base;
|
||||
uint32_t limit;
|
||||
int x386;
|
||||
uint32_t templ;
|
||||
uint16_t tempw;
|
||||
int c;
|
||||
|
||||
uint32_t new_cr3=0;
|
||||
uint16_t new_es,new_cs,new_ss,new_ds,new_fs,new_gs;
|
||||
|
|
@ -2310,8 +2303,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||
|
||||
uint32_t addr;
|
||||
|
||||
uint16_t oldflags;
|
||||
|
||||
uint16_t segdat2[4];
|
||||
|
||||
//output=3;
|
||||
|
|
@ -2361,6 +2352,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||
if (optype==IRET) flags&=~NT_FLAG;
|
||||
|
||||
// if (output) pclog("Write PC %08X %08X\n",tr.base,pc);
|
||||
cpu_386_flags_rebuild();
|
||||
writememl(tr.base,0x1C,cr3);
|
||||
writememl(tr.base,0x20,pc);
|
||||
writememl(tr.base,0x24,flags|(eflags<<16));
|
||||
|
|
@ -2402,7 +2394,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||
|
||||
|
||||
cr3=new_cr3;
|
||||
// pclog("New CR3 %08X\n",cr3);
|
||||
pclog("TS New CR3 %08X\n",cr3);
|
||||
flushmmucache();
|
||||
|
||||
|
||||
|
|
@ -2411,6 +2403,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||
// if (output) pclog("New pc %08X\n",new_pc);
|
||||
flags=new_flags;
|
||||
eflags=new_flags>>16;
|
||||
cpu_386_flags_extract();
|
||||
|
||||
// if (output) pclog("Load LDT %04X\n",new_ldt);
|
||||
ldt.seg=new_ldt;
|
||||
|
|
|
|||
239
src/x87.c
239
src/x87.c
|
|
@ -8,8 +8,11 @@
|
|||
//SCR_CalcRefdef
|
||||
//Calls R_SetVrect and R_ViewChanged
|
||||
|
||||
#define fplog 0
|
||||
|
||||
#include <math.h>
|
||||
#include "ibm.h"
|
||||
#include "pic.h"
|
||||
#include "x86.h"
|
||||
#include "x87.h"
|
||||
|
||||
|
|
@ -67,6 +70,30 @@ int TOP;
|
|||
#define C2 (1<<10)
|
||||
#define C3 (1<<14)
|
||||
|
||||
#define STATUS_ZERODIVIDE 4
|
||||
|
||||
#define x87_div(dst, src1, src2) do \
|
||||
{ \
|
||||
if (((double)src2) == 0.0) \
|
||||
{ \
|
||||
npxs |= STATUS_ZERODIVIDE; \
|
||||
if (npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double)src2; \
|
||||
else \
|
||||
{ \
|
||||
pclog("FPU : divide by zero\n"); \
|
||||
picint(1 << 13); \
|
||||
} \
|
||||
return; \
|
||||
} \
|
||||
else \
|
||||
dst = src1 / (double)src2; \
|
||||
} while (0)
|
||||
|
||||
void x87_checkexceptions()
|
||||
{
|
||||
}
|
||||
|
||||
void x87_reset()
|
||||
{
|
||||
}
|
||||
|
|
@ -80,8 +107,8 @@ void x87_dumpregs()
|
|||
|
||||
void x87_print()
|
||||
{
|
||||
pclog("\tST(0)=%.20f\tST(1)=%.20f\tST(2)=%f\tST(3)=%f\t",ST[TOP],ST[(TOP+1)&7],ST[(TOP+2)&7],ST[(TOP+3)&7]);
|
||||
pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n\n",ST[(TOP+4)&7],ST[(TOP+5)&7],ST[(TOP+6)&7],ST[(TOP+7)&7]);
|
||||
pclog("\tST(0)=%.20f\tST(1)=%.20f\tST(2)=%f\tST(3)=%f\t",ST[TOP&7],ST[(TOP+1)&7],ST[(TOP+2)&7],ST[(TOP+3)&7]);
|
||||
pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t TOP=%i CR=%04X SR=%04X TAG=%04X\n",ST[(TOP+4)&7],ST[(TOP+5)&7],ST[(TOP+6)&7],ST[(TOP+7)&7], TOP, npxc, npxs, tag);
|
||||
}
|
||||
|
||||
void x87_push(double i)
|
||||
|
|
@ -186,16 +213,19 @@ void x87_d8()
|
|||
{
|
||||
case 0xC0: case 0xC1: case 0xC2: case 0xC3: /*FADD*/
|
||||
case 0xC4: case 0xC5: case 0xC6: case 0xC7:
|
||||
if (fplog) pclog("FADD\n");
|
||||
ST(0)=ST(0)+ST(rmdat32&7);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xC8: case 0xC9: case 0xCA: case 0xCB: /*FMUL*/
|
||||
case 0xCC: case 0xCD: case 0xCE: case 0xCF:
|
||||
if (fplog) pclog("FMUL\n");
|
||||
ST(0)=ST(0)*ST(rmdat32&7);
|
||||
cycles-=16;
|
||||
return;
|
||||
case 0xD0: case 0xD1: case 0xD2: case 0xD3: /*FCOM*/
|
||||
case 0xD4: case 0xD5: case 0xD6: case 0xD7:
|
||||
if (fplog) pclog("FCOM\n");
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==ST(rmdat32&7)) npxs|=C3;
|
||||
else if (ST(0)<ST(rmdat32&7)) npxs|=C0;
|
||||
|
|
@ -203,6 +233,7 @@ void x87_d8()
|
|||
return;
|
||||
case 0xD8: case 0xD9: case 0xDA: case 0xDB: /*FCOMP*/
|
||||
case 0xDC: case 0xDD: case 0xDE: case 0xDF:
|
||||
if (fplog) pclog("FCOMP\n");
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==ST(rmdat32&7)) npxs|=C3;
|
||||
else if (ST(0)<ST(rmdat32&7)) npxs|=C0;
|
||||
|
|
@ -211,22 +242,26 @@ void x87_d8()
|
|||
return;
|
||||
case 0xE0: case 0xE1: case 0xE2: case 0xE3: /*FSUB*/
|
||||
case 0xE4: case 0xE5: case 0xE6: case 0xE7:
|
||||
if (fplog) pclog("FSUB\n");
|
||||
ST(0)=ST(0)-ST(rmdat32&7);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xE8: case 0xE9: case 0xEA: case 0xEB: /*FSUBR*/
|
||||
case 0xEC: case 0xED: case 0xEE: case 0xEF:
|
||||
if (fplog) pclog("FSUBR\n");
|
||||
ST(0)=ST(rmdat32&7)-ST(0);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xF0: case 0xF1: case 0xF2: case 0xF3: /*FDIV*/
|
||||
case 0xF4: case 0xF5: case 0xF6: case 0xF7:
|
||||
ST(0)=ST(0)/ST(rmdat32&7);
|
||||
if (fplog) pclog("FDIV\n");
|
||||
x87_div(ST(0), ST(0), ST(rmdat32&7));
|
||||
cycles-=73;
|
||||
return;
|
||||
case 0xF8: case 0xF9: case 0xFA: case 0xFB: /*FDIVR*/
|
||||
case 0xFC: case 0xFD: case 0xFE: case 0xFF:
|
||||
ST(0)=ST(rmdat32&7)/ST(0);
|
||||
if (fplog) pclog("FDIVR\n");
|
||||
x87_div(ST(0), ST(rmdat32&7), ST(0));
|
||||
cycles-=73;
|
||||
return;
|
||||
}
|
||||
|
|
@ -237,20 +272,25 @@ void x87_d8()
|
|||
switch (reg)
|
||||
{
|
||||
case 0: /*FADD short*/
|
||||
if (fplog) pclog("FADDs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s);
|
||||
ST(0)+=ts.s;
|
||||
cycles-=8;
|
||||
return;
|
||||
case 1: /*FMUL short*/
|
||||
if (fplog) pclog("FMULs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s);
|
||||
ST(0)*=ts.s;
|
||||
cycles-=11;
|
||||
if (abrt) pclog("ABRT FMUL\n");
|
||||
return;
|
||||
case 2: /*FCOM short*/
|
||||
if (fplog) pclog("FCOMs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s);
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==ts.s) npxs|=C3;
|
||||
else if (ST(0)<ts.s) npxs|=C0;
|
||||
cycles-=4;
|
||||
return;
|
||||
case 3: /*FCOMP short*/
|
||||
if (fplog) pclog("FCOMPs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s);
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==ts.s) npxs|=C3;
|
||||
else if (ST(0)<ts.s) npxs|=C0;
|
||||
|
|
@ -258,19 +298,23 @@ void x87_d8()
|
|||
x87_pop();
|
||||
return;
|
||||
case 4: /*FSUB short*/
|
||||
if (fplog) pclog("FSUBs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s);
|
||||
ST(0)-=ts.s;
|
||||
cycles-=8;
|
||||
return;
|
||||
case 5: /*FSUBR short*/
|
||||
if (fplog) pclog("FSUBRs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s);
|
||||
ST(0)=ts.s-ST(0);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 6: /*FDIV short*/
|
||||
ST(0)=ST(0)/ts.s;
|
||||
if (fplog) pclog("FDIVs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s);
|
||||
x87_div(ST(0), ST(0), ts.s);
|
||||
cycles-=73;
|
||||
return;
|
||||
case 7: /*FDIVR short*/
|
||||
ST(0)=ts.s/ST(0);
|
||||
if (fplog) pclog("FDIVRs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s);
|
||||
x87_div(ST(0), ts.s, ST(0));
|
||||
cycles-=73;
|
||||
return;
|
||||
}
|
||||
|
|
@ -285,7 +329,6 @@ void x87_d9()
|
|||
float s;
|
||||
uint32_t i;
|
||||
} ts;
|
||||
float t;
|
||||
double td;
|
||||
int64_t temp64;
|
||||
uint16_t tempw;
|
||||
|
|
@ -295,82 +338,99 @@ void x87_d9()
|
|||
{
|
||||
case 0xC0: case 0xC1: case 0xC2: case 0xC3: /*FLD*/
|
||||
case 0xC4: case 0xC5: case 0xC6: case 0xC7:
|
||||
if (fplog) pclog("FLD %f\n", ST(rmdat32 & 7));
|
||||
x87_push(ST(rmdat32&7));
|
||||
cycles-=4;
|
||||
return;
|
||||
case 0xC8: case 0xC9: case 0xCA: case 0xCB: /*FXCH*/
|
||||
case 0xCC: case 0xCD: case 0xCE: case 0xCF:
|
||||
if (fplog) pclog("FXCH\n");
|
||||
td=ST(0);
|
||||
ST(0)=ST(rmdat32&7);
|
||||
ST(rmdat32&7)=td;
|
||||
cycles-=4;
|
||||
return;
|
||||
case 0xD0: /*FNOP*/
|
||||
if (fplog) pclog("FNOP\n");
|
||||
cycles-=3;
|
||||
return;
|
||||
case 0xE0: /*FCHS*/
|
||||
if (fplog) pclog("FCHS\n");
|
||||
ST(0)=-ST(0);
|
||||
cycles-=6;
|
||||
return;
|
||||
case 0xE1: /*FABS*/
|
||||
if (fplog) pclog("FABS %f\n", ST(0));
|
||||
ST(0)=fabs(ST(0));
|
||||
cycles-=3;
|
||||
return;
|
||||
case 0xE4: /*FTST*/
|
||||
if (fplog) pclog("FTST\n");
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==0.0) npxs|=C3;
|
||||
else if (ST(0)<0.0) npxs|=C0;
|
||||
cycles-=4;
|
||||
return;
|
||||
case 0xE5: /*FXAM*/
|
||||
// pclog("FXAM %f %i\n",ST(0),(tag>>((TOP&1)<<1))&3);
|
||||
if (fplog) pclog("FXAM %i %f\n", ((tag>>((TOP&7)<<1))&3), ST(0));
|
||||
// pclog("FXAM %f %i\n",ST(0),(tag>>((TOP&7)<<1))&3);
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (((tag>>((TOP&1)<<1))&3)==3) npxs|=(C0|C3);
|
||||
if (((tag>>((TOP&7)<<1))&3)==3) npxs|=(C0|C3);
|
||||
else if (ST(0)==0.0) npxs|=C3;
|
||||
else npxs|=C2;
|
||||
if (ST(0)<0.0) npxs|=C1;
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xE8: /*FLD1*/
|
||||
if (fplog) pclog("FLD1\n");
|
||||
x87_push(1.0);
|
||||
cycles-=4;
|
||||
return;
|
||||
case 0xE9: /*FLDL2T*/
|
||||
if (fplog) pclog("FLDL2T\n");
|
||||
x87_push(3.3219280948873623);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xEA: /*FLDL2E*/
|
||||
if (fplog) pclog("FLDL2E\n");
|
||||
x87_push(1.4426950408889634);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xEB: /*FLDPI*/
|
||||
if (fplog) pclog("FLDPI\n");
|
||||
x87_push(3.141592653589793);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xEC: /*FLDEG2*/
|
||||
if (fplog) pclog("FLDEG2\n");
|
||||
x87_push(0.3010299956639812);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xED: /*FLDLN2*/
|
||||
if (fplog) pclog("FLDLN2\n");
|
||||
x87_push(0.693147180559945);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xEE: /*FLDZ*/
|
||||
if (fplog) pclog("FLDZ\n");
|
||||
// pclog("FLDZ %04X:%08X\n",CS,pc);
|
||||
x87_push(0.0);
|
||||
tag|=(1<<((TOP&7)<<1));
|
||||
cycles-=4;
|
||||
return;
|
||||
case 0xF0: /*F2XM1*/
|
||||
if (fplog) pclog("F2XM1\n");
|
||||
ST(0)=pow(2.0,ST(0))-1.0;
|
||||
cycles-=200;
|
||||
return;
|
||||
case 0xF1: /*FYL2X*/
|
||||
if (fplog) pclog("FYL2X\n");
|
||||
ST(1)=ST(1)*(log(ST(0))/log(2.0));
|
||||
x87_pop();
|
||||
cycles-=250;
|
||||
return;
|
||||
case 0xF2: /*FPTAN*/
|
||||
if (fplog) pclog("FPTAN\n");
|
||||
// pclog("Tan of %f = ",ST(0));
|
||||
ST(0)=tan(ST(0));
|
||||
// pclog("%f\n",ST(0));
|
||||
|
|
@ -379,20 +439,31 @@ void x87_d9()
|
|||
cycles-=235;
|
||||
return;
|
||||
case 0xF3: /*FPATAN*/
|
||||
if (fplog) pclog("FPATAN\n");
|
||||
/* times++;
|
||||
if (times==50)
|
||||
{
|
||||
dumpregs();
|
||||
exit(-1);
|
||||
}*/
|
||||
// pclog("FPATAN %08X\n",pc);
|
||||
ST(1)=atan2(ST(1),ST(0));
|
||||
x87_pop();
|
||||
cycles-=250;
|
||||
return;
|
||||
case 0xF6: /*FDECSTP*/
|
||||
if (fplog) pclog("FDECSTP\n");
|
||||
TOP=(TOP-1)&7;
|
||||
return;
|
||||
case 0xF7: /*FINCSTP*/
|
||||
if (fplog) pclog("FINCSTP\n");
|
||||
TOP=(TOP+1)&7;
|
||||
return;
|
||||
case 0xF8: /*FPREM*/
|
||||
if (fplog) pclog("FPREM %f %f ", ST(0), ST(1));
|
||||
temp64=(int64_t)(ST(0)/ST(1));
|
||||
ST(0)=ST(0)-(ST(1)*(double)temp64);
|
||||
if (fplog) pclog("%f\n", ST(0));
|
||||
npxs&=~(C0|C1|C2|C3);
|
||||
if (temp64&4) npxs|=C0;
|
||||
if (temp64&2) npxs|=C3;
|
||||
|
|
@ -400,10 +471,12 @@ void x87_d9()
|
|||
cycles-=100;
|
||||
return;
|
||||
case 0xFA: /*FSQRT*/
|
||||
if (fplog) pclog("FSQRT\n");
|
||||
ST(0)=sqrt(ST(0));
|
||||
cycles-=83;
|
||||
return;
|
||||
case 0xFB: /*FSINCOS*/
|
||||
if (fplog) pclog("FSINCOS\n");
|
||||
td=ST(0);
|
||||
ST(0)=sin(td);
|
||||
x87_push(cos(td));
|
||||
|
|
@ -411,22 +484,26 @@ void x87_d9()
|
|||
cycles-=330;
|
||||
return;
|
||||
case 0xFC: /*FRNDINT*/
|
||||
if (fplog) pclog("FRNDINT\n");
|
||||
// pclog("FRNDINT %f %i ",ST(0),(npxc>>10)&3);
|
||||
ST(0)=(double)x87_fround(ST(0));
|
||||
// pclog("%f\n",ST(0));
|
||||
cycles-=21;
|
||||
return;
|
||||
case 0xFD: /*FSCALE*/
|
||||
if (fplog) pclog("FSCALE\n");
|
||||
temp64=(int64_t)ST(1);
|
||||
ST(0)=ST(0)*pow(2.0,(double)temp64);
|
||||
cycles-=30;
|
||||
return;
|
||||
case 0xFE: /*FSIN*/
|
||||
if (fplog) pclog("FSIN\n");
|
||||
ST(0)=sin(ST(0));
|
||||
npxs&=~C2;
|
||||
cycles-=300;
|
||||
return;
|
||||
case 0xFF: /*FCOS*/
|
||||
if (fplog) pclog("FCOS\n");
|
||||
ST(0)=cos(ST(0));
|
||||
npxs&=~C2;
|
||||
cycles-=300;
|
||||
|
|
@ -438,24 +515,30 @@ void x87_d9()
|
|||
switch (reg)
|
||||
{
|
||||
case 0: /*FLD single-precision*/
|
||||
if (fplog) pclog("FLDs %08X:%08X\n", easeg, eaaddr);
|
||||
// if ((rmdat32&0xFFFF)==0xD445) { pclog("FLDS\n"); output=3; dumpregs(); exit(-1); }
|
||||
ts.i=(float)geteal(); if (abrt) return;
|
||||
ts.i=geteal(); if (abrt) { pclog("FLD sp abort\n"); return; }
|
||||
if (fplog) pclog(" %f\n", ts.s);
|
||||
x87_push((double)ts.s);
|
||||
cycles-=3;
|
||||
return;
|
||||
case 2: /*FST single-precision*/
|
||||
if (fplog) pclog("FSTs %08X:%08X\n", easeg, eaaddr);
|
||||
ts.s=(float)ST(0);
|
||||
seteal(ts.i);
|
||||
if (abrt) { pclog("FST sp abort\n"); return; }
|
||||
cycles-=7;
|
||||
return;
|
||||
case 3: /*FSTP single-precision*/
|
||||
if (fplog) pclog("FSTPs %08X:%08X\n", easeg, eaaddr);
|
||||
ts.s=(float)ST(0);
|
||||
seteal(ts.i); if (abrt) return;
|
||||
seteal(ts.i); if (abrt) { pclog("FSTP sp abort\n"); return; }
|
||||
// if (pc==0x3f50c) pclog("FSTP %f %f %08X\n",ST(0),ts.s,ts.i);
|
||||
x87_pop();
|
||||
cycles-=7;
|
||||
return;
|
||||
case 4: /*FLDENV*/
|
||||
if (fplog) pclog("FLDENV %08X:%08X\n", easeg, eaaddr);
|
||||
switch ((cr0&1)|(op32&0x100))
|
||||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
|
|
@ -474,14 +557,17 @@ void x87_d9()
|
|||
break;
|
||||
}
|
||||
cycles-=(cr0&1)?34:44;
|
||||
if (abrt) { pclog("FLDENV\n"); return; }
|
||||
return;
|
||||
case 5: /*FLDCW*/
|
||||
if (fplog) pclog("FLDCW %08X:%08X\n", easeg, eaaddr);
|
||||
tempw=geteaw();
|
||||
if (abrt) return;
|
||||
if (abrt) if (abrt) { pclog("FLDCW abort\n"); return; }
|
||||
npxc=tempw;
|
||||
cycles-=4;
|
||||
return;
|
||||
case 6: /*FSTENV*/
|
||||
if (fplog) pclog("FSTENV %08X:%08X\n", easeg, eaaddr);
|
||||
switch ((cr0&1)|(op32&0x100))
|
||||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
|
|
@ -518,10 +604,13 @@ void x87_d9()
|
|||
writememl(easeg,eaaddr+24,x87_op_seg);
|
||||
break;
|
||||
}
|
||||
if (abrt) { pclog("FSTENV\n"); return; }
|
||||
cycles-=(cr0&1)?56:67;
|
||||
return;
|
||||
case 7: /*FSTCW*/
|
||||
if (fplog) pclog("FSTCW %08X:%08X\n", easeg, eaaddr);
|
||||
seteaw(npxc);
|
||||
if (abrt) { pclog("FSTCW\n"); return; }
|
||||
cycles-=3;
|
||||
return;
|
||||
}
|
||||
|
|
@ -537,6 +626,7 @@ void x87_da()
|
|||
switch (rmdat32&0xFF)
|
||||
{
|
||||
case 0xE9: /*FUCOMPP*/
|
||||
if (fplog) pclog("FUCOMPP\n", easeg, eaaddr);
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==ST(1)) npxs|=C3;
|
||||
else if (ST(0)<ST(1)) npxs|=C0;
|
||||
|
|
@ -548,24 +638,28 @@ void x87_da()
|
|||
}
|
||||
else
|
||||
{
|
||||
templ=geteal(); if (abrt) return;
|
||||
templ=(int32_t)geteal(); if (abrt) return;
|
||||
switch (reg)
|
||||
{
|
||||
case 0: /*FIADD*/
|
||||
if (fplog) pclog("FIADDl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
ST(0)=ST(0)+(double)templ;
|
||||
cycles-=20;
|
||||
return;
|
||||
case 1: /*FIMUL*/
|
||||
if (fplog) pclog("FIMULl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
ST(0)=ST(0)*(double)templ;
|
||||
cycles-=22;
|
||||
return;
|
||||
case 2: /*FICOM*/
|
||||
if (fplog) pclog("FICOMl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==(double)templ) npxs|=C3;
|
||||
else if (ST(0)<(double)templ) npxs|=C0;
|
||||
cycles-=15;
|
||||
return;
|
||||
case 3: /*FICOMP*/
|
||||
if (fplog) pclog("FICOMPl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==(double)templ) npxs|=C3;
|
||||
else if (ST(0)<(double)templ) npxs|=C0;
|
||||
|
|
@ -573,19 +667,23 @@ void x87_da()
|
|||
cycles-=15;
|
||||
return;
|
||||
case 4: /*FISUB*/
|
||||
if (fplog) pclog("FISUBl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
ST(0)=ST(0)-(double)templ;
|
||||
cycles-=20;
|
||||
return;
|
||||
case 5: /*FISUBR*/
|
||||
if (fplog) pclog("FISUBRl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
ST(0)=(double)templ-ST(0);
|
||||
cycles-=19;
|
||||
return;
|
||||
case 6: /*FIDIV*/
|
||||
ST(0)=ST(0)/(double)templ;
|
||||
if (fplog) pclog("FIDIVl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
x87_div(ST(0), ST(0), (double)templ);
|
||||
cycles-=84;
|
||||
return;
|
||||
case 7: /*FIDIVR*/
|
||||
ST(0)=(double)templ/ST(0);
|
||||
if (fplog) pclog("FIDIVRl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
x87_div(ST(0), (double)templ, ST(0));
|
||||
cycles-=84;
|
||||
return;
|
||||
}
|
||||
|
|
@ -597,6 +695,7 @@ void x87_db()
|
|||
{
|
||||
double t;
|
||||
int32_t templ;
|
||||
int64_t temp64;
|
||||
if (mod==3)
|
||||
{
|
||||
switch (reg)
|
||||
|
|
@ -607,9 +706,11 @@ void x87_db()
|
|||
case 0xE1:
|
||||
return;
|
||||
case 0xE2: /*FCLEX*/
|
||||
if (fplog) pclog("FCLEX\n");
|
||||
npxs&=0xFF00;
|
||||
return;
|
||||
case 0xE3: /*FINIT*/
|
||||
if (fplog) pclog("FINIT\n");
|
||||
npxc=0x37F;
|
||||
npxs=0;
|
||||
tag=0xFFFF;
|
||||
|
|
@ -627,25 +728,38 @@ void x87_db()
|
|||
switch (reg)
|
||||
{
|
||||
case 0: /*FILD short*/
|
||||
if (fplog) pclog("FILDs %08X:%08X\n", easeg, eaaddr);
|
||||
templ=geteal(); if (abrt) return;
|
||||
if (fplog) pclog(" %f %08X %i\n", (double)templ, templ, templ);
|
||||
x87_push((double)templ);
|
||||
cycles-=9;
|
||||
return;
|
||||
case 2: /*FIST short*/
|
||||
seteal((int32_t)x87_fround(ST(0)));
|
||||
if (fplog) pclog("FISTs %08X:%08X\n", easeg, eaaddr);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 2147483647 || temp64 < -2147483647)
|
||||
fatal("FISTl out of range! %i\n", temp64);*/
|
||||
seteal((int32_t)temp64);
|
||||
cycles-=28;
|
||||
return;
|
||||
case 3: /*FISTP short*/
|
||||
seteal((int32_t)x87_fround(ST(0))); if (abrt) return;
|
||||
if (fplog) pclog("FISTPs %08X:%08X\n", easeg, eaaddr);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 2147483647 || temp64 < -2147483647)
|
||||
fatal("FISTPl out of range! %i\n", temp64);*/
|
||||
seteal((int32_t)temp64); if (abrt) return;
|
||||
x87_pop();
|
||||
cycles-=28;
|
||||
return;
|
||||
case 5: /*FLD extended*/
|
||||
if (fplog) pclog("FLDe %08X:%08X\n", easeg, eaaddr);
|
||||
t=x87_ld80(); if (abrt) return;
|
||||
if (fplog) pclog(" %f\n", t);
|
||||
x87_push(t);
|
||||
cycles-=6;
|
||||
return;
|
||||
case 7: /*FSTP extended*/
|
||||
if (fplog) pclog("FSTPe %08X:%08X\n", easeg, eaaddr);
|
||||
x87_st80(ST(0)); if (abrt) return;
|
||||
x87_pop();
|
||||
cycles-=6;
|
||||
|
|
@ -668,32 +782,38 @@ void x87_dc()
|
|||
{
|
||||
case 0xC0: case 0xC1: case 0xC2: case 0xC3: /*FADD*/
|
||||
case 0xC4: case 0xC5: case 0xC6: case 0xC7:
|
||||
if (fplog) pclog("FADD %f %f\n", ST(rmdat32 & 7), ST(0));
|
||||
ST(rmdat32&7)=ST(rmdat32&7)+ST(0);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xC8: case 0xC9: case 0xCA: case 0xCB: /*FMUL*/
|
||||
case 0xCC: case 0xCD: case 0xCE: case 0xCF:
|
||||
if (fplog) pclog("FMUL %f %f\n", ST(rmdat32 & 7), ST(0));
|
||||
ST(rmdat32&7)=ST(rmdat32&7)*ST(0);
|
||||
cycles-=16;
|
||||
return;
|
||||
case 0xE0: case 0xE1: case 0xE2: case 0xE3: /*FSUBR*/
|
||||
case 0xE4: case 0xE5: case 0xE6: case 0xE7:
|
||||
if (fplog) pclog("FSUBR %f %f\n", ST(rmdat32 & 7), ST(0));
|
||||
ST(rmdat32&7)=ST(0)-ST(rmdat32&7);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xE8: case 0xE9: case 0xEA: case 0xEB: /*FSUB*/
|
||||
case 0xEC: case 0xED: case 0xEE: case 0xEF:
|
||||
if (fplog) pclog("FSUB %f %f\n", ST(rmdat32 & 7), ST(0));
|
||||
ST(rmdat32&7)=ST(rmdat32&7)-ST(0);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xF0: case 0xF1: case 0xF2: case 0xF3: /*FDIVR*/
|
||||
case 0xF4: case 0xF5: case 0xF6: case 0xF7:
|
||||
ST(rmdat32&7)=ST(0)/ST(rmdat32&7);
|
||||
if (fplog) pclog("FDIVR %f %f\n", ST(rmdat32 & 7), ST(0));
|
||||
x87_div(ST(rmdat32&7), ST(0), ST(rmdat32&7));
|
||||
cycles-=73;
|
||||
return;
|
||||
case 0xF8: case 0xF9: case 0xFA: case 0xFB: /*FDIV*/
|
||||
case 0xFC: case 0xFD: case 0xFE: case 0xFF:
|
||||
ST(rmdat32&7)=ST(rmdat32&7)/ST(0);
|
||||
if (fplog) pclog("FDIV %f %f\n", ST(rmdat32 & 7), ST(0));
|
||||
x87_div(ST(rmdat32&7), ST(rmdat32&7), ST(0));
|
||||
cycles-=73;
|
||||
return;
|
||||
}
|
||||
|
|
@ -706,20 +826,24 @@ void x87_dc()
|
|||
switch (reg)
|
||||
{
|
||||
case 0: /*FADD double*/
|
||||
if (fplog) pclog("FADDd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d);
|
||||
ST(0)+=t.d;
|
||||
cycles-=8;
|
||||
return;
|
||||
case 1: /*FMUL double*/
|
||||
if (fplog) pclog("FMULd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d);
|
||||
ST(0)*=t.d;
|
||||
cycles-=14;
|
||||
return;
|
||||
case 2: /*FCOM double*/
|
||||
if (fplog) pclog("FCOMd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d);
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==t.d) npxs|=C3;
|
||||
else if (ST(0)<t.d) npxs|=C0;
|
||||
cycles-=4;
|
||||
return;
|
||||
case 3: /*FCOMP double*/
|
||||
if (fplog) pclog("FCOMPd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d);
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==t.d) npxs|=C3;
|
||||
else if (ST(0)<t.d) npxs|=C0;
|
||||
|
|
@ -727,19 +851,23 @@ void x87_dc()
|
|||
x87_pop();
|
||||
return;
|
||||
case 4: /*FSUB double*/
|
||||
if (fplog) pclog("FSUBd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d);
|
||||
ST(0)-=t.d;
|
||||
cycles-=8;
|
||||
return;
|
||||
case 5: /*FSUBR double*/
|
||||
if (fplog) pclog("FSUBRd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d);
|
||||
ST(0)=t.d-ST(0);
|
||||
cycles-=8;
|
||||
return;
|
||||
case 6: /*FDIV double*/
|
||||
ST(0)=ST(0)/t.d;
|
||||
if (fplog) pclog("FDIVd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d);
|
||||
x87_div(ST(0), ST(0), t.d);
|
||||
cycles-=73;
|
||||
return;
|
||||
case 7: /*FDIVR double*/
|
||||
ST(0)=t.d/ST(0);
|
||||
if (fplog) pclog("FDIVRd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d);
|
||||
x87_div(ST(0), t.d, ST(0));
|
||||
cycles-=73;
|
||||
return;
|
||||
}
|
||||
|
|
@ -760,10 +888,12 @@ void x87_dd()
|
|||
switch (reg)
|
||||
{
|
||||
case 0: /*FFREE*/
|
||||
if (fplog) pclog("FFREE\n");
|
||||
tag|=(3<<((rmdat32&7)<<1));
|
||||
cycles-=3;
|
||||
return;
|
||||
case 2: /*FST*/
|
||||
if (fplog) pclog("FST\n");
|
||||
ST(rmdat32&7)=ST(0);
|
||||
temp=(tag>>((TOP&7)<<1))&3;
|
||||
tag&=~(3<<((rmdat32&7)<<1));
|
||||
|
|
@ -771,6 +901,7 @@ void x87_dd()
|
|||
cycles-=3;
|
||||
return;
|
||||
case 3: /*FSTP*/
|
||||
if (fplog) pclog("FSTP\n");
|
||||
ST(rmdat32&7)=ST(0);
|
||||
temp=(tag>>((TOP&7)<<1))&3;
|
||||
tag&=~(3<<((rmdat32&7)<<1));
|
||||
|
|
@ -779,12 +910,14 @@ void x87_dd()
|
|||
cycles-=3;
|
||||
return;
|
||||
case 4: /*FUCOM*/
|
||||
if (fplog) pclog("FUCOM\n");
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==ST(rmdat32&7)) npxs|=C3;
|
||||
else if (ST(0)<ST(rmdat32&7)) npxs|=C0;
|
||||
cycles-=4;
|
||||
return;
|
||||
case 5: /*FUCOMP*/
|
||||
if (fplog) pclog("FUCOMP\n");
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==ST(rmdat32&7)) npxs|=C3;
|
||||
else if (ST(0)<ST(rmdat32&7)) npxs|=C0;
|
||||
|
|
@ -798,18 +931,22 @@ void x87_dd()
|
|||
switch (reg)
|
||||
{
|
||||
case 0: /*FLD double-precision*/
|
||||
if (fplog) pclog("FLDd %08X:%08X\n", easeg, eaaddr);
|
||||
t.i=readmeml(easeg,eaaddr);
|
||||
t.i|=(uint64_t)readmeml(easeg,eaaddr+4)<<32; if (abrt) return;
|
||||
if (fplog) pclog(" %f\n", t.d);
|
||||
x87_push(t.d);
|
||||
cycles-=3;
|
||||
return;
|
||||
case 2: /*FST double-precision*/
|
||||
if (fplog) pclog("FSTd %08X:%08X\n", easeg, eaaddr);
|
||||
t.d=ST(0);
|
||||
writememl(easeg,eaaddr,t.i);
|
||||
writememl(easeg,eaaddr+4,(t.i>>32));
|
||||
cycles-=8;
|
||||
return;
|
||||
case 3: /*FSTP double-precision*/
|
||||
if (fplog) pclog("FSTPd %08X:%08X\n", easeg, eaaddr);
|
||||
t.d=ST(0);
|
||||
writememl(easeg,eaaddr,t.i);
|
||||
writememl(easeg,eaaddr+4,(t.i>>32)); if (abrt) return;
|
||||
|
|
@ -817,6 +954,7 @@ void x87_dd()
|
|||
cycles-=8;
|
||||
return;
|
||||
case 4: /*FRSTOR*/
|
||||
if (fplog) pclog("FRSTOR %08X:%08X\n", easeg, eaaddr);
|
||||
switch ((cr0&1)|(op32&0x100))
|
||||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
|
|
@ -847,6 +985,7 @@ void x87_dd()
|
|||
cycles-=(cr0&1)?34:44;
|
||||
return;
|
||||
case 6: /*FSAVE*/
|
||||
if (fplog) pclog("FSAVE %08X:%08X\n", easeg, eaaddr);
|
||||
switch ((cr0&1)|(op32&0x100))
|
||||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
|
|
@ -922,6 +1061,7 @@ void x87_dd()
|
|||
cycles-=(cr0&1)?56:67;
|
||||
return;
|
||||
case 7: /*FSTSW*/
|
||||
if (fplog) pclog("FSTSW %08X:%08X\n", easeg, eaaddr);
|
||||
seteaw((npxs&0xC7FF)|(TOP<<11));
|
||||
cycles-=3;
|
||||
return;
|
||||
|
|
@ -932,7 +1072,6 @@ void x87_dd()
|
|||
}
|
||||
void x87_de()
|
||||
{
|
||||
double t;
|
||||
int32_t templ;
|
||||
if (mod==3)
|
||||
{
|
||||
|
|
@ -940,17 +1079,20 @@ void x87_de()
|
|||
{
|
||||
case 0xC0: case 0xC1: case 0xC2: case 0xC3: /*FADDP*/
|
||||
case 0xC4: case 0xC5: case 0xC6: case 0xC7:
|
||||
ST(rmdat32&7)=ST(rmdat32&7)+ST[TOP];
|
||||
if (fplog) pclog("FADDP %f %f\n", ST(rmdat32 & 7), ST(0));
|
||||
ST(rmdat32&7)=ST(rmdat32&7)+ST(0);
|
||||
x87_pop();
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xC8: case 0xC9: case 0xCA: case 0xCB: /*FMULP*/
|
||||
case 0xCC: case 0xCD: case 0xCE: case 0xCF:
|
||||
ST(rmdat32&7)=ST(rmdat32&7)*ST[TOP];
|
||||
if (fplog) pclog("FMULP %f %f\n", ST(rmdat32 & 7), ST(0));
|
||||
ST(rmdat32&7)=ST(rmdat32&7)*ST(0);
|
||||
x87_pop();
|
||||
cycles-=16;
|
||||
return;
|
||||
case 0xD9: /*FCOMPP*/
|
||||
if (fplog) pclog("FCOMPP %f %f\n", ST(0), ST(1));
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==ST(1)) npxs|=C3;
|
||||
else if (ST(0)<ST(1)) npxs|=C0;
|
||||
|
|
@ -960,25 +1102,29 @@ void x87_de()
|
|||
return;
|
||||
case 0xE0: case 0xE1: case 0xE2: case 0xE3: /*FSUBRP*/
|
||||
case 0xE4: case 0xE5: case 0xE6: case 0xE7:
|
||||
if (fplog) pclog("FSUBRP %f %f\n", ST(rmdat32 & 7), ST(0));
|
||||
ST(rmdat32&7)=ST(0)-ST(rmdat32&7);
|
||||
x87_pop();
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xE8: case 0xE9: case 0xEA: case 0xEB: /*FSUBP*/
|
||||
case 0xEC: case 0xED: case 0xEE: case 0xEF:
|
||||
ST(rmdat32&7)=ST(rmdat32&7)-ST[TOP];
|
||||
if (fplog) pclog("FSUBP %f %f\n", ST(rmdat32 & 7), ST(0));
|
||||
ST(rmdat32&7)=ST(rmdat32&7)-ST(0);
|
||||
x87_pop();
|
||||
cycles-=8;
|
||||
return;
|
||||
case 0xF0: case 0xF1: case 0xF2: case 0xF3: /*FDIVRP*/
|
||||
case 0xF4: case 0xF5: case 0xF6: case 0xF7:
|
||||
ST(rmdat32&7)=ST(0)/ST(rmdat32&7);
|
||||
if (fplog) pclog("FDIVRP %f %f\n", ST(rmdat32 & 7), ST(0));
|
||||
x87_div(ST(rmdat32&7), ST(0), ST(rmdat32&7));
|
||||
x87_pop();
|
||||
cycles-=73;
|
||||
return;
|
||||
case 0xF8: case 0xF9: case 0xFA: case 0xFB: /*FDIVP*/
|
||||
case 0xFC: case 0xFD: case 0xFE: case 0xFF:
|
||||
ST(rmdat32&7)=ST(rmdat32&7)/ST[TOP];
|
||||
if (fplog) pclog("FDIVP %f %f %i\n", ST(rmdat32 & 7), ST(0), rmdat32 & 7);
|
||||
x87_div(ST(rmdat32&7), ST(rmdat32&7), ST(0));
|
||||
x87_pop();
|
||||
cycles-=73;
|
||||
return;
|
||||
|
|
@ -986,24 +1132,28 @@ void x87_de()
|
|||
}
|
||||
else
|
||||
{
|
||||
templ=(int32_t)geteaw(); if (abrt) return;
|
||||
templ=(int32_t)(int16_t)geteaw(); if (abrt) return;
|
||||
switch (reg)
|
||||
{
|
||||
case 0: /*FIADD*/
|
||||
if (fplog) pclog("FIADDw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
ST(0)=ST(0)+(double)templ;
|
||||
cycles-=20;
|
||||
return;
|
||||
case 1: /*FIMUL*/
|
||||
if (fplog) pclog("FIMULw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
ST(0)=ST(0)*(double)templ;
|
||||
cycles-=22;
|
||||
return;
|
||||
case 2: /*FICOM*/
|
||||
if (fplog) pclog("FICOMw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==(double)templ) npxs|=C3;
|
||||
else if (ST(0)<(double)templ) npxs|=C0;
|
||||
cycles-=15;
|
||||
return;
|
||||
case 3: /*FICOMP*/
|
||||
if (fplog) pclog("FICOMPw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
npxs&=~(C0|C2|C3);
|
||||
if (ST(0)==(double)templ) npxs|=C3;
|
||||
else if (ST(0)<(double)templ) npxs|=C0;
|
||||
|
|
@ -1011,19 +1161,23 @@ void x87_de()
|
|||
cycles-=15;
|
||||
return;
|
||||
case 4: /*FISUB*/
|
||||
if (fplog) pclog("FISUBw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
ST(0)=ST(0)-(double)templ;
|
||||
cycles-=20;
|
||||
return;
|
||||
case 5: /*FISUBR*/
|
||||
if (fplog) pclog("FISUBRw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
ST(0)=(double)templ-ST(0);
|
||||
cycles-=19;
|
||||
return;
|
||||
case 6: /*FIDIV*/
|
||||
ST(0)=ST(0)/(double)templ;
|
||||
if (fplog) pclog("FIDIVw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
x87_div(ST(0), ST(0), (double)templ);
|
||||
cycles-=84;
|
||||
return;
|
||||
case 7: /*FIDIVR*/
|
||||
ST(0)=(double)templ/ST(0);
|
||||
if (fplog) pclog("FIDIVRw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ);
|
||||
x87_div(ST(0), (double)templ, ST(0));
|
||||
cycles-=84;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1046,6 +1200,7 @@ void x87_df()
|
|||
switch (rmdat32&0xFF)
|
||||
{
|
||||
case 0xE0: /*FSTSW AX*/
|
||||
if (fplog) pclog("FSTSW\n");
|
||||
AX=npxs;
|
||||
cycles-=3;
|
||||
return;
|
||||
|
|
@ -1058,29 +1213,42 @@ void x87_df()
|
|||
switch (reg)
|
||||
{
|
||||
case 0: /*FILD short*/
|
||||
if (fplog) pclog("FILDw %08X:%08X\n", easeg, eaaddr);
|
||||
temp16=geteaw(); if (abrt) return;
|
||||
if (fplog) pclog(" %f\n", (double)temp16);
|
||||
x87_push((double)temp16);
|
||||
cycles-=13;
|
||||
return;
|
||||
case 2: /*FIST word*/
|
||||
temp16=x87_fround(ST(0));
|
||||
seteaw(temp16);
|
||||
if (fplog) pclog("FISTw %08X:%08X\n", easeg, eaaddr);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 32767 || temp64 < -32768)
|
||||
fatal("FISTw overflow %i\n", temp64);*/
|
||||
seteaw((int16_t)temp64);
|
||||
cycles-=29;
|
||||
return;
|
||||
case 3: /*FISTP word*/
|
||||
temp16=x87_fround(ST(0));
|
||||
seteaw(temp16); if (abrt) return;
|
||||
if (fplog) pclog("FISTPw %08X:%08X\n", easeg, eaaddr);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 32767 || temp64 < -32768)
|
||||
fatal("FISTw overflow %i\n", temp64);*/
|
||||
seteaw((int16_t)temp64); if (abrt) return;
|
||||
x87_pop();
|
||||
cycles-=29;
|
||||
return;
|
||||
case 5: /*FILD long*/
|
||||
if (fplog) pclog("FILDl %08X:%08X\n", easeg, eaaddr);
|
||||
temp64=geteal(); if (abrt) return;
|
||||
temp64|=(uint64_t)readmeml(easeg,eaaddr+4)<<32;
|
||||
if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,eaaddr), readmeml(easeg,eaaddr+4));
|
||||
x87_push((double)temp64);
|
||||
cycles-=10;
|
||||
return;
|
||||
case 6: /*FBSTP*/
|
||||
if (fplog) pclog("FBSTP %08X:%08X\n", easeg, eaaddr);
|
||||
tempd=ST(0);
|
||||
if (tempd < 0.0)
|
||||
tempd = -tempd;
|
||||
for (c=0;c<9;c++)
|
||||
{
|
||||
tempc=(uint8_t)floor(fmod(tempd,10.0)); tempd-=floor(fmod(tempd,10.0)); tempd/=10.0;
|
||||
|
|
@ -1088,11 +1256,12 @@ void x87_df()
|
|||
writememb(easeg,eaaddr+c,tempc);
|
||||
}
|
||||
tempc=(uint8_t)floor(fmod(tempd,10.0));
|
||||
if (tempd<0.0) tempc|=0x80;
|
||||
if (ST(0)<0.0) tempc|=0x80;
|
||||
writememb(easeg,eaaddr+9,tempc); if (abrt) return;
|
||||
x87_pop();
|
||||
return;
|
||||
case 7: /*FISTP long*/
|
||||
if (fplog) pclog("FISTPl %08X:%08X\n", easeg, eaaddr);
|
||||
temp64=x87_fround(ST(0));
|
||||
seteal(temp64);
|
||||
writememl(easeg,eaaddr+4,temp64>>32); if (abrt) return;
|
||||
|
|
|
|||
11
src/xtide.c
11
src/xtide.c
|
|
@ -1,10 +1,12 @@
|
|||
#include "ibm.h"
|
||||
#include "xtide.h"
|
||||
|
||||
#include "io.h"
|
||||
#include "ide.h"
|
||||
#include "xtide.h"
|
||||
|
||||
uint8_t xtide_high;
|
||||
|
||||
void xtide_write(uint16_t port, uint8_t val)
|
||||
void xtide_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
switch (port & 0xf)
|
||||
{
|
||||
|
|
@ -27,7 +29,7 @@ void xtide_write(uint16_t port, uint8_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t xtide_read(uint16_t port)
|
||||
uint8_t xtide_read(uint16_t port, void *priv)
|
||||
{
|
||||
uint16_t tempw;
|
||||
switch (port & 0xf)
|
||||
|
|
@ -51,5 +53,6 @@ uint8_t xtide_read(uint16_t port)
|
|||
|
||||
void xtide_init()
|
||||
{
|
||||
io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL);
|
||||
ide_init();
|
||||
io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue