Removed ALLEGRO, per Kotori's OK.

Fixed serial driver, re-worked API and updated other files accordingly.
Fixed serial mouse driver for new serial port, prepared for Mouse Systems mode.
This commit is contained in:
waltje
2017-05-07 02:14:44 -04:00
parent 3f3471ee7e
commit 79bccfeb77
33 changed files with 858 additions and 2740 deletions

View File

@@ -180,7 +180,7 @@ LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \
# Build rules.
%.o: %.c
@echo $<
$(CC) $(CFLAGS) -c $<
@$(CC) $(CFLAGS) -c $<
%.o: %.cc
@echo $<

View File

@@ -1,639 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#include "ibm.h"
#include "device.h"
#include "allegro-main.h"
#include "allegro-gui.h"
#include "cpu.h"
#include "fdd.h"
#include "gameport.h"
#include "model.h"
#include "sound.h"
#include "video.h"
#include "vid_voodoo.h"
static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX];
static int settings_sound_to_list[20], settings_list_to_sound[20];
typedef struct allegro_list_t
{
char name[256];
int num;
} allegro_list_t;
static allegro_list_t model_list[ROM_MAX+1];
static allegro_list_t video_list[GFX_MAX+1];
static allegro_list_t sound_list[GFX_MAX+1];
static allegro_list_t cpumanu_list[4];
static allegro_list_t cpu_list[32];
static allegro_list_t joystick_list[32];
static char mem_size_str[10], mem_size_units[3];
static allegro_list_t cache_list[] =
{
{"A little", 0},
{"A bit", 1},
{"Some", 2},
{"A lot", 3},
{"Infinite", 4},
{"", -1}
};
static allegro_list_t vidspeed_list[] =
{
{"8-bit", 0},
{"Slow 16-bit", 1},
{"Fast 16-bit", 2},
{"Slow VLB/PCI", 3},
{"Mid VLB/PCI", 4},
{"Fast VLB/PCI", 5},
{"", -1}
};
static allegro_list_t fdd_list[] =
{
{"None", 0},
{"5.25\" 360k", 1},
{"5.25\" 1.2M", 2},
{"5.25\" 1.2M Dual RPM", 3},
{"3.5\" 720k", 4},
{"3.5\" 1.44M", 5},
{"3.5\" 1.44M 3-Mode", 6},
{"3.5\" 2.88M", 7},
{"", -1}
};
static void reset_list();
static char *list_proc_model(int index, int *list_size)
{
if (index < 0)
{
int c = 0;
while (model_list[c].name[0])
c++;
*list_size = c;
return NULL;
}
return model_list[index].name;
}
static char *list_proc_video(int index, int *list_size)
{
if (index < 0)
{
int c = 0;
while (video_list[c].name[0])
c++;
*list_size = c;
return NULL;
}
return video_list[index].name;
}
static char *list_proc_cache(int index, int *list_size)
{
if (index < 0)
{
int c = 0;
while (cache_list[c].name[0])
c++;
*list_size = c;
return NULL;
}
return cache_list[index].name;
}
static char *list_proc_vidspeed(int index, int *list_size)
{
if (index < 0)
{
int c = 0;
while (vidspeed_list[c].name[0])
c++;
*list_size = c;
return NULL;
}
return vidspeed_list[index].name;
}
static char *list_proc_sound(int index, int *list_size)
{
if (index < 0)
{
int c = 0;
while (sound_list[c].name[0])
c++;
*list_size = c;
return NULL;
}
return sound_list[index].name;
}
static char *list_proc_cpumanu(int index, int *list_size)
{
if (index < 0)
{
int c = 0;
while (cpumanu_list[c].name[0])
c++;
*list_size = c;
return NULL;
}
return cpumanu_list[index].name;
}
static char *list_proc_cpu(int index, int *list_size)
{
if (index < 0)
{
int c = 0;
while (cpu_list[c].name[0])
c++;
*list_size = c;
return NULL;
}
return cpu_list[index].name;
}
static char *list_proc_fdd(int index, int *list_size)
{
if (index < 0)
{
int c = 0;
while (fdd_list[c].name[0])
c++;
*list_size = c;
return NULL;
}
return fdd_list[index].name;
}
static char *list_proc_joystick(int index, int *list_size)
{
if (index < 0)
{
int c = 0;
while (joystick_list[c].name[0])
c++;
*list_size = c;
return NULL;
}
return joystick_list[index].name;
}
static int voodoo_config_proc(int msg, DIALOG *d, int c)
{
int ret = d_button_proc(msg, d, c);
if (ret == D_CLOSE)
{
deviceconfig_open(&voodoo_device);
return D_O_K;
}
return ret;
}
static int video_config_proc(int msg, DIALOG *d, int c);
static int sound_config_proc(int msg, DIALOG *d, int c);
static int list_proc(int msg, DIALOG *d, int c);
static DIALOG configure_dialog[] =
{
{d_shadow_box_proc, 0, 0, 568,352,0,0xffffff,0,0, 0,0,0,0,0}, // 0
{d_button_proc, 226, 328, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1
{d_button_proc, 296, 328, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2
{list_proc, 70*2, 12, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_model, 0, 0},
{list_proc, 70*2, 32, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_video, 0, 0},
{list_proc, 70*2, 52, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cpumanu, 0, 0}, //5
{list_proc, 70*2, 72, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cpu, 0, 0},
{d_list_proc, 70*2, 112, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cache, 0, 0},
{d_list_proc, 70*2, 132, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_vidspeed, 0, 0},
{list_proc, 70*2, 152, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_sound, 0, 0}, //9
{d_edit_proc, 70*2, 236, 32, 14, 0, 0xffffff, 0, 0, 3, 0, mem_size_str, 0, 0},
{d_text_proc, 98*2, 236, 40, 10, 0, 0xffffff, 0, 0, 0, 0, mem_size_units, 0, 0},
{d_check_proc, 14*2, 252, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "CMS / Game Blaster", 0, 0},
{d_check_proc, 14*2, 268, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Gravis Ultrasound", 0, 0},
{d_check_proc, 14*2, 284, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Innovation SSI-2001", 0, 0},
{d_check_proc, 14*2, 300, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Composite CGA", 0, 0},
{d_check_proc, 14*2, 316, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Voodoo Graphics", 0, 0},
{d_text_proc, 16*2, 16, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Machine :", 0, 0},
{d_text_proc, 16*2, 36, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Video :", 0, 0},
{d_text_proc, 16*2, 56, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "CPU type :", 0, 0},
{d_text_proc, 16*2, 76, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "CPU :", 0, 0},
{d_text_proc, 16*2, 116, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Cache :", 0, 0},
{d_text_proc, 16*2, 136, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Video speed :", 0, 0},
{d_text_proc, 16*2, 156, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Soundcard :", 0, 0},
{d_text_proc, 16*2, 236, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Memory :", 0, 0},
{d_check_proc, 14*2, 92, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Dynamic Recompiler", 0, 0},
{d_text_proc, 16*2, 176, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Drive A: :", 0, 0},
{d_text_proc, 16*2, 196, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Drive B: :", 0, 0},
{d_list_proc, 70*2, 172, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_fdd, 0, 0},
{d_list_proc, 70*2, 192, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_fdd, 0, 0},
{video_config_proc, 452, 32+4, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, //30
{sound_config_proc, 452, 152+4, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0},
{voodoo_config_proc, 452, 316, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0},
{d_text_proc, 16*2, 216, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Joystick :", 0, 0},
{d_list_proc, 70*2, 212, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_joystick, 0, 0}, //34
{0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL}
};
static int list_proc(int msg, DIALOG *d, int c)
{
int old = d->d1;
int ret = d_list_proc(msg, d, c);
if (d->d1 != old)
{
int new_model = model_list[configure_dialog[3].d1].num;
int new_cpu_m = configure_dialog[5].d1;
int new_cpu = configure_dialog[6].d1;
int new_dynarec = configure_dialog[25].flags & D_SELECTED;
int new_gfxcard = video_old_to_new(video_list[configure_dialog[4].d1].num);
int new_mem_size;
int cpu_flags;
reset_list();
if (models[new_model].fixed_gfxcard)
configure_dialog[4].flags |= D_DISABLED;
else
configure_dialog[4].flags &= ~D_DISABLED;
cpu_flags = models[new_model].cpu[new_cpu_m].cpus[new_cpu].cpu_flags;
configure_dialog[25].flags = (((cpu_flags & CPU_SUPPORTS_DYNAREC) && new_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC)) ? D_SELECTED : 0;
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC))
configure_dialog[25].flags |= D_DISABLED;
sscanf(mem_size_str, "%i", &new_mem_size);
new_mem_size &= ~(models[new_model].ram_granularity - 1);
if (new_mem_size < models[new_model].min_ram)
new_mem_size = models[new_model].min_ram;
else if (new_mem_size > models[new_model].max_ram)
new_mem_size = models[new_model].max_ram;
sprintf(mem_size_str, "%i", new_mem_size);
if (models[new_model].is_at)
sprintf(mem_size_units, "MB");
else
sprintf(mem_size_units, "kB");
if (!video_card_has_config(new_gfxcard))
configure_dialog[30].flags |= D_DISABLED;
else
configure_dialog[30].flags &= ~D_DISABLED;
if (!sound_card_has_config(configure_dialog[9].d1))
configure_dialog[31].flags |= D_DISABLED;
else
configure_dialog[31].flags &= ~D_DISABLED;
return D_REDRAW;
}
return ret;
}
static int video_config_proc(int msg, DIALOG *d, int c)
{
int ret = d_button_proc(msg, d, c);
if (ret == D_CLOSE)
{
int new_gfxcard = video_old_to_new(video_list[configure_dialog[4].d1].num);
deviceconfig_open(video_card_getdevice(new_gfxcard));
return D_O_K;
}
return ret;
}
static int sound_config_proc(int msg, DIALOG *d, int c)
{
int ret = d_button_proc(msg, d, c);
if (ret == D_CLOSE)
{
int new_sndcard = sound_list[configure_dialog[9].d1].num;
deviceconfig_open(sound_card_getdevice(new_sndcard));
return D_O_K;
}
return ret;
}
static void reset_list()
{
int model = model_list[configure_dialog[3].d1].num;
int cpumanu = configure_dialog[5].d1;
int cpu = configure_dialog[6].d1;
int c;
memset(cpumanu_list, 0, sizeof(cpumanu_list));
memset(cpu_list, 0, sizeof(cpu_list));
c = 0;
while (models[model].cpu[c].cpus != NULL && c < 3)
{
strcpy(cpumanu_list[c].name, models[model].cpu[c].name);
cpumanu_list[c].num = c;
c++;
}
if (cpumanu >= c)
cpumanu = configure_dialog[6].d1 = c-1;
c = 0;
while (models[model].cpu[cpumanu].cpus[c].cpu_type != -1)
{
strcpy(cpu_list[c].name, models[model].cpu[cpumanu].cpus[c].name);
cpu_list[c].num = c;
c++;
}
if (cpu >= c)
cpu = configure_dialog[7].d1 = c-1;
}
int settings_configure()
{
int c, d;
int cpu_flags;
memset(model_list, 0, sizeof(model_list));
memset(video_list, 0, sizeof(video_list));
memset(sound_list, 0, sizeof(sound_list));
for (c = 0; c < ROM_MAX; c++)
romstolist[c] = 0;
c = d = 0;
while (models[c].id != -1)
{
pclog("INITDIALOG : %i %i %i\n",c,models[c].id,romspresent[models[c].id]);
if (romspresent[models[c].id])
{
strcpy(model_list[d].name, models[c].name);
model_list[d].num = c;
if (c == model)
configure_dialog[3].d1 = d;
d++;
}
c++;
}
if (models[model].fixed_gfxcard)
configure_dialog[4].flags |= D_DISABLED;
else
configure_dialog[4].flags &= ~D_DISABLED;
c = d = 0;
while (1)
{
char *s = video_card_getname(c);
if (!s[0])
break;
pclog("video_card_available : %i\n", c);
if (video_card_available(c))
{
strcpy(video_list[d].name, video_card_getname(c));
video_list[d].num = video_new_to_old(c);
if (video_new_to_old(c) == gfxcard)
configure_dialog[4].d1 = d;
d++;
}
c++;
}
if (!video_card_has_config(video_old_to_new(gfxcard)))
configure_dialog[30].flags |= D_DISABLED;
else
configure_dialog[30].flags &= ~D_DISABLED;
c = d = 0;
while (1)
{
char *s = sound_card_getname(c);
if (!s[0])
break;
if (sound_card_available(c))
{
strcpy(sound_list[d].name, sound_card_getname(c));
sound_list[d].num = c;
if (c == sound_card_current)
configure_dialog[9].d1 = d;
d++;
}
c++;
}
c = 0;
while (joystick_get_name(c))
{
strcpy(joystick_list[c].name, joystick_get_name(c));
if (c == joystick_type)
configure_dialog[34].d1 = c;
c++;
}
if (!sound_card_has_config(configure_dialog[9].d1))
configure_dialog[31].flags |= D_DISABLED;
else
configure_dialog[31].flags &= ~D_DISABLED;
configure_dialog[5].d1 = cpu_manufacturer;
configure_dialog[6].d1 = cpu;
configure_dialog[7].d1 = cache;
configure_dialog[8].d1 = video_speed;
reset_list();
// strcpy(cpumanu_str, models[romstomodel[romset]].cpu[cpu_manufacturer].name);
// strcpy(cpu_str, models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[cpu].name);
// strcpy(cache_str, cache_str_list[cache]);
// strcpy(vidspeed_str, vidspeed_str_list[video_speed]);
// strcpy(soundcard_str, sound_card_getname(sound_card_current));
if (GAMEBLASTER)
configure_dialog[12].flags |= D_SELECTED;
else
configure_dialog[12].flags &= ~D_SELECTED;
if (GUS)
configure_dialog[13].flags |= D_SELECTED;
else
configure_dialog[13].flags &= ~D_SELECTED;
if (SSI2001)
configure_dialog[14].flags |= D_SELECTED;
else
configure_dialog[14].flags &= ~D_SELECTED;
if (cga_comp)
configure_dialog[15].flags |= D_SELECTED;
else
configure_dialog[15].flags &= ~D_SELECTED;
if (voodoo_enabled)
configure_dialog[16].flags |= D_SELECTED;
else
configure_dialog[16].flags &= ~D_SELECTED;
if (models[model].is_at)
sprintf(mem_size_str, "%i", mem_size / 1024);
else
sprintf(mem_size_str, "%i", mem_size);
if (models[model].is_at)
sprintf(mem_size_units, "MB");
else
sprintf(mem_size_units, "kB");
cpu_flags = models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_flags;
configure_dialog[25].flags = (((cpu_flags & CPU_SUPPORTS_DYNAREC) && cpu_use_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC)) ? D_SELECTED : 0;
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC))
configure_dialog[25].flags |= D_DISABLED;
configure_dialog[28].d1 = fdd_get_type(0);
configure_dialog[29].d1 = fdd_get_type(1);
while (1)
{
position_dialog(configure_dialog, SCREEN_W/2 - configure_dialog[0].w/2, SCREEN_H/2 - configure_dialog[0].h/2);
c = popup_dialog(configure_dialog, 1);
position_dialog(configure_dialog, -(SCREEN_W/2 - configure_dialog[0].w/2), -(SCREEN_H/2 - configure_dialog[0].h/2));
if (c == 1)
{
int new_model = model_list[configure_dialog[3].d1].num;
int new_gfxcard = video_list[configure_dialog[4].d1].num;
int new_sndcard = sound_list[configure_dialog[9].d1].num;
int new_cpu_m = configure_dialog[5].d1;
int new_cpu = configure_dialog[6].d1;
int new_mem_size;
int new_has_fpu = (models[new_model].cpu[new_cpu_m].cpus[new_cpu].cpu_type >= CPU_i486DX) ? 1 : 0;
int new_GAMEBLASTER = (configure_dialog[12].flags & D_SELECTED) ? 1 : 0;
int new_GUS = (configure_dialog[13].flags & D_SELECTED) ? 1 : 0;
int new_SSI2001 = (configure_dialog[14].flags & D_SELECTED) ? 1 : 0;
int new_voodoo = (configure_dialog[16].flags & D_SELECTED) ? 1 : 0;
int new_dynarec = (configure_dialog[25].flags & D_SELECTED) ? 1 : 0;
int new_fda = configure_dialog[28].d1;
int new_fdb = configure_dialog[29].d1;
sscanf(mem_size_str, "%i", &new_mem_size);
new_mem_size &= ~(models[new_model].ram_granularity - 1);
if (new_mem_size < models[new_model].min_ram)
new_mem_size = models[new_model].min_ram;
else if (new_mem_size > models[new_model].max_ram)
new_mem_size = models[new_model].max_ram;
if (models[new_model].is_at)
new_mem_size *= 1024;
if (new_model != model || new_gfxcard != gfxcard || new_mem_size != mem_size ||
new_has_fpu != hasfpu || new_GAMEBLASTER != GAMEBLASTER || new_GUS != GUS ||
new_SSI2001 != SSI2001 || new_sndcard != sound_card_current || new_voodoo != voodoo_enabled ||
new_dynarec != cpu_use_dynarec || new_fda != fdd_get_type(0) || new_fdb != fdd_get_type(1))
{
if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) != 1)
continue;
model = new_model;
romset = model_getromset();
gfxcard = new_gfxcard;
mem_size = new_mem_size;
cpu_manufacturer = new_cpu_m;
cpu = new_cpu;
GAMEBLASTER = new_GAMEBLASTER;
GUS = new_GUS;
SSI2001 = new_SSI2001;
sound_card_current = new_sndcard;
voodoo_enabled = new_voodoo;
cpu_use_dynarec = new_dynarec;
mem_resize();
loadbios();
resetpchard();
fdd_set_type(0, new_fda);
fdd_set_type(1, new_fdb);
}
video_speed = configure_dialog[8].d1;
cga_comp = (configure_dialog[15].flags & D_SELECTED) ? 1 : 0;
cpu_manufacturer = new_cpu_m;
cpu = new_cpu;
cpu_set();
cache = configure_dialog[7].d1;
mem_updatecache();
joystick_type = configure_dialog[34].d1;
gameport_update_joystick_type();
saveconfig();
speedchanged();
return D_O_K;
}
if (c == 2)
return D_O_K;
}
return D_O_K;
}

View File

@@ -1,306 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#include "ibm.h"
#include "device.h"
#include "allegro-main.h"
#include "allegro-gui.h"
#include "config.h"
static device_t *config_device;
#define MAX_CONFIG_SIZE 64
#define MAX_CONFIG_SELECTIONS 8
static device_config_selection_t *config_selections[MAX_CONFIG_SELECTIONS];
#define list_proc_device_func(i) \
static char *list_proc_device_ ## i(int index, int *list_size) \
{ \
device_config_selection_t *config = config_selections[i]; \
\
if (index < 0) \
{ \
int c = 0; \
\
while (config[c].description[0]) \
c++; \
\
*list_size = c; \
return NULL; \
} \
\
return config[index].description; \
}
list_proc_device_func(0)
list_proc_device_func(1)
list_proc_device_func(2)
list_proc_device_func(3)
list_proc_device_func(4)
list_proc_device_func(5)
list_proc_device_func(6)
list_proc_device_func(7)
static DIALOG deviceconfig_dialog[MAX_CONFIG_SIZE] =
{
{d_shadow_box_proc, 0, 0, 568,332,0,0xffffff,0,0, 0,0,0,0,0} // 0
};
void deviceconfig_open(device_t *device)
{
DIALOG *d;
device_config_t *config = device->config;
int y = 10;
int dialog_pos = 1;
int list_pos = 0;
int c;
int id_ok, id_cancel;
memset((void *)((uintptr_t)deviceconfig_dialog) + sizeof(DIALOG), 0, sizeof(deviceconfig_dialog) - sizeof(DIALOG));
deviceconfig_dialog[0].x = deviceconfig_dialog[0].y = 0;
while (config->type != -1)
{
d = &deviceconfig_dialog[dialog_pos];
switch (config->type)
{
case CONFIG_BINARY:
d->x = 32;
d->y = y;
d->w = 118*2;
d->h = 15;
d->dp = config->description;
d->proc = d_check_proc;
d->flags = config_get_int(device->name, config->name, config->default_int) ? D_SELECTED : 0;
d->bg = 0xffffff;
d->fg = 0;
dialog_pos++;
y += 20;
break;
case CONFIG_SELECTION:
if (list_pos >= MAX_CONFIG_SELECTIONS)
break;
d->x = 32;
d->y = y;
d->w = 80;
d->h = 15;
d->dp = config->description;
d->proc = d_text_proc;
d->flags = 0;
d->bg = 0xffffff;
d->fg = 0;
d++;
d->x = 250;
d->y = y;
d->w = 304;
d->h = 20;
switch (list_pos)
{
case 0 : d->dp = list_proc_device_0; break;
case 1 : d->dp = list_proc_device_1; break;
case 2 : d->dp = list_proc_device_2; break;
case 3 : d->dp = list_proc_device_3; break;
case 4 : d->dp = list_proc_device_4; break;
case 5 : d->dp = list_proc_device_5; break;
case 6 : d->dp = list_proc_device_6; break;
case 7 : d->dp = list_proc_device_7; break;
}
d->proc = d_list_proc;
d->flags = 0;
d->bg = 0xffffff;
d->fg = 0;
config_selections[list_pos++] = config->selection;
c = 0;
while (config->selection[c].description[0])
{
if (config_get_int(device->name, config->name, config->default_int) == config->selection[c].value)
d->d1 = c;
c++;
}
dialog_pos += 2;
y += 20;
break;
case CONFIG_MIDI:
break;
}
config++;
if (dialog_pos >= MAX_CONFIG_SIZE-3)
break;
}
d = &deviceconfig_dialog[dialog_pos];
id_ok = dialog_pos;
id_cancel = dialog_pos + 1;
d->x = 226;
d->y = y+8;
d->w = 50;
d->h = 16;
d->dp = "OK";
d->proc = d_button_proc;
d->flags = D_EXIT;
d->bg = 0xffffff;
d->fg = 0;
d++;
d->x = 296;
d->y = y+8;
d->w = 50;
d->h = 16;
d->dp = "Cancel";
d->proc = d_button_proc;
d->flags = D_EXIT;
d->bg = 0xffffff;
d->fg = 0;
deviceconfig_dialog[0].h = y + 28;
config_device = device;
while (1)
{
position_dialog(deviceconfig_dialog, SCREEN_W/2 - deviceconfig_dialog[0].w/2, SCREEN_H/2 - deviceconfig_dialog[0].h/2);
c = popup_dialog(deviceconfig_dialog, 1);
position_dialog(deviceconfig_dialog, -(SCREEN_W/2 - deviceconfig_dialog[0].w/2), -(SCREEN_H/2 - deviceconfig_dialog[0].h/2));
if (c == id_ok)
{
int changed = 0;
dialog_pos = 1;
config = device->config;
while (config->type != -1)
{
int val;
d = &deviceconfig_dialog[dialog_pos];
switch (config->type)
{
case CONFIG_BINARY:
val = (d->flags & D_SELECTED) ? 1 : 0;
if (val != config_get_int(device->name, config->name, config->default_int))
changed = 1;
dialog_pos++;
break;
case CONFIG_SELECTION:
if (list_pos >= MAX_CONFIG_SELECTIONS)
break;
d++;
val = config->selection[d->d1].value;
if (val != config_get_int(device->name, config->name, config->default_int))
changed = 1;
dialog_pos += 2;
break;
case CONFIG_MIDI:
break;
}
config++;
if (dialog_pos >= MAX_CONFIG_SIZE-3)
break;
}
if (!changed)
return;
if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) != 1)
continue;
dialog_pos = 1;
config = device->config;
while (config->type != -1)
{
int val;
d = &deviceconfig_dialog[dialog_pos];
switch (config->type)
{
case CONFIG_BINARY:
val = (d->flags & D_SELECTED) ? 1 : 0;
config_set_int(config_device->name, config->name, val);
dialog_pos++;
break;
case CONFIG_SELECTION:
if (list_pos >= MAX_CONFIG_SELECTIONS)
break;
d++;
val = config->selection[d->d1].value;
config_set_int(config_device->name, config->name, val);
dialog_pos += 2;
break;
case CONFIG_MIDI:
break;
}
config++;
if (dialog_pos >= MAX_CONFIG_SIZE-3)
break;
}
saveconfig();
resetpchard();
return;
}
if (c == id_cancel)
break;
}
}

View File

@@ -1,516 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _GNU_SOURCE
#include <stdio.h>
#include "ibm.h"
#include "device.h"
#include "ide.h"
#include "allegro-main.h"
#include "allegro-gui.h"
static char hd_path[4][260];
static char hd_sectors[4][10];
static char hd_heads[4][10];
static char hd_cylinders[4][10];
static char hd_size[4][20];
static char hd_path_new[260];
static char hd_sectors_new[10];
static char hd_heads_new[10];
static char hd_cylinders_new[10];
static char hd_size_new[20];
static int new_cdrom_channel;
static hard_disk_t hdc_new[4];
static DIALOG hdparams_dialog[]=
{
{d_shadow_box_proc, 0, 0, 194*2,86,0,0xffffff,0,0, 0,0,0,0,0}, // 0
{d_button_proc, 126, 66, 50, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1
{d_button_proc, 196, 66, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2
{d_text_proc, 7*2, 6, 170, 10, 0, 0xffffff, 0, 0, 0, 0, "Initial settings are based on file size", 0, 0},
{d_text_proc, 7*2, 22, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0},
{d_text_proc, 63*2, 22, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0},
{d_text_proc, 120*2, 22, 28, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0},
{d_edit_proc, 44*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 2, 0, hd_sectors_new, 0, 0},
{d_edit_proc, 92*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 3, 0, hd_heads_new, 0, 0},
{d_edit_proc, 168*2, 22, 24*2, 12, 0, 0xffffff, 0, 0, 5, 0, hd_cylinders_new, 0, 0},
{d_text_proc, 7*2, 54, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size_new, 0, 0},
{0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL}
};
static int hdconf_open(int msg, DIALOG *d, int c)
{
int drv = d->d2;
int ret = d_button_proc(msg, d, c);
if (ret == D_EXIT)
{
char fn[260];
int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64;
strcpy(fn, hd_path[drv]);
ret = file_select_ex("Please choose a disc image", fn, "IMG", 260, xsize, ysize);
if (ret)
{
uint64_t sz;
FILE *f = fopen64(fn, "rb");
if (!f)
{
return D_REDRAW;
}
fseeko64(f, -1, SEEK_END);
sz = ftello64(f) + 1;
fclose(f);
sprintf(hd_sectors_new, "63");
sprintf(hd_heads_new, "16");
sprintf(hd_cylinders_new, "%i", (int)((sz / 512) / 16) / 63);
while (1)
{
position_dialog(hdparams_dialog, SCREEN_W/2 - 186, SCREEN_H/2 - 86/2);
ret = popup_dialog(hdparams_dialog, 1);
position_dialog(hdparams_dialog, -(SCREEN_W/2 - 186), -(SCREEN_H/2 - 86/2));
if (ret == 1)
{
int spt, hpc, cyl;
sscanf(hd_sectors_new, "%i", &spt);
sscanf(hd_heads_new, "%i", &hpc);
sscanf(hd_cylinders_new, "%i", &cyl);
if (spt > 63)
{
alert("Drive has too many sectors (maximum is 63)", NULL, NULL, "OK", NULL, 0, 0);
continue;
}
if (hpc > 128)
{
alert("Drive has too many heads (maximum is 128)", NULL, NULL, "OK", NULL, 0, 0);
continue;
}
if (cyl > 16383)
{
alert("Drive has too many cylinders (maximum is 16383)", NULL, NULL, "OK", NULL, 0, 0);
continue;
}
hdc_new[drv].spt = spt;
hdc_new[drv].hpc = hpc;
hdc_new[drv].tracks = cyl;
strcpy(hd_path[drv], fn);
sprintf(hd_sectors[drv], "%i", hdc_new[drv].spt);
sprintf(hd_heads[drv], "%i", hdc_new[drv].hpc);
sprintf(hd_cylinders[drv], "%i", hdc_new[drv].tracks);
sprintf(hd_size[drv], "Size : %imb", (((((uint64_t)hdc_new[drv].tracks*(uint64_t)hdc_new[drv].hpc)*(uint64_t)hdc_new[drv].spt)*512)/1024)/1024);
return D_REDRAW;
}
if (ret == 2)
break;
}
}
return D_REDRAW;
}
return ret;
}
static int hdconf_new_file(int msg, DIALOG *d, int c)
{
int ret = d_button_proc(msg, d, c);
if (ret == D_EXIT)
{
char fn[260];
int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64;
strcpy(fn, hd_path_new);
ret = file_select_ex("Please choose a disc image", fn, "IMG", 260, xsize, ysize);
if (ret)
strcpy(hd_path_new, fn);
return D_REDRAW;
}
return ret;
}
static DIALOG hdnew_dialog[]=
{
{d_shadow_box_proc, 0, 0, 194*2,86,0,0xffffff,0,0, 0,0,0,0,0}, // 0
{d_button_proc, 126, 66, 50, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1
{d_button_proc, 196, 66, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2
{d_edit_proc, 7*2, 6, 136*2, 10, 0, 0xffffff, 0, 0, 0, 0, hd_path_new, 0, 0},
{hdconf_new_file, 143*2, 6, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "...", 0, 0},
{d_text_proc, 7*2, 22, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0},
{d_text_proc, 63*2, 22, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0},
{d_text_proc, 120*2, 22, 28, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0},
{d_edit_proc, 44*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 2, 0, hd_sectors_new, 0, 0},
{d_edit_proc, 92*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 3, 0, hd_heads_new, 0, 0},
{d_edit_proc, 168*2, 22, 24*2, 12, 0, 0xffffff, 0, 0, 5, 0, hd_cylinders_new, 0, 0},
// {d_text_proc, 7*2, 54, 136, 12, 0, -1, 0, 0, 0, 0, hd_size_new, 0, 0},
{0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL}
};
static int create_hd(char *fn, int cyl, int hpc, int spt)
{
int c;
int e;
uint8_t buf[512];
FILE *f = fopen64(hd_path_new, "wb");
e = errno;
if (!f)
{
alert("Can't open file for write", NULL, NULL, "OK", NULL, 0, 0);
return -1;
}
memset(buf, 0, 512);
for (c = 0; c < (cyl * hpc * spt); c++)
{
fwrite(buf, 512, 1, f);
}
fclose(f);
}
static int hdconf_new(int msg, DIALOG *d, int c)
{
int drv = d->d2;
int ret = d_button_proc(msg, d, c);
if (ret == D_EXIT)
{
sprintf(hd_sectors_new, "63");
sprintf(hd_heads_new, "16");
sprintf(hd_cylinders_new, "511");
strcpy(hd_path_new, "");
while (1)
{
position_dialog(hdnew_dialog, SCREEN_W/2 - 186, SCREEN_H/2 - 86/2);
ret = popup_dialog(hdnew_dialog, 1);
position_dialog(hdnew_dialog, -(SCREEN_W/2 - 186), -(SCREEN_H/2 - 86/2));
if (ret == 1)
{
int spt, hpc, cyl;
int c, d;
FILE *f;
uint8_t *buf;
sscanf(hd_sectors_new, "%i", &spt);
sscanf(hd_heads_new, "%i", &hpc);
sscanf(hd_cylinders_new, "%i", &cyl);
if (spt > 63)
{
alert("Drive has too many sectors (maximum is 63)", NULL, NULL, "OK", NULL, 0, 0);
continue;
}
if (hpc > 128)
{
alert("Drive has too many heads (maximum is 128)", NULL, NULL, "OK", NULL, 0, 0);
continue;
}
if (cyl > 16383)
{
alert("Drive has too many cylinders (maximum is 16383)", NULL, NULL, "OK", NULL, 0, 0);
continue;
}
if (create_hd(hd_path_new, cyl, hpc, spt))
return D_REDRAW;
alert("Remember to partition and format the new drive", NULL, NULL, "OK", NULL, 0, 0);
hdc_new[drv].spt = spt;
hdc_new[drv].hpc = hpc;
hdc_new[drv].tracks = cyl;
strcpy(hd_path[drv], hd_path_new);
sprintf(hd_sectors[drv], "%i", hdc_new[drv].spt);
sprintf(hd_heads[drv], "%i", hdc_new[drv].hpc);
sprintf(hd_cylinders[drv], "%i", hdc_new[drv].tracks);
sprintf(hd_size[drv], "Size : %imb", (((((uint64_t)hdc_new[drv].tracks*(uint64_t)hdc_new[drv].hpc)*(uint64_t)hdc_new[drv].spt)*512)/1024)/1024);
return D_REDRAW;
}
if (ret == 2)
break;
}
return D_REDRAW;
}
return ret;
}
static int hdconf_eject(int msg, DIALOG *d, int c)
{
int drv = d->d2;
int ret = d_button_proc(msg, d, c);
if (ret == D_EXIT)
{
hdc_new[drv].spt = 0;
hdc_new[drv].hpc = 0;
hdc_new[drv].tracks = 0;
strcpy(hd_path[drv], "");
sprintf(hd_sectors[drv], "%i", hdc_new[drv].spt);
sprintf(hd_heads[drv], "%i", hdc_new[drv].hpc);
sprintf(hd_cylinders[drv], "%i", hdc_new[drv].tracks);
sprintf(hd_size[drv], "Size : %imb", (((((uint64_t)hdc_new[drv].tracks*(uint64_t)hdc_new[drv].hpc)*(uint64_t)hdc_new[drv].spt)*512)/1024)/1024);
return D_REDRAW;
}
return ret;
}
static int hdconf_radio_hd(int msg, DIALOG *d, int c);
static int hdconf_radio_cd(int msg, DIALOG *d, int c);
static DIALOG hdconf_dialog[]=
{
{d_shadow_box_proc, 0, 0, 210*2,354,0,0xffffff,0,0, 0,0,0,0,0}, // 0
{d_button_proc, 150, 334, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1
{d_button_proc, 220, 334, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2
{d_text_proc, 7*2, 6, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "C:", 0, 0},
{hdconf_radio_hd, 7*2, 22, 96, 12, 0, 0xffffff, 0, D_EXIT, 0, 0, "Hard drive", 0, 0}, // 4
{hdconf_radio_cd, 100*2, 22, 64, 12, 0, 0xffffff, 0, D_EXIT, 0, 0, "CD-ROM", 0, 0}, // 5
{d_edit_proc, 7*2, 38, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[0], 0, 0},
{hdconf_open, 143*2, 38, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "...", 0, 0},
{hdconf_new, 159*2, 38, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "New", 0, 0},
{hdconf_eject, 183*2, 38, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Eject", 0, 0},
{d_text_proc, 7*2, 54, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0},
{d_text_proc, 63*2, 54, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0},
{d_text_proc, 120*2, 54, 28, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0},
{d_edit_proc, 44*2, 54, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[0], 0, 0},
{d_edit_proc, 92*2, 54, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[0], 0, 0},
{d_edit_proc, 168*2, 54, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[0], 0, 0},
{d_text_proc, 7*2, 54, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[0], 0, 0},
{d_text_proc, 7*2, 76, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "D:", 0, 0},
{hdconf_radio_hd, 7*2, 92, 96, 12, 0, 0xffffff, 0, D_EXIT, 1, 0, "Hard drive", 0, 0}, // 18
{hdconf_radio_cd, 100*2, 92, 64, 12, 0, 0xffffff, 0, D_EXIT, 1, 0, "CD-ROM", 0, 0}, // 19
{d_edit_proc, 7*2, 108, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[1], 0, 0},
{hdconf_open, 143*2, 108, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 1, "...", 0, 0},
{hdconf_new, 159*2, 108, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 1, "New", 0, 0},
{hdconf_eject, 183*2, 108, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 1, "Eject", 0, 0},
{d_edit_proc, 44*2, 124, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[1], 0, 0},
{d_edit_proc, 92*2, 124, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[1], 0, 0},
{d_edit_proc, 168*2, 124, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[1], 0, 0},
{d_text_proc, 7*2, 124, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0},
{d_text_proc, 63*2, 124, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0},
{d_text_proc, 120*2, 124, 32, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0},
{d_text_proc, 7*2, 140, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[1], 0, 0},
{d_text_proc, 7*2, 162, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "E:", 0, 0},
{hdconf_radio_hd, 7*2, 178, 96, 12, 0, 0xffffff, 0, D_EXIT, 2, 0, "Hard drive", 0, 0}, // 32
{hdconf_radio_cd, 100*2, 178, 64, 12, 0, 0xffffff, 0, D_EXIT, 2, 0, "CD-ROM", 0, 0}, // 33
{d_edit_proc, 7*2, 194, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[2], 0, 0},
{hdconf_open, 143*2, 194, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 2, "...", 0, 0},
{hdconf_new, 159*2, 194, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 2, "New", 0, 0},
{hdconf_eject, 183*2, 194, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 2, "Eject", 0, 0},
{d_edit_proc, 44*2, 210, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[2], 0, 0},
{d_edit_proc, 92*2, 210, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[2], 0, 0},
{d_edit_proc, 168*2, 210, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[2], 0, 0},
{d_text_proc, 7*2, 210, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0},
{d_text_proc, 63*2, 210, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0},
{d_text_proc, 120*2, 210, 32, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0},
{d_text_proc, 7*2, 226, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[2], 0, 0},
{d_text_proc, 7*2, 248, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "F:", 0, 0},
{hdconf_radio_hd, 7*2, 264, 96, 12, 0, 0xffffff, 0, D_EXIT, 3, 0, "Hard drive", 0, 0}, // 46
{hdconf_radio_cd, 100*2, 264, 64, 12, 0, 0xffffff, 0, D_EXIT, 3, 0, "CD-ROM", 0, 0}, // 47
{d_edit_proc, 7*2, 280, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[3], 0, 0},
{hdconf_open, 143*2, 280, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 3, "...", 0, 0},
{hdconf_new, 159*2, 280, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 3, "New", 0, 0},
{hdconf_eject, 183*2, 280, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 3, "Eject", 0, 0},
{d_edit_proc, 44*2, 296, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[3], 0, 0},
{d_edit_proc, 92*2, 296, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[3], 0, 0},
{d_edit_proc, 168*2, 296, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[3], 0, 0},
{d_text_proc, 7*2, 296, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0},
{d_text_proc, 63*2, 296, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0},
{d_text_proc, 120*2, 296, 32, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0},
{d_text_proc, 7*2, 312, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[3], 0, 0},
{0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL}
};
static void update_hdd_cdrom()
{
if (new_cdrom_channel == 0)
{
hdconf_dialog[4].flags &= ~D_SELECTED;
hdconf_dialog[5].flags |= D_SELECTED;
}
else
{
hdconf_dialog[4].flags |= D_SELECTED;
hdconf_dialog[5].flags &= ~D_SELECTED;
}
if (new_cdrom_channel == 1)
{
hdconf_dialog[18].flags &= ~D_SELECTED;
hdconf_dialog[19].flags |= D_SELECTED;
}
else
{
hdconf_dialog[18].flags |= D_SELECTED;
hdconf_dialog[19].flags &= ~D_SELECTED;
}
if (new_cdrom_channel == 2)
{
hdconf_dialog[32].flags &= ~D_SELECTED;
hdconf_dialog[33].flags |= D_SELECTED;
}
else
{
hdconf_dialog[32].flags |= D_SELECTED;
hdconf_dialog[33].flags &= ~D_SELECTED;
}
if (new_cdrom_channel == 3)
{
hdconf_dialog[46].flags &= ~D_SELECTED;
hdconf_dialog[47].flags |= D_SELECTED;
}
else
{
hdconf_dialog[46].flags |= D_SELECTED;
hdconf_dialog[47].flags &= ~D_SELECTED;
}
}
static int hdconf_radio_hd(int msg, DIALOG *d, int c)
{
int ret = d_radio_proc(msg, d, c);
if (ret == D_CLOSE)
{
if (new_cdrom_channel == d->d1)
{
new_cdrom_channel = -1;
update_hdd_cdrom();
}
return D_REDRAW;
}
return ret;
}
static int hdconf_radio_cd(int msg, DIALOG *d, int c)
{
int ret = d_radio_proc(msg, d, c);
if (ret == D_CLOSE)
{
if (new_cdrom_channel != d->d1)
{
new_cdrom_channel = d->d1;
update_hdd_cdrom();
}
return D_REDRAW;
}
return ret;
}
int disc_hdconf()
{
int c;
int changed=0;
hdc_new[0] = hdc[0];
hdc_new[1] = hdc[1];
hdc_new[2] = hdc[2];
hdc_new[3] = hdc[3];
strcpy(hd_path[0], ide_fn[0]);
strcpy(hd_path[1], ide_fn[1]);
strcpy(hd_path[2], ide_fn[2]);
strcpy(hd_path[3], ide_fn[3]);
sprintf(hd_sectors[0], "%i", hdc[0].spt);
sprintf(hd_sectors[1], "%i", hdc[1].spt);
sprintf(hd_sectors[2], "%i", hdc[2].spt);
sprintf(hd_sectors[3], "%i", hdc[3].spt);
sprintf(hd_heads[0], "%i", hdc[0].hpc);
sprintf(hd_heads[1], "%i", hdc[1].hpc);
sprintf(hd_heads[2], "%i", hdc[2].hpc);
sprintf(hd_heads[3], "%i", hdc[3].hpc);
sprintf(hd_cylinders[0], "%i", hdc[0].tracks);
sprintf(hd_cylinders[1], "%i", hdc[1].tracks);
sprintf(hd_cylinders[2], "%i", hdc[2].tracks);
sprintf(hd_cylinders[3], "%i", hdc[3].tracks);
sprintf(hd_size[0], "Size : %imb", (((((uint64_t)hdc[0].tracks*(uint64_t)hdc[0].hpc)*(uint64_t)hdc[0].spt)*512)/1024)/1024);
sprintf(hd_size[1], "Size : %imb", (((((uint64_t)hdc[1].tracks*(uint64_t)hdc[1].hpc)*(uint64_t)hdc[1].spt)*512)/1024)/1024);
sprintf(hd_size[2], "Size : %imb", (((((uint64_t)hdc[2].tracks*(uint64_t)hdc[2].hpc)*(uint64_t)hdc[2].spt)*512)/1024)/1024);
sprintf(hd_size[3], "Size : %imb", (((((uint64_t)hdc[3].tracks*(uint64_t)hdc[3].hpc)*(uint64_t)hdc[3].spt)*512)/1024)/1024);
new_cdrom_channel = cdrom_channel;
update_hdd_cdrom();
while (1)
{
position_dialog(hdconf_dialog, SCREEN_W/2 - hdconf_dialog[0].w/2, SCREEN_H/2 - hdconf_dialog[0].h/2);
c = popup_dialog(hdconf_dialog, 1);
position_dialog(hdconf_dialog, -(SCREEN_W/2 - hdconf_dialog[0].w/2), -(SCREEN_H/2 - hdconf_dialog[0].h/2));
if (c == 1)
{
if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1)
{
hdc[0] = hdc_new[0];
hdc[1] = hdc_new[1];
hdc[2] = hdc_new[2];
hdc[3] = hdc_new[3];
strcpy(ide_fn[0], hd_path[0]);
strcpy(ide_fn[1], hd_path[1]);
strcpy(ide_fn[2], hd_path[2]);
strcpy(ide_fn[3], hd_path[3]);
cdrom_channel = new_cdrom_channel;
saveconfig();
resetpchard();
return D_O_K;
}
}
if (c == 2)
return D_O_K;
}
return D_O_K;
}

View File

@@ -1,229 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#include "ibm.h"
#include "device.h"
#include "allegro-main.h"
#include "allegro-gui.h"
#include "disc.h"
#include "ide.h"
static int file_return(void)
{
return D_CLOSE;
}
static int file_exit(void)
{
quited = 1;
return D_CLOSE;
}
static int file_reset(void)
{
resetpchard();
return D_CLOSE;
}
static int file_cad(void)
{
resetpc_cad();
return D_CLOSE;
}
static MENU file_menu[]=
{
{"&Return", file_return, NULL, 0, NULL},
{"&Hard Reset", file_reset, NULL, 0, NULL},
{"&Ctrl+Alt+Del", file_cad, NULL, 0, NULL},
{"E&xit", file_exit, NULL, 0, NULL},
{NULL,NULL,NULL,0,NULL}
};
static int disc_load_a()
{
char fn[260];
int ret;
int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64;
strcpy(fn, discfns[0]);
ret = file_select_ex("Please choose a disc image", fn, "IMG;IMA;FDI", 260, xsize, ysize);
if (ret)
{
disc_close(0);
disc_load(0, fn);
saveconfig();
}
return D_O_K;
}
static int disc_load_b()
{
char fn[260];
int ret;
int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64;
strcpy(fn, discfns[1]);
ret = file_select_ex("Please choose a disc image", fn, "IMG;IMA;FDI", 260, xsize, ysize);
if (ret)
{
disc_close(1);
disc_load(1, fn);
saveconfig();
}
return D_O_K;
}
static int disc_eject_a()
{
disc_close(0);
saveconfig();
return D_O_K;
}
static int disc_eject_b()
{
disc_close(1);
saveconfig();
return D_O_K;
}
static MENU disc_menu[]=
{
{"Load drive &A:...", disc_load_a, NULL, 0, NULL},
{"Load drive &B:...", disc_load_b, NULL, 0, NULL},
{"&Eject drive &A:", disc_eject_a, NULL, 0, NULL},
{"Eject drive &B:", disc_eject_b, NULL, 0, NULL},
{"&Configure hard discs...", disc_hdconf, NULL, 0, NULL},
{NULL,NULL,NULL,0,NULL}
};
static MENU cdrom_menu[];
static void cdrom_update()
{
int c;
for (c = 0; cdrom_menu[c].text; c++)
cdrom_menu[c].flags = 0;
if (!cdrom_enabled)
cdrom_menu[0].flags = D_SELECTED;
else
cdrom_menu[1].flags = D_SELECTED;
return D_O_K;
}
static int cdrom_disabled()
{
if (!cdrom_enabled)
return D_O_K;
if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1)
{
atapi->exit();
cdrom_enabled = 0;
saveconfig();
resetpchard();
cdrom_update();
}
return D_O_K;
}
static int cdrom_empty()
{
if (cdrom_enabled)
{
atapi->exit();
cdrom_drive = -1;
cdrom_null_open(cdrom_drive);
return D_O_K;
}
if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1)
{
cdrom_drive = -1;
cdrom_enabled = 1;
cdrom_null_open(cdrom_drive);
saveconfig();
resetpchard();
cdrom_update();
}
}
static int cdrom_dev()
{
if (cdrom_enabled)
{
atapi->exit();
cdrom_drive = 1;
ioctl_open(cdrom_drive);
return D_O_K;
}
if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1)
{
cdrom_drive = 1;
cdrom_enabled = 1;
ioctl_open(cdrom_drive);
saveconfig();
resetpchard();
cdrom_update();
}
}
static MENU cdrom_menu[] =
{
{"&Disabled", cdrom_disabled, NULL, 0, NULL},
{"&Empty", cdrom_empty, NULL, 0, NULL},
{"/dev/cdrom", cdrom_dev, NULL, 0, NULL},
{NULL,NULL,NULL,0,NULL}
};
static MENU settings_menu[]=
{
{"&Configure...", settings_configure, NULL, 0, NULL},
{"CD-ROM", NULL, cdrom_menu, 0, NULL},
{NULL,NULL,NULL,0,NULL}
};
static MENU main_menu[]=
{
{"&File", NULL, file_menu, 0, NULL},
{"&Disc", NULL, disc_menu, 0, NULL},
{"&Settings", NULL, settings_menu, 0, NULL},
{NULL,NULL,NULL,0,NULL}
};
static DIALOG main_windows_gui[]=
{
{d_menu_proc, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, main_menu, NULL, NULL},
{d_yield_proc, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, NULL, NULL, NULL},
{0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL}
};
void gui_enter()
{
DIALOG_PLAYER *dp;
int x = 1;
infocus = 0;
dp = init_dialog(main_windows_gui, 0);
show_mouse(screen);
while (x && !(mouse_b & 2) && !key[KEY_ESC])
{
x = update_dialog(dp);
}
show_mouse(NULL);
shutdown_dialog(dp);
clear(screen);
clear_keybuf();
infocus = 1;
device_force_redraw();
}

View File

@@ -1,15 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
void gui_enter();
extern int quited;
extern int romspresent[ROM_MAX];
extern int gfx_present[GFX_MAX];
int disc_hdconf();
int settings_configure();
void deviceconfig_open(device_t *device);

View File

@@ -1,52 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#include "allegro-main.h"
#include "plat-joystick.h"
#include "device.h"
#include "gameport.h"
plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
joystick_t joystick_state[MAX_JOYSTICKS];
int joysticks_present;
void joystick_init()
{
install_joystick(JOY_TYPE_AUTODETECT);
joysticks_present = num_joysticks;
}
void joystick_close()
{
}
void joystick_poll()
{
int c, d;
poll_joystick();
for (c = 0; c < num_joysticks; c++)
{
plat_joystick_state[c].a[0] = joy[c].stick[0].axis[0].pos * 256;
plat_joystick_state[c].a[1] = joy[c].stick[0].axis[1].pos * 256;
for (d = 0; d < MAX_JOYSTICK_BUTTONS; d++)
plat_joystick_state[c].b[d] = joy[c].button[d].b;
}
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++)
{
if (c < num_joysticks)
{
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
joystick_state[c].axis[d] = plat_joystick_state[c].a[d];
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
joystick_state[c].button[d] = plat_joystick_state[c].b[d];
}
else
{
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
joystick_state[c].axis[d] = 0;
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
joystick_state[c].button[d] = 0;
}
}
}

View File

@@ -1,52 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#include "allegro-main.h"
#include "plat-keyboard.h"
int recv_key[272];
int rawinputkey[272];
static int key_convert[128] =
{
-1, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22, /* , A, B, C, D, E, F, G*/
0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18, /* H, I, J, K, L, M, N, O*/
0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11, /* P, Q, R, S, T, U, V, W*/
0x2d, 0x15, 0x2c, 0x0b, 0x02, 0x03, 0x04, 0x05, /* X, Y, Z, 0, 1, 2, 3, 4*/
0x06, 0x07, 0x08, 0x09, 0x0a, 0x52, 0x4f, 0x50, /* 5, 6, 7, 8, 9, p0, p1, p2*/
0x51, 0x4b, 0x4c, 0x4d, 0x47, 0x48, 0x49, 0x3b, /* p3, p4, p5, p6, p7, p8, p9, F1*/
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, /* F2, F3, F4, F5, F6, F7, F8, F9*/
0x44, 0x57, 0x58, 0x01, 0x29, 0x0c, 0x0d, 0x0e, /*F10, F11, F12, ESC, `<60>, -_, =+, backspace*/
0x0f, 0x1a, 0x1b, 0x1c, 0x27, 0x28, 0x2b, 0x56, /*TAB, [{, ]}, ENT, ;:, '@, \|, #~*/
0x33, 0x34, 0x35, 0x39, 0xd2, 0xd3, 0xc7, 0xcf, /* ,<, .>, /?, SPC, INS, DEL, HOME, END*/
0xc9, 0xd1, 0xcb, 0xcd, 0xc8, 0xd0, 0xb5, 0x37, /*PGU, PGD, LFT, RHT, UP, DN, /, * */
0x4a, 0x4e, 0x53, 0x9c, 0xff, -1, -1, -1, /* p-, p+, pDL, pEN, psc, pse, abnt, yen*/
-1, -1, -1, -1, -1, -1, -1, -1, /*kana, convert, noconvert, at, circumflex, colon2, kanji, pad equals*/
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 0x2a, 0x36, 0x1d, 0x9d, 0x38, /*, , lshift, rshift, lctrl, rctrl, alt*/
0xb8, 0xdb, 0xdc, 0xdd, 0x46, 0x45, 0x3a, -1 /*altgr, lwin, rwin, menu, scrlock, numlock, capslock*/
};
void keyboard_init()
{
install_keyboard();
}
void keyboard_close()
{
}
void keyboard_poll_host()
{
int c;
for (c = 0; c < 128; c++)
{
int key_idx = key_convert[c];
if (key_idx == -1)
continue;
if (key[c] != recv_key[key_idx])
recv_key[key_idx] = key[c];
}
}

View File

@@ -1,172 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#include "allegro-main.h"
#include "ibm.h"
#include "cpu.h"
#include "model.h"
#include "nvr.h"
#include "video.h"
#undef printf
int mousecapture = 0;
int quited = 0;
int winsizex = -1, winsizey = -1;
int romspresent[ROM_MAX];
int gfx_present[GFX_MAX];
void updatewindowsize(int x, int y)
{
if (x < 128)
x = 128;
if (y < 128)
y = 128;
if (winsizex != x || winsizey != y)
{
winsizex = x;
winsizey = y;
allegro_video_update_size(x, y);
}
}
void startblit()
{
}
void endblit()
{
}
static int ticks = 0;
static void timer_rout()
{
ticks++;
}
uint64_t timer_freq;
uint64_t timer_read()
{
return 0;
}
int main(int argc, char *argv[])
{
int frames = 0;
int c, d;
allegro_init();
allegro_video_init();
install_timer();
install_int_ex(timer_rout, BPS_TO_TIMER(100));
install_int_ex(onesec, BPS_TO_TIMER(1));
midi_init();
initpc(argc, argv);
d = romset;
for (c = 0; c < ROM_MAX; c++)
{
romset = c;
romspresent[c] = loadbios();
pclog("romset %i - %i\n", c, romspresent[c]);
}
for (c = 0; c < ROM_MAX; c++)
{
if (romspresent[c])
break;
}
if (c == ROM_MAX)
{
printf("No ROMs present!\nYou must have at least one romset to use 86Box.");
return 0;
}
romset=d;
c=loadbios();
if (!c)
{
if (romset != -1)
printf("Configured romset not available.\nDefaulting to available romset.");
for (c = 0; c < ROM_MAX; c++)
{
if (romspresent[c])
{
romset = c;
model = model_getmodel(romset);
saveconfig();
resetpchard();
break;
}
}
}
for (c = 0; c < GFX_MAX; c++)
gfx_present[c] = video_card_available(video_old_to_new(c));
if (!video_card_available(video_old_to_new(gfxcard)))
{
if (gfxcard) printf("Configured video BIOS not available.\nDefaulting to available romset.");
for (c = GFX_MAX-1; c >= 0; c--)
{
if (gfx_present[c])
{
gfxcard = c;
saveconfig();
resetpchard();
break;
}
}
}
resetpchard();
ticks = 0;
while (!quited)
{
if (ticks)
{
ticks--;
runpc();
frames++;
if (frames >= 200 && nvr_dosave)
{
frames = 0;
nvr_dosave = 0;
savenvr();
}
}
else
rest(1);
if (ticks > 10)
ticks = 0;
if ((mouse_b & 1) && !mousecapture)
mousecapture = 1;
if (((key[KEY_LCONTROL] || key[KEY_RCONTROL]) && key[KEY_END]) || (mouse_b & 4))
mousecapture = 0;
if ((key[KEY_LCONTROL] || key[KEY_RCONTROL]) && key[KEY_ALT] && key[KEY_PGDN])
{
int old_winsizex = winsizex, old_winsizey = winsizey;
if (winsizex < 512 || winsizey < 350)
updatewindowsize(512, 350);
gui_enter();
if (old_winsizex < 512 || old_winsizey < 350)
updatewindowsize(old_winsizex, old_winsizey);
ticks = 0;
}
}
closepc();
midi_close();
return 0;
}
END_OF_MAIN();

View File

@@ -1,22 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#define getr8 allegro_getr8
#define setr8 allegro_setr8
#define get_filename allegro_get_filename
#define append_filename allegro_append_filename
#define put_backslash allegro_put_backslash
#define get_extension allegro_get_extension
#define GFX_VGA allegro_GFX_VGA
#define MAX_JOYSTICKS allegro_MAX_JOYSTICKS
#include <allegro.h>
#undef MAX_JOYSTICKS
#undef GFX_VGA
#undef getr8
#undef setr8
#undef get_filename
#undef append_filename
#undef put_backslash
#undef get_extension

View File

@@ -1,48 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#include "allegro-main.h"
#include "ibm.h"
#include "plat-midi.h"
//#define USE_ALLEGRO_MIDI
void midi_init()
{
#ifdef USE_ALLEGRO_MIDI
install_sound(DIGI_NONE, MIDI_AUTODETECT, NULL);
#endif
}
void midi_close()
{
#ifdef USE_ALLEGRO_MIDI
remove_sound();
#endif
}
static int midi_cmd_pos, midi_len;
static uint8_t midi_command[3];
static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 0};
void midi_write(uint8_t val)
{
if (val & 0x80)
{
midi_cmd_pos = 0;
midi_len = midi_lengths[(val >> 4) & 7];
midi_command[0] = midi_command[1] = midi_command[2] = 0;
}
if (midi_len && midi_cmd_pos < 3)
{
midi_command[midi_cmd_pos] = val;
midi_cmd_pos++;
#ifdef USE_ALLEGRO_MIDI
if (midi_cmd_pos == midi_len)
midi_out(midi_command, midi_len);
#endif
}
}

View File

@@ -1,34 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#include "allegro-main.h"
#include "plat-mouse.h"
int mouse_buttons;
void mouse_init()
{
install_mouse();
}
void mouse_close()
{
}
void mouse_poll_host()
{
//poll_mouse();
mouse_buttons = mouse_b;
}
void mouse_get_mickeys(int *x, int *y)
{
if (mousecapture)
{
get_mouse_mickeys(x, y);
// position_mouse(64, 64);
}
else
*x = *y = 0;
}

View File

@@ -1,130 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#include "allegro-main.h"
#include "ibm.h"
#include "video.h"
#include "allegro-video.h"
static PALETTE cgapal=
{
{0,0,0},{0,42,0},{42,0,0},{42,21,0},
{0,0,0},{0,42,42},{42,0,42},{42,42,42},
{0,0,0},{21,63,21},{63,21,21},{63,63,21},
{0,0,0},{21,63,63},{63,21,63},{63,63,63},
{0,0,0},{0,0,42},{0,42,0},{0,42,42},
{42,0,0},{42,0,42},{42,21,00},{42,42,42},
{21,21,21},{21,21,63},{21,63,21},{21,63,63},
{63,21,21},{63,21,63},{63,63,21},{63,63,63},
{0,0,0},{0,21,0},{0,0,42},{0,42,42},
{42,0,21},{21,10,21},{42,0,42},{42,0,63},
{21,21,21},{21,63,21},{42,21,42},{21,63,63},
{63,0,0},{42,42,0},{63,21,42},{41,41,41},
{0,0,0},{0,42,42},{42,0,0},{42,42,42},
{0,0,0},{0,42,42},{42,0,0},{42,42,42},
{0,0,0},{0,63,63},{63,0,0},{63,63,63},
{0,0,0},{0,63,63},{63,0,0},{63,63,63},
};
static uint32_t pal_lookup[256];
static void allegro_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h);
static void allegro_blit_memtoscreen_8(int x, int y, int w, int h);
static BITMAP *buffer32_vscale;
void allegro_video_init()
{
int c;
set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
video_blit_memtoscreen = allegro_blit_memtoscreen;
video_blit_memtoscreen_8 = allegro_blit_memtoscreen_8;
for (c = 0; c < 256; c++)
pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2);
buffer32_vscale = create_bitmap(2048, 2048);
}
void allegro_video_close()
{
destroy_bitmap(buffer32_vscale);
}
void allegro_video_update_size(int x, int y)
{
if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, x, y, 0, 0))
fatal("Failed to set gfx mode %i,%i : %s\n", x, y, allegro_error);
}
static void allegro_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
{
if (h < winsizey)
{
int yy;
for (yy = y+y1; yy < y+y2; yy++)
{
if (yy >= 0)
{
memcpy(&((uint32_t *)buffer32_vscale->line[yy*2])[x], &((uint32_t *)buffer32->line[yy])[x], w*4);
memcpy(&((uint32_t *)buffer32_vscale->line[(yy*2)+1])[x], &((uint32_t *)buffer32->line[yy])[x], w*4);
}
}
blit(buffer32_vscale, screen, x, (y+y1)*2, 0, y1, w, (y2-y1)*2);
}
else
blit(buffer32, screen, x, y+y1, 0, y1, w, y2-y1);
}
static void allegro_blit_memtoscreen_8(int x, int y, int w, int h)
{
int xx, yy;
int line_double = (winsizey > h) ? 1 : 0;
if (y < 0)
{
h += y;
y = 0;
}
for (yy = y; yy < y+h; yy++)
{
int dy = line_double ? yy*2 : yy;
if (dy < buffer->h)
{
if (line_double)
{
for (xx = x; xx < x+w; xx++)
{
((uint32_t *)buffer32->line[dy])[xx] =
((uint32_t *)buffer32->line[dy + 1])[xx] = pal_lookup[buffer->line[yy][xx]];
}
}
else
{
for (xx = x; xx < x+w; xx++)
((uint32_t *)buffer32->line[dy])[xx] = pal_lookup[buffer->line[yy][xx]];
}
}
}
if (readflash)
{
if (line_double)
rectfill(buffer32, x+SCREEN_W-40, y*2+8, SCREEN_W-8, y*2+14, makecol(255, 255, 255));
else
rectfill(buffer32, x+SCREEN_W-40, y+8, SCREEN_W-8, y+14, makecol(255, 255, 255));
readflash = 0;
}
if (line_double)
blit(buffer32, screen, x, y*2, 0, 0, w, h*2);
else
blit(buffer32, screen, x, y, 0, 0, w, h);
}

View File

@@ -1,6 +0,0 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
void allegro_video_init();
void allegro_video_close();
void allegro_video_update_size(int x, int y);

View File

@@ -86,19 +86,19 @@ void set_serial1_addr()
switch (fdc37c665_regs[2] & 3)
{
case 0:
serial1_set(0x3f8, 4);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
break;
case 1:
serial1_set(0x2f8, 3);
serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ);
break;
case 2:
serial1_set(com3_addr, 4);
serial_setup(1, com3_addr, 4);
break;
case 3:
serial1_set(com4_addr, 3);
serial_setup(1, com4_addr, 3);
break;
}
}
@@ -111,19 +111,19 @@ void set_serial2_addr()
switch (fdc37c665_regs[2] & 0x30)
{
case 0:
serial2_set(0x3f8, 4);
serial_setup(2, SERIAL1_ADDR, SERIAL1_IRQ);
break;
case 1:
serial2_set(0x2f8, 3);
serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ);
break;
case 2:
serial2_set(com3_addr, 4);
serial_setup(2, com3_addr, 4);
break;
case 3:
serial2_set(com4_addr, 3);
serial_setup(2, com4_addr, 3);
break;
}
}
@@ -186,7 +186,7 @@ void fdc37c665_write(uint16_t port, uint8_t val, void *priv)
}
if (valxor & 0x60)
{
serial1_remove();
serial_remove(1);
set_com34_addr();
set_serial1_addr();
set_serial2_addr();
@@ -195,12 +195,12 @@ void fdc37c665_write(uint16_t port, uint8_t val, void *priv)
case 2:
if (valxor & 7)
{
serial1_remove();
serial_remove(1);
set_serial1_addr();
}
if (valxor & 0x70)
{
serial2_remove();
serial_remove(2);
set_serial2_addr();
}
break;
@@ -254,11 +254,11 @@ void fdc37c665_reset(void)
fdc_update_is_nsc(0);
serial1_remove();
serial1_set(0x3f8, 4);
serial_remove(1);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
serial2_remove();
serial2_set(0x2f8, 3);
serial_remove(2);
serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ);
lpt2_remove();

View File

@@ -170,13 +170,13 @@ process_value:
case 2:
if (valxor & 8)
{
serial1_remove();
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8);
serial_remove(1);
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8);
}
if (valxor & 0x80)
{
serial2_remove();
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF);
serial_remove(2);
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF);
}
break;
case 3:
@@ -224,29 +224,29 @@ process_value:
case 0x24:
if (valxor & 0xfe)
{
serial1_remove();
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8);
serial_remove(1);
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8);
}
break;
case 0x25:
if (valxor & 0xfe)
{
serial2_remove();
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF);
serial_remove(2);
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF);
}
break;
case 0x28:
if (valxor & 0xf)
{
serial2_remove();
serial_remove(2);
if ((fdc37c669_regs[0x28] & 0xf) == 0) fdc37c669_regs[0x28] |= 0x3;
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF);
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF);
}
if (valxor & 0xf0)
{
serial1_remove();
serial_remove(1);
if ((fdc37c669_regs[0x28] & 0xf0) == 0) fdc37c669_regs[0x28] |= 0x40;
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8);
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8);
}
break;
}
@@ -280,11 +280,11 @@ void fdc37c669_reset(void)
fdc_update_is_nsc(0);
serial1_remove();
serial1_set(0x3f8, 4);
serial_remove(1);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
serial2_remove();
serial2_set(0x2f8, 3);
serial_remove(2);
serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ);
lpt2_remove();

