Skip to content

Commit

Permalink
Added A20 line support.
Browse files Browse the repository at this point in the history
  • Loading branch information
andreas-jonsson committed Oct 11, 2024
1 parent 1dd6bfc commit ef82cdf
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 23 deletions.
12 changes: 8 additions & 4 deletions front/sdl/docopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,15 @@ int elems_to_args(struct Elements *elements, struct DocoptArgs *args,
for (i = 0; i < elements->n_options; i++) {
option = &elements->options[i];
if (help && option->value && strcmp(option->olong, "--help") == 0) {
for (j = 0; j < 19; j++)
for (j = 0; j < 20; j++)
puts(args->help_message[j]);
return EXIT_FAILURE;
} else if (version && option->value &&
strcmp(option->olong, "--version") == 0) {
puts(version);
return EXIT_FAILURE;
} else if (strcmp(option->olong, "--a20") == 0) {
args->a20 = option->value;
} else if (strcmp(option->olong, "--clean") == 0) {
args->clean = option->value;
} else if (strcmp(option->olong, "--edit") == 0) {
Expand Down Expand Up @@ -299,8 +301,8 @@ int elems_to_args(struct Elements *elements, struct DocoptArgs *args,

struct DocoptArgs docopt(int argc, char *argv[], const bool help, const char *version) {
struct DocoptArgs args = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, (char *) "10.0", NULL, NULL,
NULL,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, (char *) "10.0", NULL,
NULL, NULL,
usage_pattern,
{ "Usage: virtualxt [options]",
"",
Expand All @@ -310,6 +312,7 @@ struct DocoptArgs docopt(int argc, char *argv[], const bool help, const char *ve
" --hdboot Prefer booting from harddrive.",
" --halt Debug break on startup.",
" --mute Disable audio.",
" --a20 Enable support for A20 line.",
" --no-activity Disable disk activity indicator.",
" --no-idle Disable CPU idle on INT28.",
" --clean Remove config file and write a new default one.",
Expand All @@ -327,6 +330,7 @@ struct DocoptArgs docopt(int argc, char *argv[], const bool help, const char *ve
struct Argument arguments[] = {NULL
};
struct Option options[] = {
{NULL, "--a20", 0, 0, NULL},
{NULL, "--clean", 0, 0, NULL},
{NULL, "--edit", 0, 0, NULL},
{NULL, "--halt", 0, 0, NULL},
Expand All @@ -349,7 +353,7 @@ struct DocoptArgs docopt(int argc, char *argv[], const bool help, const char *ve

elements.n_commands = 0;
elements.n_arguments = 0;
elements.n_options = 16;
elements.n_options = 17;
elements.commands = commands;
elements.arguments = arguments;
elements.options = options;
Expand Down
3 changes: 2 additions & 1 deletion front/sdl/docopt.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ typedef size_t bool;
struct DocoptArgs {

/* options without arguments */
size_t a20;
size_t clean;
size_t edit;
size_t halt;
Expand All @@ -101,7 +102,7 @@ struct DocoptArgs {
char *trace;
/* special */
const char *usage_pattern;
const char *help_message[19];
const char *help_message[20];
};

struct DocoptArgs docopt(int, char *[], bool, const char *);
Expand Down
8 changes: 8 additions & 0 deletions front/sdl/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@ static int load_config(void *user, const char *section, const char *name, const
args.hdboot |= atoi(value);
else if (!strcmp("halt", name))
args.halt |= atoi(value);
else if (!strcmp("a20", name))
args.a20 |= atoi(value);
else if (!strcmp("mute", name))
args.mute |= atoi(value);
else if (!strcmp("no-activity", name))
Expand Down Expand Up @@ -745,6 +747,7 @@ static bool write_default_config(const char *path, bool clean) {
"\n[args]\n"
";halt=1\n"
";hdboot=1\n"
";a20=1\n"
";harddrive=boot/freedos_hd.img\n"
"\n[ch36x_isa]\n"
"port=0x201\n"
Expand Down Expand Up @@ -947,6 +950,11 @@ int main(int argc, char *argv[]) {
else
vxt_system_configure(vxt, "rifs", "readonly", "1");
#endif

#ifdef VXTU_MODULE_CHIPSET
if (args.a20)
vxt_system_configure(vxt, "args", "a20", "1");
#endif

#ifdef VXTU_MODULE_GDB
if (args.halt)
Expand Down
1 change: 1 addition & 0 deletions front/sdl/virtualxt.docopt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Options:
--hdboot Prefer booting from harddrive.
--halt Debug break on startup.
--mute Disable audio.
--a20 Enable support for A20 line.
--no-activity Disable disk activity indicator.
--no-idle Disable CPU idle on INT28.
--clean Remove config file and write a new default one.
Expand Down
7 changes: 4 additions & 3 deletions lib/vxt/include/vxt/vxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ extern "C" {
#define VXT_API
#endif

#define VXT_POINTER(s, o) ( (((((vxt_pointer)(vxt_word)(s)) << 4) + (vxt_pointer)(vxt_word)(o))) & 0xFFFFF )
#define VXT_INVALID_POINTER ((vxt_pointer)0xFFFFFFFF)
#define VXT_INVALID_TIMER_ID ((vxt_timer_id)-1)
#define VXT_POINTER(s, o) ( ((((vxt_pointer)(vxt_word)(s)) << 4) + (vxt_pointer)(vxt_word)(o)) & 0xFFFFFF )
#define VXT_INVALID_POINTER ( (vxt_pointer)0xFFFFFFFF )
#define VXT_INVALID_TIMER_ID ( (vxt_timer_id)-1 )

#define _VXT_ERROR_CODES(x) \
x(0, VXT_NO_ERROR, "no error") \
Expand Down Expand Up @@ -335,6 +335,7 @@ VXT_API struct vxt_registers *vxt_system_registers(vxt_system *s);

VXT_API int vxt_system_frequency(vxt_system *s);
VXT_API void vxt_system_set_frequency(vxt_system *s, int freq);
VXT_API void vxt_system_set_a20(vxt_system *s, bool enable);
VXT_API void vxt_system_set_tracer(vxt_system *s, void (*tracer)(vxt_system*,vxt_pointer,vxt_byte));
VXT_API void vxt_system_set_validator(vxt_system *s, const struct vxt_validator *intrf);
VXT_API void vxt_system_set_userdata(vxt_system *s, void *data);
Expand Down
41 changes: 33 additions & 8 deletions lib/vxt/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ VXT_API struct vxt_peripheral *vxt_allocate_peripheral(vxt_allocator *alloc, siz

VXT_API void vxt_system_reset(CONSTP(vxt_system) s) {
cpu_reset(&s->cpu);
s->a20 = false;

for (int i = 0; i < s->num_devices; i++) {
CONSTSP(vxt_peripheral) d = s->devices[i];
if (d->reset)
Expand Down Expand Up @@ -312,6 +314,10 @@ VXT_API void vxt_system_set_frequency(CONSTP(vxt_system) s, int freq) {
s->frequency = freq;
}

VXT_API void vxt_system_set_a20(CONSTP(vxt_system) s, bool enable) {
s->a20 = enable;
}

VXT_API void vxt_system_install_monitor(CONSTP(vxt_system) s, struct vxt_peripheral *dev, const char *name, void *reg, enum vxt_monitor_flag flags) {
if (s->num_monitors < VXT_MAX_MONITORS)
s->monitors[s->num_monitors++] = (struct vxt_monitor){ dev ? vxt_peripheral_name(dev) : "CPU", name, reg, flags };
Expand Down Expand Up @@ -357,25 +363,44 @@ VXT_API void vxt_system_install_io(CONSTP(vxt_system) s, struct vxt_peripheral *

VXT_API void vxt_system_install_mem(CONSTP(vxt_system) s, struct vxt_peripheral *dev, vxt_pointer from, vxt_pointer to) {
VERIFY_PERIPHERAL(dev,);
if ((from | to) & ~0xFFFFF)
VXT_LOG("ERROR: Trying to register memory above 1MB!");

if ((from | (to + 1)) & 0xF)
VXT_LOG("ERROR: Trying to register unaligned address!");

from = (from >> 4) & 0xFFFF;
to = (to >> 4) & 0xFFFF;
from = from >> 4;
to = to >> 4;
while (from <= to)
s->mem_map[from++] = ((struct peripheral*)dev)->idx;
}

VXT_API vxt_byte vxt_system_read_byte(CONSTP(vxt_system) s, vxt_pointer addr) {
addr &= 0xFFFFF;
CONSTSP(vxt_peripheral) dev = s->devices[s->mem_map[addr >> 4]];
return dev->io.read(vxt_peripheral_device(dev), addr);
if (!s->a20)
addr &= 0xEFFFFF;

if (addr >= 0x100000) {
addr -= 0x100000;
return (addr >= UMA_SIZE) ? 0xFF : s->ext_mem[addr];
}

CONSTSP(vxt_peripheral) dev = s->devices[s->mem_map[addr >> 4]];
return dev->io.read(vxt_peripheral_device(dev), addr);
}

VXT_API void vxt_system_write_byte(CONSTP(vxt_system) s, vxt_pointer addr, vxt_byte data) {
addr &= 0xFFFFF;
CONSTSP(vxt_peripheral) dev = s->devices[s->mem_map[addr >> 4]];
dev->io.write(vxt_peripheral_device(dev), addr, data);
if (!s->a20)
addr &= 0xEFFFFF;

if (addr >= 0x100000) {
addr -= 0x100000;
if (addr < UMA_SIZE)
s->ext_mem[addr] = data;
return;
}

CONSTSP(vxt_peripheral) dev = s->devices[s->mem_map[addr >> 4]];
dev->io.write(vxt_peripheral_device(dev), addr, data);
}

vxt_byte system_in(CONSTP(vxt_system) s, vxt_word port) {
Expand Down
3 changes: 3 additions & 0 deletions lib/vxt/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#define MAX_TIMERS 256
#define INT64 long long
#define UMA_SIZE (0x10000 - 16)
#define PERIPHERAL_SIGNATURE 0xFAF129C3

#define VERIFY_PERIPHERAL(p, r) \
Expand Down Expand Up @@ -60,10 +61,12 @@ struct system {

vxt_byte io_map[VXT_IO_MAP_SIZE];
vxt_byte mem_map[VXT_MEM_MAP_SIZE];
vxt_byte ext_mem[UMA_SIZE];

vxt_allocator *alloc;
struct cpu cpu;
int frequency;
bool a20;

int num_timers;
struct timer timers[MAX_TIMERS];
Expand Down
80 changes: 80 additions & 0 deletions modules/chipset/a20.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright (c) 2019-2024 Andreas T Jonsson <mail@andreasjonsson.se>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software in
// a product, an acknowledgment (see the following) in the product
// documentation is required.
//
// This product make use of the VirtualXT software emulator.
// Visit https://virtualxt.org for more information.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.

#include <vxt/vxtu.h>

struct a20 {
bool available;
vxt_byte port_92;
};

static vxt_byte in(struct a20 *c, vxt_word port) {
(void)port;
return c->port_92;
}

static void out(struct a20 *c, vxt_word port, vxt_byte data) {
(void)port;
bool enable_a20 = (data & 2) != 0;
if ((c->port_92 & 2) != (data & 2))
VXT_LOG(enable_a20 ? "Enable Fast-A20 line!" : "Disable Fast-A20 line!");

vxt_system_set_a20(VXT_GET_SYSTEM(c), enable_a20);
c->port_92 = data;
}

static vxt_error config(struct a20 *c, const char *section, const char *key, const char *value) {
if (!strcmp(section, "args") && !strcmp(key, "a20"))
c->available = atoi(value) != 0;
return VXT_NO_ERROR;
}

static vxt_error install(struct a20 *c, vxt_system *s) {
if (c->available)
vxt_system_install_io_at(s, VXT_GET_PERIPHERAL(c), 0x92);
return VXT_NO_ERROR;
}

static vxt_error reset(struct a20 *c) {
c->port_92 = 0;
return VXT_NO_ERROR;
}

static const char *name(struct a20 *c) {
(void)c; return "Fast-A20";
}

struct vxt_peripheral *a20_create(vxt_allocator *alloc, void *frontend, const char *args) {
(void)frontend; (void)args;

struct VXT_PERIPHERAL(struct a20) *p;
*(void**)&p = (void*)vxt_allocate_peripheral(alloc, sizeof(struct a20));

p->install = &install;
p->config = &config;
p->reset = &reset;
p->name = &name;
p->io.in = &in;
p->io.out = &out;
return (struct vxt_peripheral*)p;
}
5 changes: 4 additions & 1 deletion modules/chipset/chipset.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ struct vxt_peripheral *kbc_create(vxt_allocator *alloc);
bool kbc_key_event(struct vxt_peripheral *p, enum vxtu_scancode key, bool force);
vxt_int16 kbc_generate_sample(struct vxt_peripheral *p, int freq);

// Fast-A20 switch
struct vxt_peripheral *a20_create(vxt_allocator *alloc, void *frontend, const char *args);

static struct vxt_peripheral *pic_create(vxt_allocator *alloc, void *frontend, const char *args) {
(void)frontend; (void)args;
return vxtu_pic_create(alloc);
Expand Down Expand Up @@ -109,4 +112,4 @@ static struct vxt_peripheral *ppi_kbc_create(vxt_allocator *alloc, void *fronten
return p;
}

VXTU_MODULE_ENTRIES(&pic_create, &dma_create, &pit_create, &ppi_kbc_create)
VXTU_MODULE_ENTRIES(&pic_create, &dma_create, &pit_create, &ppi_kbc_create, &a20_create)
3 changes: 2 additions & 1 deletion modules/chipset/premake5.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
files {
"chipset.c",
"kbc.c"
"kbc.c",
"a20.c"
}
4 changes: 0 additions & 4 deletions modules/gdb/gdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,15 +357,11 @@ int gdb_sys_putchar(struct gdb_state *state, int ch) {
}

int gdb_sys_mem_readb(struct gdb_state *state, address addr, char *val) {
if (addr > 0xFFFFF)
return GDB_EOF;
*val = (char)vxt_system_read_byte(state->sys, addr);
return 0;
}

int gdb_sys_mem_writeb(struct gdb_state *state, address addr, char val) {
if (addr > 0xFFFFF)
return GDB_EOF;
vxt_system_write_byte(state->sys, addr, (vxt_byte)val);
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion tools/docopt/docopt_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
#include <sys/limits.h>
#elif defined(__FreeBSD__) || defined(__NetBSD__) \
#elif defined(__NetBSD__) \
|| defined(__OpenBSD__) || defined(__bsdi__) \
|| defined(__DragonFly__) || defined(macintosh) \
|| defined(__APPLE__) || defined(__APPLE_CC__)
Expand Down

0 comments on commit ef82cdf

Please sign in to comment.