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:
TomW 2013-05-27 17:46:42 +01:00
commit 9312de19ac
87 changed files with 4528 additions and 9373 deletions

7748
src/386.c

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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)
{

View file

@ -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
View file

@ -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;

View file

@ -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);

View file

@ -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
View file

@ -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);
}

View file

@ -1,4 +1,6 @@
void fdc_init();
void fdc_add();
void fdc_remove();
void fdc_reset();
void fdc_poll();
void fdc_abort();

View file

@ -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);
}

View file

@ -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
View file

@ -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;
}

View file

@ -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
View file

@ -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;

View file

@ -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);

View file

@ -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);
}

View file

@ -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])
{

View file

@ -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;

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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
View file

@ -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;
}

View file

@ -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();

View file

@ -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());

View file

@ -14,3 +14,7 @@ typedef struct
extern MODEL models[];
extern int model;
int model_getromset();
char *model_getname();
void model_init();

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -1 +1,3 @@
void nvr_init();
extern int nvr_dosave;

View file

@ -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
View file

@ -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");
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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();
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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();

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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();

View file

@ -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;

View file

@ -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);

View file

@ -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))

View file

@ -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*/

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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()

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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();

View file

@ -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)

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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
};

View file

@ -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);
}

View file

@ -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);

View file

@ -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()

View file

@ -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;

View file

@ -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);
}

View file

@ -1,4 +1,6 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "video.h"
BITMAP *screen;

227
src/win.c
View file

@ -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)
{

View file

@ -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();

View file

@ -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;
}

View file

@ -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
View file

@ -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;

View file

@ -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);
}