View File

@@ -297,11 +297,11 @@ process_value:
if (valxor)
{
if (!val)
serial1_remove();
serial_remove(1);
else
{
ld_port = make_port(4);
serial1_set(ld_port, fdc37c932fr_ld_regs[4][0x70]);
serial_setup(1, ld_port, fdc37c932fr_ld_regs[4][0x70]);
}
}
break;
@@ -311,7 +311,7 @@ process_value:
if (valxor && fdc37c932fr_ld_regs[4][0x30])
{
ld_port = make_port(4);
serial1_set(ld_port, fdc37c932fr_ld_regs[4][0x70]);
serial_setup(1, ld_port, fdc37c932fr_ld_regs[4][0x70]);
}
break;
}
@@ -325,11 +325,11 @@ process_value:
if (valxor)
{
if (!val)
serial2_remove();
serial_remove(2);
else
{
ld_port = make_port(5);
serial2_set(ld_port, fdc37c932fr_ld_regs[5][0x70]);
serial_setup(2, ld_port, fdc37c932fr_ld_regs[5][0x70]);
}
}
break;
@@ -339,7 +339,7 @@ process_value:
if (valxor && fdc37c932fr_ld_regs[5][0x30])
{
ld_port = make_port(5);
serial2_set(ld_port, fdc37c932fr_ld_regs[5][0x70]);
serial_setup(2, ld_port, fdc37c932fr_ld_regs[5][0x70]);
}
break;
}

View File

@@ -275,11 +275,11 @@ void common_init()
pit_init();
if (serial_enabled[0])
{
serial1_init(0x3f8, 4);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
}
if (serial_enabled[1])
{
serial2_init(0x2f8, 3);
serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ);
}
}
@@ -306,7 +306,7 @@ void pcjr_init()
pit_set_out_func(&pit, 0, pit_irq0_timer_pcjr);
if (serial_enabled[0])
{
serial1_init(0x2f8, 3);
serial_setup(1, 0x2f8, 3);
}
keyboard_pcjr_init();
device_add(&sn76489_device);

View File

@@ -1,12 +1,29 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of Serial Mouse devices.
*
* Based on the 86Box Serial Mouse driver as a framework.
*
* Version: @(#)mouse_serial.c 1.0.2 2017/05/06
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*/
#include <stdlib.h>
#include "ibm.h"
#include "mouse.h"
#include "pic.h"
#include "serial.h"
#include "timer.h"
#include "serial.h"
#include "mouse.h"
#include "mouse_serial.h"
typedef struct mouse_serial_t {
int port;
int pos,
delay;
int oldb;
@@ -14,16 +31,19 @@ typedef struct mouse_serial_t {
} mouse_serial_t;
/* Callback from serial driver: RTS was toggled. */
static void
sermouse_rcr(SERIAL *serial, void *priv)
sermouse_callback(SERIAL *serial, void *priv)
{
mouse_serial_t *ms = (mouse_serial_t *)priv;
/* Start a timer to wake us up in a little while. */
ms->pos = -1;
ms->delay = 5000 * (1 << TIMER_SHIFT);
}
/* Callback timer expired, now send our "mouse ID" to the serial port. */
static void
sermouse_timer(void *priv)
{
@@ -32,6 +52,8 @@ sermouse_timer(void *priv)
ms->delay = 0;
if (ms->pos == -1) {
ms->pos = 0;
/* This identifies a two-button Microsoft Serial mouse. */
serial_write_fifo(ms->serial, 'M');
}
}
@@ -41,10 +63,7 @@ static uint8_t
sermouse_poll(int x, int y, int z, int b, void *priv)
{
mouse_serial_t *ms = (mouse_serial_t *)priv;
SERIAL *sp = ms->serial;
uint8_t mousedat[3];
if (!(sp->ier & 1)) return(1);
uint8_t data[3];
if (!x && !y && b == ms->oldb) return(1);
@@ -55,24 +74,21 @@ sermouse_poll(int x, int y, int z, int b, void *priv)
if (y<-128) y = -128;
/* Use Microsoft format. */
mousedat[0] = 0x40;
mousedat[0] |= (((y>>6)&3)<<2);
mousedat[0] |= ((x>>6)&3);
if (b&1) mousedat[0] |= 0x20;
if (b&2) mousedat[0] |= 0x10;
mousedat[1] = x & 0x3F;
mousedat[2] = y & 0x3F;
data[0] = 0x40;
data[0] |= (((y>>6)&3)<<2);
data[0] |= ((x>>6)&3);
if (b&1) data[0] |= 0x20;
if (b&2) data[0] |= 0x10;
data[1] = x & 0x3F;
data[2] = y & 0x3F;
/* FIXME: we should check in serial_write_fifo, not here! --FvK */
if (! (sp->mctrl & 0x10)) {
/* Send the packet to the bottom-half of the attached port. */
#if 0
pclog("Serial data %02X %02X %02X\n",
mousedat[0], mousedat[1], mousedat[2]);
pclog("Mouse_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]);
#endif
serial_write_fifo(ms->serial, mousedat[0]);
serial_write_fifo(ms->serial, mousedat[1]);
serial_write_fifo(ms->serial, mousedat[2]);
}
serial_write_fifo(ms->serial, data[0]);
serial_write_fifo(ms->serial, data[1]);
serial_write_fifo(ms->serial, data[2]);
return(0);
}
@@ -83,11 +99,10 @@ sermouse_init(void)
{
mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t));
memset(ms, 0x00, sizeof(mouse_serial_t));
ms->port = SERMOUSE_PORT;
/* Attach a serial port to the mouse. */
ms->serial = &serial1;
serial1.rcr_callback = sermouse_rcr;
serial1.rcr_callback_p = ms;
ms->serial = serial_attach(ms->port, sermouse_callback, ms);
timer_add(sermouse_timer, &ms->delay, &ms->delay, ms);
@@ -101,7 +116,7 @@ sermouse_close(void *priv)
mouse_serial_t *ms = (mouse_serial_t *)priv;
/* Detach serial port from the mouse. */
serial1.rcr_callback = NULL;
serial_attach(ms->port, NULL, NULL);
free(ms);
}

View File

@@ -1 +1,27 @@
extern mouse_t mouse_serial_microsoft;
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of Serial Mouse devices.
*
* Definitions for the Serial Mouse driver.
*
* Version: @(#)mouse_serial.h 1.0.2 2017/05/06
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*/
#ifndef MOUSE_SERIAL_H
# define MOUSE_SERIAL_H
#define SERMOUSE_PORT 1 /* attach to Serial1 */
extern mouse_t mouse_serial_microsoft;
#endif /*MOUSE_SERIAL_H*/

View File

@@ -101,6 +101,8 @@ int atfullspeed;
void saveconfig();
int infocus;
int mousecapture;
void pclog(const char *format, ...)
{
#ifndef RELEASE_BUILD
@@ -117,7 +119,7 @@ void pclog_w(const wchar_t *format, ...)
#ifndef RELEASE_BUILD
va_list ap;
va_start(ap, format);
_vwprintf_p(format, ap);
vwprintf(format, ap);
va_end(ap);
fflush(stdout);
#endif
@@ -130,6 +132,7 @@ void pclog_w(const wchar_t *format, ...)
#undef memmem
/* Return the first occurrence of NEEDLE in HAYSTACK. */
void *memmem (const void *haystack, size_t haystack_len, const void *needle, size_t needle_len)
{
@@ -154,6 +157,7 @@ void *memmem (const void *haystack, size_t haystack_len, const void *needle, siz
}
#endif
void fatal(const char *format, ...)
{
char msg[1024];
@@ -184,8 +188,9 @@ void fatal(const char *format, ...)
uint8_t cgastat;
int pollmouse_delay = 2;
void pollmouse()
void pollmouse(void)
{
int x, y, z;
pollmouse_delay--;
@@ -245,14 +250,14 @@ int updatestatus;
int win_title_update=0;
void onesec()
void onesec(void)
{
fps=framecount;
framecount=0;
win_title_update=1;
}
void pc_reset()
void pc_reset(void)
{
cpu_set();
resetx86();
@@ -268,6 +273,8 @@ void pc_reset()
ali1429_reset();
}
#undef printf
void initpc(int argc, wchar_t *argv[])
{
@@ -285,7 +292,7 @@ void initpc(int argc, wchar_t *argv[])
{
if (!_wcsicmp(argv[c], L"--help"))
{
printf("PCem command line options :\n\n");
printf("Command line options :\n\n");
printf("--config file.cfg - use given config file as initial configuration\n");
printf("--dump - always dump memory on exit\n");
printf("--fullscreen - start in fullscreen mode\n");
@@ -317,6 +324,7 @@ void initpc(int argc, wchar_t *argv[])
mouse_init();
midi_init();
serial_init();
if (config_file == NULL)
{
@@ -424,7 +432,7 @@ void initpc(int argc, wchar_t *argv[])
}
}
void resetpc()
void resetpc(void)
{
pc_reset();
shadowbios=0;
@@ -442,7 +450,7 @@ void pc_keyboard_send(uint8_t val)
}
}
void resetpc_cad()
void resetpc_cad(void)
{
pc_keyboard_send(29); /* Ctrl key pressed */
pc_keyboard_send(56); /* Alt key pressed */
@@ -454,7 +462,7 @@ void resetpc_cad()
int suppress_overscan = 0;
void resetpchard()
void resetpchard(void)
{
int i = 0;
@@ -475,7 +483,7 @@ void resetpchard()
mem_resize();
fdc_init();
disc_reset();
model_init();
mouse_emu_init();
video_init();
@@ -566,7 +574,7 @@ int emu_fps = 0;
static WCHAR wmodel[2048];
static WCHAR wcpu[2048];
void runpc()
void runpc(void)
{
wchar_t s[200];
int done=0;
@@ -651,7 +659,7 @@ void runpc()
done++;
}
void fullspeed()
void fullspeed(void)
{
cpuspeed2=cpuspeed;
if (!atfullspeed)
@@ -666,7 +674,7 @@ void fullspeed()
nvr_recalc();
}
void speedchanged()
void speedchanged(void)
{
if (AT)
setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed);
@@ -675,7 +683,7 @@ void speedchanged()
nvr_recalc();
}
void closepc()
void closepc(void)
{
int i = 0;
for (i = 0; i < CDROM_NUM; i++)
@@ -693,18 +701,6 @@ void closepc()
midi_close();
}
/*int main()
{
initpc();
while (!key[KEY_F11])
{
runpc();
}
closepc();
return 0;
}
END_OF_MAIN();*/
void loadconfig(wchar_t *fn)
{
@@ -970,7 +966,7 @@ wchar_t *nvr_concat(wchar_t *to_concat)
return temp_nvr_path;
}
void saveconfig()
void saveconfig(void)
{
int c, d;

View File

@@ -89,24 +89,24 @@ void serial1_handler()
temp = (pc87306_regs[1] >> 2) & 3;
switch (temp)
{
case 0: serial1_set(0x3f8, uart1_int()); break;
case 1: serial1_set(0x2f8, uart1_int()); break;
case 0: serial_setup(1, SERIAL1_ADDR, uart1_int()); break;
case 1: serial_setup(1, SERIAL2_ADDR, uart1_int()); break;
case 2:
switch ((pc87306_regs[1] >> 6) & 3)
{
case 0: serial1_set(0x3e8, uart1_int()); break;
case 1: serial1_set(0x338, uart1_int()); break;
case 2: serial1_set(0x2e8, uart1_int()); break;
case 3: serial1_set(0x220, uart1_int()); break;
case 0: serial_setup(1, 0x3e8, uart1_int()); break;
case 1: serial_setup(1, 0x338, uart1_int()); break;
case 2: serial_setup(1, 0x2e8, uart1_int()); break;
case 3: serial_setup(1, 0x220, uart1_int()); break;
}
break;
case 3:
switch ((pc87306_regs[1] >> 6) & 3)
{
case 0: serial1_set(0x2e8, uart1_int()); break;
case 1: serial1_set(0x238, uart1_int()); break;
case 2: serial1_set(0x2e0, uart1_int()); break;
case 3: serial1_set(0x228, uart1_int()); break;
case 0: serial_setup(1, 0x2e8, uart1_int()); break;
case 1: serial_setup(1, 0x238, uart1_int()); break;
case 2: serial_setup(1, 0x2e0, uart1_int()); break;
case 3: serial_setup(1, 0x228, uart1_int()); break;
}
break;
}
@@ -118,24 +118,24 @@ void serial2_handler()
temp = (pc87306_regs[1] >> 4) & 3;
switch (temp)
{
case 0: serial2_set(0x3f8, uart2_int()); break;
case 1: serial2_set(0x2f8, uart2_int()); break;
case 0: serial_setup(2, SERIAL1_ADDR, uart2_int()); break;
case 1: serial_setup(2, SERIAL2_ADDR, uart2_int()); break;
case 2:
switch ((pc87306_regs[1] >> 6) & 3)
{
case 0: serial2_set(0x3e8, uart2_int()); break;
case 1: serial2_set(0x338, uart2_int()); break;
case 2: serial2_set(0x2e8, uart2_int()); break;
case 3: serial2_set(0x220, uart2_int()); break;
case 0: serial_setup(2, 0x3e8, uart2_int()); break;
case 1: serial_setup(2, 0x338, uart2_int()); break;
case 2: serial_setup(2, 0x2e8, uart2_int()); break;
case 3: serial_setup(2, 0x220, uart2_int()); break;
}
break;
case 3:
switch ((pc87306_regs[1] >> 6) & 3)
{
case 0: serial2_set(0x2e8, uart2_int()); break;
case 1: serial2_set(0x238, uart2_int()); break;
case 2: serial2_set(0x2e0, uart2_int()); break;
case 3: serial2_set(0x228, uart2_int()); break;
case 0: serial_setup(2, 0x2e8, uart2_int()); break;
case 1: serial_setup(2, 0x238, uart2_int()); break;
case 2: serial_setup(2, 0x2e0, uart2_int()); break;
case 3: serial_setup(2, 0x228, uart2_int()); break;
}
break;
}
@@ -206,7 +206,7 @@ process_value:
if (valxor & 2)
{
serial1_remove();
serial_remove(1);
if (val & 2)
{
serial1_handler();
@@ -214,7 +214,7 @@ process_value:
}
if (valxor & 4)
{
serial2_remove();
serial_remove(2);
if (val & 4)
{
serial2_handler();
@@ -266,7 +266,7 @@ process_value:
}
else
{
serial1_remove();
serial_remove(1);
}
}
@@ -278,7 +278,7 @@ process_value:
}
else
{
serial2_remove();
serial_remove(2);
}
}
break;
@@ -288,8 +288,8 @@ process_value:
if (val & 1)
{
lpt1_remove();
serial1_remove();
serial2_remove();
serial_remove(1);
serial_remove(2);
fdc_remove();
}
else
@@ -448,8 +448,8 @@ void pc87306_reset(void)
fdc_remove();
fdc_set_base(0x3f0, 0);
fdd_swap = 0;
serial1_remove();
serial2_remove();
serial_remove(1);
serial_remove(2);
serial1_handler();
serial2_handler();
pc87306_gpio_init();

View File

@@ -74,9 +74,9 @@ void ps1_write(uint16_t port, uint8_t val, void *p)
case 0x102:
lpt1_remove();
if (val & 0x04)
serial1_init(0x3f8, 4);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial1_remove();
serial_remove(1);
if (val & 0x10)
{
switch ((val >> 5) & 3)
@@ -155,8 +155,8 @@ void ps1mb_init()
lpt2_remove();
lpt1_init(0x3bc);
serial1_remove();
serial2_remove();
serial_remove(1);
serial_remove(2);
memset(&ps1_hd, 0, sizeof(ps1_hd));
}
@@ -242,9 +242,9 @@ void ps1_m2121_write(uint16_t port, uint8_t val, void *p)
case 0x102:
lpt1_remove();
if (val & 0x04)
serial1_init(0x3f8, 4);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial1_remove();
serial_remove(1);
if (val & 0x10)
{
switch ((val >> 5) & 3)
@@ -299,8 +299,8 @@ void ps1mb_m2121_init()
lpt2_remove();
lpt1_init(0x3bc);
serial1_remove();
serial2_remove();
serial_remove(1);
serial_remove(2);
mem_remap_top_384k();
}

View File

@@ -68,9 +68,9 @@ void ps2_write(uint16_t port, uint8_t val, void *p)
case 0x102:
lpt1_remove();
if (val & 0x04)
serial1_init(0x3f8, 4);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial1_remove();
serial_remove(1);
if (val & 0x10)
{
switch ((val >> 5) & 3)
@@ -131,8 +131,8 @@ void ps2board_init()
lpt2_remove();
lpt1_init(0x3bc);
serial1_remove();
serial2_remove();
serial_remove(1);
serial_remove(2);
memset(&ps2_hd, 0, sizeof(ps2_hd));
}

View File

@@ -192,16 +192,16 @@ static void model_50_write(uint16_t port, uint8_t val)
break;
case 0x102:
lpt1_remove();
serial1_remove();
serial_remove(1);
if (val & 0x04)
{
if (val & 0x08)
serial1_init(0x3f8, 4);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial1_init(0x2f8, 3);
serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ);
}
else
serial1_remove();
serial_remove(1);
if (val & 0x10)
{
switch ((val >> 5) & 3)
@@ -248,16 +248,16 @@ static void model_55sx_write(uint16_t port, uint8_t val)
break;
case 0x102:
lpt1_remove();
serial1_remove();
serial_remove(1);
if (val & 0x04)
{
if (val & 0x08)
serial1_init(0x3f8, 4);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial1_init(0x2f8, 3);
serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ);
}
else
serial1_remove();
serial_remove(1);
if (val & 0x10)
{
switch ((val >> 5) & 3)
@@ -324,16 +324,16 @@ static void model_80_write(uint16_t port, uint8_t val)
break;
case 0x102:
lpt1_remove();
serial1_remove();
serial_remove(1);
if (val & 0x04)
{
if (val & 0x08)
serial1_init(0x3f8, 4);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial1_init(0x2f8, 3);
serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ);
}
else
serial1_remove();
serial_remove(1);
if (val & 0x10)
{
switch ((val >> 5) & 3)
@@ -556,8 +556,8 @@ static void ps2_mca_board_common_init()
lpt2_remove();
lpt1_init(0x3bc);
serial1_remove();
serial2_remove();
serial_remove(1);
serial_remove(2);
}
void ps2_mca_board_model_50_init()

View File

@@ -1,295 +1,621 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of NS8250-series UART devices.
*
* The original IBM-PC design did not have any serial ports of
* any kind. Rather, these were offered as add-on devices, most
* likely because a) most people did not need one at the time,
* and, b) this way, IBM could make more money off them.
*
* So, for the PC, the offerings were for an IBM Asynchronous
* Communications Adapter, and, later, a model for synchronous
* communications.
*
* The "Async Adapter" was based on the NS8250 UART chip, and
* is what we now call the "serial" or "com" port of the PC.
*
* Of course, many system builders came up with similar boards,
* and even more boards were designed where several I/O functions
* were combined into a single board: the Multi-I/O adapters.
* Initially, these had all the chips as-is, but later many of
* these functions were integrated into a single MIO chip.
*
* This file implements the standard NS8250 series of chips, with
* support for the later (16450 and 16550) FIFO additions. On the
* lower half of the driver, we interface to the host system's
* serial ports for real-world access.
*
* Based on the 86Box serial port driver as a framework.
*
* Version: @(#)serial.c 1.0.3 2017/05/06
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 2017 Fred N. van Kempen.
*/
#include "ibm.h"
#include "io.h"
#include "mouse.h"
#include "pic.h"
#include "serial.h"
#include "timer.h"
#include "serial.h"
#include "plat-serial.h"
enum
{
SERIAL_INT_LSR = 1,
SERIAL_INT_RECEIVE = 2,
SERIAL_INT_TRANSMIT = 4,
SERIAL_INT_MSR = 8
enum {
SERINT_LSR = 1,
SERINT_RECEIVE = 2,
SERINT_TRANSMIT = 4,
SERINT_MSR = 8
};
SERIAL serial1, serial2;
void serial_reset()
{
serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0;
serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0;
serial1.fifo_read = serial1.fifo_write = 0;
serial2.fifo_read = serial2.fifo_write = 0;
}
/* IER register bits. */
#define IER_RDAIE (0x01)
#define IER_THREIE (0x02)
#define IER_RXLSIE (0x04)
#define IER_MSIE (0x08)
#define IER_SLEEP (0x10) /* NS16750 */
#define IER_LOWPOWER (0x20) /* NS16750 */
#define IER_MASK (0x0f) /* not including SLEEP|LOWP */
void serial_update_ints(SERIAL *serial)
/* IIR register bits. */
#define IIR_IP (0x01)
#define IIR_IID (0x0e)
# define IID_IDMDM (0x00)
# define IID_IDTX (0x02)
# define IID_IDRX (0x04)
# define IID_IDERR (0x06)
# define IID_IDTMO (0x0c)
#define IIR_IIRFE (0xc0)
# define IIR_FIFO64 (0x20)
# define IIR_FIFOBAD (0x80) /* 16550 */
# define IIR_FIFOENB (0xc0)
/* FCR register bits. */
#define FCR_FCRFE (0x01)
#define FCR_RFR (0x02)
#define FCR_TFR (0x04)
#define FCR_SELDMA1 (0x08)
#define FCR_FENB64 (0x20) /* 16750 */
#define FCR_RTLS (0xc0)
# define FCR_RTLS1 (0x00)
# define FCR_RTLS4 (0x40)
# define FCR_RTLS8 (0x80)
# define FCR_RTLS14 (0xc0)
/* LCR register bits. */
#define LCR_WLS (0x03)
# define WLS_BITS5 (0x00)
# define WLS_BITS6 (0x01)
# define WLS_BITS7 (0x02)
# define WLS_BITS8 (0x03)
#define LCR_SBS (0x04)
#define LCR_PE (0x08)
#define LCR_EP (0x10)
#define LCR_PS (0x20)
# define PAR_NONE (0x00)
# define PAR_EVEN (LCR_PE | LCR_EP)
# define PAR_ODD (LCR_PE)
# define PAR_MARK (LCR_PE | LCR_PS)
# define PAR_SPACE (LCR_PE | LCR_PS | LCR_EP)
#define LCR_BC (0x40)
#define LCR_DLAB (0x80)
/* MCR register bits. */
#define MCR_DTR (0x01)
#define MCR_RTS (0x02)
#define MCR_OUT1 (0x04) /* 8250 */
#define MCR_OUT2 (0x08) /* 8250, INTEN on IBM-PC */
#define MCR_LMS (0x10)
#define MCR_AUTOFLOW (0x20) /* 16750
/* LSR register bits. */
#define LSR_DR (0x01)
#define LSR_OE (0x02)
#define LSR_PE (0x04)
#define LSR_FE (0x08)
#define LSR_BI (0x10)
#define LSR_THRE (0x20)
#define LSR_TEMT (0x40)
#define LSR_RXFE (0x80)
/* MSR register bits. */
#define MSR_DCTS (0x01)
#define MSR_DDSR (0x02)
#define MSR_TERI (0x04)
#define MSR_DDCD (0x08)
#define MSR_CTS (0x10)
#define MSR_DSR (0x20)
#define MSR_RI (0x40)
#define MSR_DCD (0x80)
#define MSR_MASK (0x0f)
static SERIAL serial1, /* serial port 1 data */
serial2; /* serial port 2 data */
static void
update_ints(SERIAL *sp)
{
int stat = 0;
int stat = 0;
serial->iir = 1;
sp->iir = IIR_IP;
if ((sp->ier & IER_RXLSIE) && (sp->int_status & SERINT_LSR)) {
/* Line Status interrupt. */
stat = 1;
sp->iir = IID_IDERR;
} else if ((sp->ier & IER_RDAIE) && (sp->int_status & SERINT_RECEIVE)) {
/* Received Data available. */
stat = 1;
sp->iir = IID_IDRX;
} else if ((sp->ier & IER_THREIE) && (sp->int_status & SERINT_TRANSMIT)) {
/* Transmit Data empty. */
stat = 1;
sp->iir = IID_IDTX;
} else if ((sp->ier & IER_MSIE) && (sp->int_status & SERINT_MSR)) {
/* Modem Status interrupt. */
stat = 1;
sp->iir = IID_IDMDM;
}
if ((serial->ier & 4) && (serial->int_status & SERIAL_INT_LSR)) /*Line status interrupt*/
{
stat = 1;
serial->iir = 6;
}
else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Recieved data available*/
{
stat = 1;
serial->iir = 4;
}
else if ((serial->ier & 2) && (serial->int_status & SERIAL_INT_TRANSMIT)) /*Transmit data empty*/
{
stat = 1;
serial->iir = 2;
}
else if ((serial->ier & 8) && (serial->int_status & SERIAL_INT_MSR)) /*Modem status interrupt*/
{
stat = 1;
serial->iir = 0;
}
if (stat && ((serial->mctrl & 8) || PCJR))
picintlevel(1 << serial->irq);
else
picintc(1 << serial->irq);
/* Raise or clear the level-based IRQ. */
if (stat && ((sp->mctrl & MCR_OUT2) || PCJR))
picintlevel(1 << sp->irq);
else
picintc(1 << sp->irq);
}
void serial_write_fifo(SERIAL *serial, uint8_t dat)
/* Fake interrupt generator, needed for Serial Mouse. */
static void
serial_timer(void *priv)
{
serial->fifo[serial->fifo_write] = dat;
serial->fifo_write = (serial->fifo_write + 1) & 0xFF;
if (!(serial->lsr & 1))
{
serial->lsr |= 1;
serial->int_status |= SERIAL_INT_RECEIVE;
serial_update_ints(serial);
}
SERIAL *sp = (SERIAL *)priv;
sp->receive_delay = 0;
if (sp->fifo_read != sp->fifo_write) {
sp->lsr |= LSR_DR;
sp->int_status |= SERINT_RECEIVE;
update_ints(sp);
}
}
uint8_t serial_read_fifo(SERIAL *serial)
/* Write data to the (input) FIFO. Used by MOUSE driver. */
void
serial_write_fifo(SERIAL *sp, uint8_t dat)
{
if (serial->fifo_read != serial->fifo_write)
{
serial->dat = serial->fifo[serial->fifo_read];
serial->fifo_read = (serial->fifo_read + 1) & 0xFF;
}
return serial->dat;
/* Stuff data into FIFO. */
sp->fifo[sp->fifo_write] = dat;
sp->fifo_write = (sp->fifo_write + 1) & 0xFF;
if (! (sp->lsr & LSR_DR)) {
sp->lsr |= LSR_DR;
sp->int_status |= SERINT_RECEIVE;
update_ints(sp);
}
}
void serial_write(uint16_t addr, uint8_t val, void *p)
static uint8_t
read_fifo(SERIAL *sp)
{
SERIAL *serial = (SERIAL *)p;
switch (addr&7)
{
case 0:
if (serial->lcr & 0x80)
{
serial->dlab1 = val;
return;
}
serial->thr = val;
serial->lsr |= 0x20;
serial->int_status |= SERIAL_INT_TRANSMIT;
serial_update_ints(serial);
if (serial->mctrl & 0x10)
{
serial_write_fifo(serial, val);
}
break;
case 1:
if (serial->lcr & 0x80)
{
serial->dlab2 = val;
return;
}
serial->ier = val & 0xf;
serial_update_ints(serial);
break;
case 2:
serial->fcr = val;
break;
case 3:
serial->lcr = val;
break;
case 4:
if ((val & 2) && !(serial->mctrl & 2))
{
if (serial->rcr_callback)
serial->rcr_callback(serial, serial->rcr_callback_p);
}
serial->mctrl = val;
if (val & 0x10)
{
uint8_t new_msr;
new_msr = (val & 0x0c) << 4;
new_msr |= (val & 0x02) ? 0x10: 0;
new_msr |= (val & 0x01) ? 0x20: 0;
if ((serial->msr ^ new_msr) & 0x10)
new_msr |= 0x01;
if ((serial->msr ^ new_msr) & 0x20)
new_msr |= 0x02;
if ((serial->msr ^ new_msr) & 0x80)
new_msr |= 0x08;
if ((serial->msr & 0x40) && !(new_msr & 0x40))
new_msr |= 0x04;
serial->msr = new_msr;
}
break;
case 5:
serial->lsr = val;
if (serial->lsr & 0x01)
serial->int_status |= SERIAL_INT_RECEIVE;
if (serial->lsr & 0x1e)
serial->int_status |= SERIAL_INT_LSR;
if (serial->lsr & 0x20)
serial->int_status |= SERIAL_INT_TRANSMIT;
serial_update_ints(serial);
break;
case 6:
serial->msr = val;
if (serial->msr & 0x0f)
serial->int_status |= SERIAL_INT_MSR;
serial_update_ints(serial);
break;
case 7:
serial->scratch = val;
break;
}
if (sp->fifo_read != sp->fifo_write) {
sp->dat = sp->fifo[sp->fifo_read];
sp->fifo_read = (sp->fifo_read + 1) & 0xFF;
}
return(sp->dat);
}
uint8_t serial_read(uint16_t addr, void *p)
{
SERIAL *serial = (SERIAL *)p;
uint8_t temp = 0;
switch (addr&7)
{
case 0:
if (serial->lcr & 0x80)
{
temp = serial->dlab1;
break;
}
serial->lsr &= ~1;
serial->int_status &= ~SERIAL_INT_RECEIVE;
serial_update_ints(serial);
temp = serial_read_fifo(serial);
if (serial->fifo_read != serial->fifo_write)
serial->recieve_delay = 1000 * TIMER_USEC;
break;
case 1:
if (serial->lcr & 0x80)
temp = serial->dlab2;
else
temp = serial->ier;
break;
case 2:
temp = serial->iir;
if ((temp & 0xe) == 2)
{
serial->int_status &= ~SERIAL_INT_TRANSMIT;
serial_update_ints(serial);
}
if (serial->fcr & 1)
temp |= 0xc0;
break;
case 3:
temp = serial->lcr;
break;
case 4:
temp = serial->mctrl;
break;
case 5:
if (serial->lsr & 0x20)
serial->lsr |= 0x40;
serial->lsr |= 0x20;
temp = serial->lsr;
if (serial->lsr & 0x1f)
serial->lsr &= ~0x1e;
serial->int_status &= ~SERIAL_INT_LSR;
serial_update_ints(serial);
break;
case 6:
temp = serial->msr;
serial->msr &= ~0x0f;
serial->int_status &= ~SERIAL_INT_MSR;
serial_update_ints(serial);
break;
case 7:
temp = serial->scratch;
break;
}
return temp;
/* BHTTY WRITE COMPLETE handler. */
static void
serial_wr_done(void *arg)
{
SERIAL *sp = (SERIAL *)arg;
/* The WRITE completed, we are ready for more. */
sp->lsr |= LSR_THRE;
sp->int_status |= SERINT_TRANSMIT;
update_ints(sp);
}
void serial_recieve_callback(void *p)
/* Handle a WRITE operation to one of our registers. */
static void
serial_write(uint16_t addr, uint8_t val, void *priv)
{
SERIAL *serial = (SERIAL *)p;
serial->recieve_delay = 0;
if (serial->fifo_read != serial->fifo_write)
{
serial->lsr |= 1;
serial->int_status |= SERIAL_INT_RECEIVE;
serial_update_ints(serial);
}
SERIAL *sp = (SERIAL *)priv;
uint8_t wl, sb, pa;
uint16_t baud;
long speed;
switch (addr & 0x07) {
case 0: /* DATA / DLAB1 */
if (sp->lcr & LCR_DLAB) {
sp->dlab1 = val;
return;
}
sp->thr = val;
if (sp->bh != NULL) {
/* We are linked, so send to BH layer. */
#if 0
bhtty_write((BHTTY *)sp->bh,
sp->thr, serial_wr_done, sp);
#else
bhtty_write((BHTTY *)sp->bh, sp->thr);
serial_wr_done(sp);
#endif
} else {
/* Not linked. Just fake LOOPBACK mode. */
if (! (sp->mctrl & MCR_LMS))
serial_write_fifo(sp, val);
}
if (sp->mctrl & MCR_LMS) {
/* Echo data back to RX. */
serial_write_fifo(sp, val);
}
break;
case 1: /* IER / DLAB2 */
if (sp->lcr & LCR_DLAB) {
sp->dlab2 = val;
return;
}
sp->ier = (val & IER_MASK);
update_ints(sp);
break;
case 2: /* FCR */
sp->fcr = val;
break;
case 3: /* LCR */
if ((sp->lcr & LCR_DLAB) && !(val & LCR_DLAB)) {
/* We dropped DLAB, so handle baudrate. */
baud = ((sp->dlab2 << 8) | sp->dlab1);
speed = 115200UL/baud;
#if 0
pclog("Serial%d: new divisor %u, baudrate %ld\n",
sp->port, baud, speed);
#endif
if (sp->bh != NULL)
bhtty_speed((BHTTY *)sp->bh, speed);
}
wl = (val & LCR_WLS) + 5; /* databits */
sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */
pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3;
#if 0
pclog("Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa);
#endif
if (sp->bh != NULL)
bhtty_params((BHTTY *)sp->bh, wl, pa, sb);
sp->lcr = val;
break;
case 4:
if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) {
/*
* This is old code for use by the Serial Mouse
* driver. If the user toggles RTS, serial mice
* are expected to send an ID, to inform any
* enumerator there 'is' something.
*/
if (sp->rts_callback) {
sp->rts_callback(sp, sp->rts_callback_p);
#if 0
pclog("RTS raised; sending ID\n");
#endif
}
}
if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) {
if (sp->bh != NULL) {
/* Linked, start reading from host port. */
(void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1);
} else {
/* Not linked, start RX timer. */
timer_add(serial_timer,
&sp->receive_delay,
&sp->receive_delay, sp);
#if 0
pclog("Serial%d: RX timer started!\n",sp->port);
#endif
}
}
sp->mctrl = val;
if (val & MCR_LMS) { /* loopback mode */
uint8_t new_msr;
/*FIXME: WTF does this do?? --FvK */
new_msr = (val & 0x0c) << 4;
new_msr |= (val & MCR_RTS) ? MCR_LMS : 0;
new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0;
if ((sp->msr ^ new_msr) & 0x10)
new_msr |= MCR_DTR;
if ((sp->msr ^ new_msr) & 0x20)
new_msr |= MCR_RTS;
if ((sp->msr ^ new_msr) & 0x80)
new_msr |= 0x08;
if ((sp->msr & 0x40) && !(new_msr & 0x40))
new_msr |= 0x04;
sp->msr = new_msr;
}
break;
case 5:
sp->lsr = val;
if (sp->lsr & LSR_DR)
sp->int_status |= SERINT_RECEIVE;
if (sp->lsr & 0x1e)
sp->int_status |= SERINT_LSR;
if (sp->lsr & LSR_THRE)
sp->int_status |= SERINT_TRANSMIT;
update_ints(sp);
break;
case 6:
sp->msr = val;
if (sp->msr & MSR_MASK)
sp->int_status |= SERINT_MSR;
update_ints(sp);
break;
case 7:
sp->scratch = val;
break;
}
}
uint16_t serial_addr[2] = { 0x3f8, 0x2f8 };
int serial_irq[2] = { 4, 3 };
/*Tandy might need COM1 at 2f8*/
void serial1_init(uint16_t addr, int irq)
/* BHTTY READ COMPLETE handler. */
static void
serial_rd_done(void *arg, int num)
{
memset(&serial1, 0, sizeof(serial1));
io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
serial1.irq = irq;
serial1.rcr_callback = NULL;
timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1);
serial_addr[0] = addr;
serial_irq[0] = irq;
}
void serial1_set(uint16_t addr, int irq)
{
serial1_remove();
io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
serial1.irq = irq;
serial_addr[0] = addr;
serial_irq[0] = irq;
}
void serial1_remove()
{
io_removehandler(serial_addr[0], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
SERIAL *sp = (SERIAL *)arg;
#if 0
pclog("%04x: %d bytes available: %02x (%c)\n",sp->addr,num,sp->hold,sp->hold);
#endif
/* Stuff the byte in the FIFO and set intr. */
serial_write_fifo(sp, sp->hold);
/* Start up the next read from the real port. */
if (sp->bh != NULL)
(void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1);
}
void serial2_init(uint16_t addr, int irq)
/* Handle a READ operation from one of our registers. */
static uint8_t
serial_read(uint16_t addr, void *priv)
{
memset(&serial2, 0, sizeof(serial2));
io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
serial2.irq = irq;
serial2.rcr_callback = NULL;
timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2);
serial_addr[1] = addr;
serial_irq[1] = irq;
SERIAL *sp = (SERIAL *)priv;
uint8_t ret = 0x00;
switch (addr&0x07) {
case 0: /* DATA / DLAB1 */
if (sp->lcr & LCR_DLAB) {
ret = sp->dlab1;
break;
}
sp->lsr &= ~LSR_DR;
sp->int_status &= ~SERINT_RECEIVE;
update_ints(sp);
ret = read_fifo(sp);
if ((sp->bh == NULL) && (sp->fifo_read != sp->fifo_write))
sp->receive_delay = 1000 * TIMER_USEC;
break;
case 1: /* LCR / DLAB2 */
if (sp->lcr & LCR_DLAB)
ret = sp->dlab2;
else
ret = sp->ier;
break;
case 2: /* IIR */
ret = sp->iir;
if ((ret & IIR_IID) == IID_IDTX) {
sp->int_status &= ~SERINT_TRANSMIT;
update_ints(sp);
}
if (sp->fcr & 0x01) {
ret |= 0xc0;
}
break;
case 3: /* LCR */
ret = sp->lcr;
break;
case 4: /* MCR */
ret = sp->mctrl;
break;
case 5: /* LSR */
if (sp->lsr & LSR_THRE)
sp->lsr |= LSR_TEMT;
sp->lsr |= LSR_THRE;
ret = sp->lsr;
if (sp->lsr & 0x1f)
sp->lsr &= ~0x1e;
#if 0
sp->lsr |= (LSR_THRE | LSR_TEMT);
#endif
sp->int_status &= ~SERINT_LSR;
update_ints(sp);
break;
case 6:
ret = sp->msr;
sp->msr &= ~0x0f;
sp->int_status &= ~SERINT_MSR;
update_ints(sp);
break;
case 7:
ret = sp->scratch;
break;
}
return(ret);
}
void serial2_set(uint16_t addr, int irq)
/* Set up a serial port for use. */
void
serial_setup(int port, uint16_t addr, int irq)
{
serial2_remove();
io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
serial2.irq = irq;
serial_addr[1] = addr;
serial_irq[1] = irq;
SERIAL *sp;
pclog("Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq);
/* Grab the desired port block. */
sp = (port == 2) ? &serial2 : &serial1;
/* Set up the basic info. */
if (sp->addr != 0x0000) {
/* Unlink the previous handler. Just in case. */
io_removehandler(sp->addr, 8,
serial_read, NULL, NULL,
serial_write, NULL, NULL, sp);
}
sp->addr = addr;
sp->irq = irq;
/* Request an I/O range. */
io_sethandler(sp->addr, 8,
serial_read, NULL, NULL,
serial_write, NULL, NULL, sp);
/* No DTR/RTS callback for now. */
sp->rts_callback = NULL;
}
void serial2_remove()
/* Release all resources held by a serial port. */
void
serial_remove(int port)
{
io_removehandler(serial_addr[1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
SERIAL *sp;
/* Grab the desired port block. */
sp = (port == 2) ? &serial2 : &serial1;
// FIXME: stop timer, if enabled!
/* Remove any callbacks. */
sp->rts_callback = NULL;
/* Close the host device. */
(void)serial_link(port, NULL);
/* Release our I/O range. */
if (sp->addr != 0x0000) {
io_removehandler(sp->addr, 8,
serial_read, NULL, NULL,
serial_write, NULL, NULL, sp);
}
sp->addr = 0x0000;
sp->irq = 0;
}
/* Initialize the serial ports. */
void
serial_init(void)
{
memset(&serial1, 0x00, sizeof(SERIAL));
serial1.port = 1;
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
memset(&serial2, 0x00, sizeof(SERIAL));
serial2.port = 2;
serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ);
}
/*
* Reset the serial ports.
*
* This should be a per-port function.
*/
void
serial_reset(void)
{
serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0;
serial1.fifo_read = serial1.fifo_write = 0;
serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0;
serial2.fifo_read = serial2.fifo_write = 0;
}
/* Link a serial port to a host (serial) port. */
int
serial_link(int port, char *arg)
{
SERIAL *sp;
BHTTY *bh;
/* Grab the desired port block. */
sp = (port == 2) ? &serial2 : &serial1;
if (arg != NULL) {
/* Make sure we're not already linked. */
if (sp->bh != NULL) {
pclog("Serial%d already linked!\n", port);
return(-1);
}
/* Request a port from the host system. */
bh = bhtty_open(arg, 0);
if (bh == NULL) {
pclog("Serial%d unable to link to '%s' !\n", port, arg);
return(-1);
}
sp->bh = bh;
/* Set up bottom-half I/O callback info. */
bh->rd_done = serial_rd_done;
bh->rd_arg = sp;
} else {
/* If we are linked, unlink it. */
if (sp->bh != NULL) {
bhtty_close((BHTTY *)sp->bh);
sp->bh = NULL;
}
}
return(0);
}
/* Attach another device (MOUSE) to a serial port. */
SERIAL *
serial_attach(int port, void *func, void *arg)
{
SERIAL *sp;
/* Grab the desired port block. */
sp = (port == 2) ? &serial2 : &serial1;
/* Set up callback info. */
sp->rts_callback = func;
sp->rts_callback_p = arg;
return(sp);
}

View File

@@ -1,35 +1,64 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
void serial1_init(uint16_t addr, int irq);
void serial2_init(uint16_t addr, int irq);
void serial1_set(uint16_t addr, int irq);
void serial2_set(uint16_t addr, int irq);
void serial1_remove();
void serial2_remove();
void serial_reset();
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the SERIAL card.
*
* Version: @(#)serial.h 1.0.2 2017/05/06
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 2017 Fred N. van Kempen.
*/
#ifndef SERIAL_H
# define SERIAL_H
struct SERIAL;
typedef struct
{
uint8_t lsr,thr,mctrl,rcr,iir,ier,lcr,msr;
uint8_t dlab1,dlab2;
uint8_t dat;
uint8_t int_status;
uint8_t scratch;
uint8_t fcr;
int irq;
/* Default settings for the standard ports. */
#define SERIAL1_ADDR 0x03f8
#define SERIAL1_IRQ 4
#define SERIAL2_ADDR 0x02f8
#define SERIAL2_IRQ 3
void (*rcr_callback)(struct SERIAL *serial, void *p);
void *rcr_callback_p;
uint8_t fifo[256];
int fifo_read, fifo_write;
int recieve_delay;
typedef struct _serial_ {
int8_t port; /* port number (1,2,..) */
int8_t irq; /* IRQ channel used */
uint16_t addr; /* I/O address used */
uint8_t lsr, thr, mctrl, rcr, /* UART registers */
iir, ier, lcr, msr;
uint8_t dlab1, dlab2;
uint8_t dat;
uint8_t int_status;
uint8_t scratch;
uint8_t fcr;
/* Data for the RTS-toggle callback. */
void (*rts_callback)(struct _serial_ *, void *);
void *rts_callback_p;
uint8_t hold;
uint8_t fifo[256];
int fifo_read, fifo_write;
int receive_delay;
void *bh; /* BottomHalf handler */
} SERIAL;
extern SERIAL serial1, serial2;
void serial_write_fifo(SERIAL *serial, uint8_t dat);
/* Functions. */
extern void serial_init(void);
extern void serial_reset(void);
extern void serial_setup(int port, uint16_t addr, int irq);
extern void serial_remove(int port);
extern SERIAL *serial_attach(int, void *, void *);
extern int serial_link(int, char *);
extern void serial_write_fifo(SERIAL *, uint8_t);
#endif /*SERIAL_H*/

View File

@@ -58,13 +58,13 @@ process_value:
{
if (val & 0x20)
{
serial1_init(0x3f8, 4);
serial2_init(0x2f8, 3);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ);
}
else
{
serial1_remove();
serial2_remove();
serial_remove(1);
serial_remove(2);
}
}

View File

@@ -92,10 +92,10 @@ void um8669f_write(uint16_t port, uint8_t val, void *priv)
temp |= 2;
switch (temp)
{
case 0: serial1_set(0x3f8, 4); break;
case 1: serial1_set(0x2f8, 4); break;
case 2: serial1_set(0x3e8, 4); break;
case 3: serial1_set(0x2e8, 4); break;
case 0: serial_setup(1, 0x3f8, 4); break;
case 1: serial_setup(1, 0x2f8, 4); break;
case 2: serial_setup(1, 0x3e8, 4); break;
case 3: serial_setup(1, 0x2e8, 4); break;
}
}
@@ -106,10 +106,10 @@ void um8669f_write(uint16_t port, uint8_t val, void *priv)
temp |= 2;
switch (temp)
{
case 0: serial2_set(0x3f8, 3); break;
case 1: serial2_set(0x2f8, 3); break;
case 2: serial2_set(0x3e8, 3); break;
case 3: serial2_set(0x2e8, 3); break;
case 0: serial_setup(2, 0x3f8, 3); break;
case 1: serial_setup(2, 0x2f8, 3); break;
case 2: serial_setup(2, 0x3e8, 3); break;
case 3: serial_setup(2, 0x2e8, 3); break;
}
}

View File

@@ -340,15 +340,15 @@ process_value:
case 4:
if (valxor & 0x10)
{
serial2_remove();
if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF);
serial_remove(2);
if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF);
}
if (valxor & 0x20)
{
serial1_remove();
serial_remove(1);
if (!(w83877f_regs[4] & 0x20))
{
serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8);
serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8);
}
}
if (valxor & 0x80)
@@ -407,28 +407,28 @@ process_value:
{
if (!(w83877f_regs[4] & 0x20))
{
serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8);
serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8);
}
}
break;
case 0x25:
if (valxor & 0xfe)
{
if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF);
if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF);
}
break;
case 0x28:
if (valxor & 0xf)
{
if ((w83877f_regs[0x28] & 0xf) == 0) w83877f_regs[0x28] |= 0x3;
if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF);
if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF);
}
if (valxor & 0xf0)
{
if ((w83877f_regs[0x28] & 0xf0) == 0) w83877f_regs[0x28] |= 0x40;
if (!(w83877f_regs[4] & 0x20))
{
serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8);
serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8);
}
}
break;
@@ -498,8 +498,8 @@ void w83877f_reset(void)
disable_write = 0;
fdc_update_drv2en(1);
fdd_setswap(0);
serial1_set(0x3f8, 4);
serial2_set(0x2f8, 3);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ);
w83877f_remap();
w83877f_locked = 0;
w83877f_rw_locked = 0;

View File

@@ -50,17 +50,17 @@ void wd76c10_write(uint16_t port, uint16_t val, void *priv)
switch ((val >> 5) & 7)
{
case 1: serial1_set(0x3f8, 4); break;
case 2: serial1_set(0x2f8, 4); break;
case 3: serial1_set(0x3e8, 4); break;
case 4: serial1_set(0x2e8, 4); break;
case 1: serial_setup(1, 0x3f8, 4); break;
case 2: serial_setup(1, 0x2f8, 4); break;
case 3: serial_setup(1, 0x3e8, 4); break;
case 4: serial_setup(1, 0x2e8, 4); break;
}
switch ((val >> 1) & 7)
{
case 1: serial2_set(0x3f8, 3); break;
case 2: serial2_set(0x2f8, 3); break;
case 3: serial2_set(0x3e8, 3); break;
case 4: serial2_set(0x2e8, 3); break;
case 1: serial_setup(2, 0x3f8, 3); break;
case 2: serial_setup(2, 0x2f8, 3); break;
case 3: serial_setup(2, 0x3e8, 3); break;
case 4: serial_setup(2, 0x2e8, 3); break;
}
break;

View File

@@ -22,7 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
#define BHTTY_C
#include "win-serial.h"
#include "plat-serial.h"
extern void pclog(char *__fmt, ...);

View File

@@ -1,53 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the Bottom Half of the SERIAL card.
*
* Version: @(#)win-serial.h 1.0.2 2017/05/05
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 2017 Fred N. van Kempen.
*/
#ifndef SERIAL_BH_H
# define SERIAL_BH_H
#define BHTTY_PORT1 "COM2" /* port 1 connects to .. */
#define BHTTY_PORT2 "COM4" /* port 2 connects to .. */
typedef struct {
char name[79]; /* name of open port */
void (*rd_done)(void *, int);
void *rd_arg;
#ifdef BHTTY_C
HANDLE handle;
OVERLAPPED rov, /* READ and WRITE events */
wov;
int tmo; /* current timeout value */
DCB dcb, /* terminal settings */
odcb;
#endif
} BHTTY;
extern BHTTY *bhtty_open(char *__port, int __tmo);
extern void bhtty_close(BHTTY *);
extern int bhtty_flush(BHTTY *);
extern void bhtty_raw(BHTTY *, void *__arg);
extern int bhtty_speed(BHTTY *, long __speed);
extern int bhtty_params(BHTTY *, char __dbit, char __par, char __sbit);
extern int bhtty_sstate(BHTTY *, void *__arg);
extern int bhtty_gstate(BHTTY *, void *__arg);
extern int bhtty_crtscts(BHTTY *, char __yesno);
extern int bhtty_write(BHTTY *, unsigned char);
extern int bhtty_read(BHTTY *, unsigned char *, int);
#endif /*SERIAL_BH_H*/