New upstream version 2.0-0.9
Some checks failed
Build / build (push) Has been cancelled

This commit is contained in:
geos_one
2025-08-14 09:28:49 +02:00
parent c338ff82fb
commit 17bb5d7efa
634 changed files with 19105 additions and 52303 deletions

View File

@@ -12,14 +12,9 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef __linux__
#include <sys/vfs.h>
#else
#include <sys/param.h>
#include <sys/mount.h>
#endif
#include <sys/statvfs.h>
#include "Linux/magic.h"
#include <linux/magic.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
@@ -41,10 +36,8 @@
#include "hma.h"
#include "xms.h"
#include "int.h"
#include "vint.h"
#include "dos2linux.h"
#include "video.h"
#include "clipboard.h"
#include "priv.h"
#include "doshelpers.h"
#include "lowmem.h"
@@ -187,8 +180,13 @@ static void process_master_boot_record(void)
* SS:BP,DS:SI pointing to the boot partition entry within 0:600 MBR
* DI = 0x7dfe
*/
struct on_disk_mbr *mbr = LOWMEM(0x600);
struct on_disk_mbr *bootrec = LOWMEM(0x7c00);
struct mbr {
char code[PART_INFO_START];
struct on_disk_partition partition[4];
unsigned short bootmagic;
} __attribute__ ((packed));
struct mbr *mbr = LOWMEM(0x600);
struct mbr *bootrec = LOWMEM(0x7c00);
int i;
unsigned offs;
@@ -200,7 +198,7 @@ static void process_master_boot_record(void)
}
if (i >= 4) {
/* aiee... no bootflags sets */
error("no bootflag set, Leaving DOS...\n");
p_dos_str("\n\rno bootflag set, Leaving DOS...\n\r");
leavedos(99);
}
LO(dx) = 0x80; /* drive C:, DOS boots only from C: */
@@ -212,13 +210,13 @@ static void process_master_boot_record(void)
LWORD(eax) = 0x0201; /* read one sector */
LWORD(ebx) = 0x7c00; /* target offset, ES is 0 */
do_int_call_back(0x13);
if ((REG(eflags) & CF) || (bootrec->signature != MBR_SIG)) {
if ((REG(eflags) & CF) || (bootrec->bootmagic != 0xaa55)) {
/* error while booting */
error("error on reading bootsector, Leaving DOS...\n");
leavedos(99);
}
offs = 0x600 + offsetof(struct on_disk_mbr, partition) + sizeof(mbr->partition[0]) * i;
offs = 0x600 + offsetof(struct mbr, partition) + sizeof(mbr->partition[0]) * i;
coopth_add_post_handler(mbr_jmp, (void *) (long) offs);
}
@@ -374,7 +372,7 @@ static int dos_helper(int stk_offs, int revect)
LWORD(eax) = DOS_HELPER_MAGIC;
LWORD(ebx) = VERSION_NUM * 0x100 + SUBLEVEL; /* major version 0.49 -> 0049 */
/* The patch level in the form n.n is a float...
* ...we let GCC at compile time translate it to 0xHHLL, HH=major, LL=minor.
* ...we let GCC at compiletime translate it to 0xHHLL, HH=major, LL=minor.
* This way we avoid usage of float instructions.
*/
LWORD(ecx) = REVISION;
@@ -393,7 +391,8 @@ static int dos_helper(int stk_offs, int revect)
break;
case DOS_HELPER_PRINT_STRING: /* PRINT STRING ES:DX */
dbug_printf("DOS to EMU: \"%s\"\n", SEG_ADR((char *), es, dx));
g_printf("DOS likes us to print a string\n");
ds_printf("DOS to EMU: \"%s\"\n", SEG_ADR((char *), es, dx));
break;
case DOS_HELPER_ADJUST_IOPERMS: /* SET IOPERMS: bx=start, cx=range,
@@ -473,10 +472,6 @@ static int dos_helper(int stk_offs, int revect)
p_dos_str("\n");
break;
case DOS_HELPER_PRESTROKES_START:
start_pre_strokes();
break;
case DOS_HELPER_INSERT_INTO_KEYBUFFER:
k_printf
("KBD: WARNING: outdated keyboard helper fn 6 was called!\n");
@@ -511,10 +506,6 @@ static int dos_helper(int stk_offs, int revect)
config.hogthreshold = LWORD(ebx);
break;
case DOS_HELPER_TEST_MODE:
config.test_mode = LO(bx);
return 1;
case DOS_HELPER_MFS_HELPER:
mfs_inte6();
return 1;
@@ -564,7 +555,7 @@ static int dos_helper(int stk_offs, int revect)
case DOS_HELPER_GARROT_HELPER: /* Mouse garrot helper */
if (!LWORD(ebx)) /* Wait sub-function requested */
idle_enable(50, 0, "mouse_garrot");
idle_enable(0, 50, 0, "mouse_garrot");
else { /* Get Hogthreshold value sub-function */
LWORD(ebx) = config.hogthreshold;
LWORD(eax) = config.hogthreshold;
@@ -673,7 +664,10 @@ static int dos_helper(int stk_offs, int revect)
case DOS_HELPER_GET_CPU_SPEED:
{
REG(eax) = 0;
if (config.rdtsc)
REG(eax) = (LLF_US << 16) / config.cpu_spd;
else
REG(eax) = 0;
break;
}
@@ -715,12 +709,10 @@ static int dos_helper(int stk_offs, int revect)
buf == NULL ? 0 : (SEGOFF2LINEAR(_ES, _DX) & 0xffff);
break;
}
case DOS_HELPER_GETPID: {
pid_t pid = getpid();
LWORD(eax) = pid;
LWORD(ebx) = pid >> 16;
case DOS_HELPER_GETPID:
LWORD(eax) = getpid();
LWORD(ebx) = getppid();
break;
}
case DOS_HELPER_CHDIR:
LWORD(eax) = chdir(SEG_ADR((char *), es, dx));
@@ -800,7 +792,7 @@ static int int15(void)
case 0x10: /* TopView/DESQview */
switch (LO(ax)) {
case 0x00:{ /* giveup timeslice */
idle_enable(100, 0, "topview");
idle_enable(0, 100, 0, "topview");
break;
}
}
@@ -895,9 +887,6 @@ static int int15(void)
unsigned src_addr, dst_addr;
unsigned src_limit, dst_limit;
unsigned int length;
void *s, *d;
unsigned int old_a20 = a20;
lp = SEG_ADR((unsigned int *), es, si);
lp += 4;
src_addr = (*lp >> 16) & 0x0000FFFF;
@@ -918,52 +907,19 @@ static int int15(void)
src_addr, dst_addr, length);
if (src_limit < length - 1 || dst_limit < length - 1 ||
src_addr + length > LOWMEM_SIZE + EXTMEM_SIZE ||
dst_addr + length > LOWMEM_SIZE + EXTMEM_SIZE) {
src_addr + length > LOWMEM_SIZE + HMASIZE + EXTMEM_SIZE ||
dst_addr + length > LOWMEM_SIZE + HMASIZE + EXTMEM_SIZE) {
x_printf("block move failed\n");
LWORD(eax) = 0x0200;
CARRY;
break;
}
/* Have to enable a20 before translating addresses */
if (!a20)
set_a20(1);
while (length) {
/* avoid crossing page boundaries */
int s_al = PAGE_ALIGN(src_addr) - src_addr;
int d_al = PAGE_ALIGN(dst_addr) - dst_addr;
int todo;
if (!s_al)
s_al += PAGE_SIZE;
if (!d_al)
d_al += PAGE_SIZE;
todo = _min(s_al, d_al);
todo = _min(todo, length);
x_printf("int 15: copy subblock: src=%#x dst=%#x len=%#x\n",
src_addr, dst_addr, todo);
s = physaddr_to_unixaddr(src_addr);
if (s == MAP_FAILED) {
error("error mapping %x to addr\n", src_addr);
break;
}
d = physaddr_to_unixaddr(dst_addr);
if (d == MAP_FAILED) {
error("error mapping %x to addr\n", dst_addr);
break;
}
e_invalidate_pa(dst_addr, todo);
memcpy(d, s, todo);
src_addr += todo;
dst_addr += todo;
length -= todo;
}
if (old_a20 != a20)
set_a20(old_a20);
if (length) {
LWORD(eax) = 0x0200;
CARRY;
} else {
unsigned int old_a20 = a20;
/* Have to enable a20 before moving */
if (!a20)
set_a20(1);
extmem_copy(dst_addr, src_addr, length);
if (old_a20 != a20)
set_a20(old_a20);
LWORD(eax) = 0;
NOCARRY;
}
@@ -971,7 +927,10 @@ static int int15(void)
}
case 0x88:
LWORD(eax) = EXTMEM_SIZE >> 10;
if (xms_intdrv())
LWORD(eax) = 0;
else
LWORD(eax) = (EXTMEM_SIZE + HMASIZE) >> 10;
NOCARRY;
break;
@@ -1053,7 +1012,7 @@ static int int15(void)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
#endif
if (LO(ax) == 1) {
Bit32u mem = EXTMEM_SIZE >> 10;
Bit32u mem = (EXTMEM_SIZE + HMASIZE) >> 10;
if (mem < 0x3c00) {
LWORD(eax) = mem;
LWORD(ebx) = 0;
@@ -1124,8 +1083,6 @@ static void set_ticks(unsigned long new_ticks)
static int int1a(void)
{
int_yield();
switch (HI(ax)) {
/*
@@ -1149,7 +1106,7 @@ increments AL so we *don't* lose a day if two consecutive midnights pass.
case 0: /* read time counter */
{
int day_rollover;
idle_enable2(50, 50, 0, "int1a:0");
idle(50, 50, 0, "int1a:0");
if (config.timemode == TM_LINUX) {
/* Set BIOS area flags to LINUX time computed values always */
last_ticks = get_linux_ticks(0, &day_rollover);
@@ -1461,7 +1418,7 @@ static int msdos(void)
#endif
case 0x2C:{ /* get time & date */
idle_enable(100, 0, "dos_time");
idle(2, 100, 0, "dos_time");
return 0;
}
@@ -1607,10 +1564,10 @@ static void do_ret_from_int(int inum, const char *pfx)
ssp = SEGOFF2LINEAR(SREG(ss), 0);
sp = LWORD(esp);
_SP += 6;
_IP = popw(ssp, sp);
_CS = popw(ssp, sp);
flgs = popw(ssp, sp);
_SP += 6;
if (flgs & IF)
set_IF();
else
@@ -1721,11 +1678,9 @@ static far_t int##x##_unrevect(uint16_t seg, uint16_t offs) \
return ret; \
int##x##_hooked = 1; \
di_printf("int_rvc: unrevect 0x%s\n", #x); \
if (test_bit(0x##x, &vm86s.int_revectored)) { \
if (!mhp_revectored(0x##x)) \
clear_bit(0x##x, &vm86s.int_revectored); \
else \
mhp_adjust_revectored(0x##x); \
if (is_revectored(0x##x, &vm86s.int_revectored)) { \
assert(!mhp_revectored(0x##x)); \
reset_revectored(0x##x, &vm86s.int_revectored); \
} else { \
di_printf("int_rvc: revectoring of 0x%s was not enabled\n", #x); \
} \
@@ -1740,7 +1695,7 @@ static int int##x##_unrevect_simple(void) \
return 0; \
int##x##_hooked = 1; \
di_printf("int_rvc: unrevect 0x%s\n", #x); \
clear_bit(0x##x, &vm86s.int_revectored); \
reset_revectored(0x##x, &vm86s.int_revectored); \
int##x##_rvc_setup(); \
SETIVEC(0x##x, INT_RVC_SEG, INT_RVC_##x##_OFF); \
return 1; \
@@ -1809,7 +1764,7 @@ static void msdos_xtra(uint16_t old_ax, uint16_t old_flags)
di_printf("int_rvc 0x21 call for ax=0x%04x %x\n", LWORD(eax), old_ax);
CARRY;
switch (HI_BYTE(old_ax)) {
switch (HI_BYTE_d(old_ax)) {
case 0x71:
if (LWORD(eax) != 0x7100)
break;
@@ -1963,10 +1918,8 @@ static int int19(void)
{
int stal;
coopth_leave();
dpmi_done0();
if (clnup_handler)
clnup_handler();
clnup_handler = NULL;
stal = coopth_flush_vm86();
if (stal) {
error("stalled %i threads on reboot\n", stal);
@@ -2070,10 +2023,8 @@ static int redir_printers(void)
/* drive for -K (aka system.com) */
struct drive_syscom {
char *path;
int drv_num;
int mfs_idx;
#define SCUSERS 5
uint8_t *drv_num[SCUSERS];
int num_scusers;
};
static struct drive_syscom syscomdrv;
/* drive for -d */
@@ -2095,18 +2046,14 @@ static int num_x_drives;
#define REDIR_F_GRP 1
void add_syscom_drive(char *path, uint8_t *user)
int *add_syscom_drive(char *path)
{
assert(syscomdrv.num_scusers == 0);
syscomdrv.path = expand_path(path);
syscomdrv.mfs_idx = mfs_define_drive(syscomdrv.path);
syscomdrv.drv_num[0] = user;
}
void add_syscom_user(uint8_t *user)
{
assert(1 + syscomdrv.num_scusers < SCUSERS);
syscomdrv.drv_num[1 + syscomdrv.num_scusers++] = user;
struct drive_syscom *drv = &syscomdrv;
assert(drv->drv_num == 0);
drv->path = expand_path(path);
drv->drv_num = -1;
drv->mfs_idx = mfs_define_drive(drv->path);
return &drv->drv_num;
}
int add_extra_drive(char *path, int ro, int cd, int grp)
@@ -2463,9 +2410,7 @@ static int redir_one_drive(const char *path, int ro, int cdrom, int prm,
int drv = find_free_drive();
if (drv < 0) {
error("no free drives\n");
if (get_lastdrive() < 7)
error("@Set LASTDRIVE=Z in your fdconfig.sys\n");
else if (config.boot_dos == FATFS_FD_D) {
if (config.boot_dos == FATFS_FD_D) {
error("@-d/-K is not supported with this freedos version\n");
leavedos(26);
}
@@ -2475,9 +2420,7 @@ static int redir_one_drive(const char *path, int ro, int cdrom, int prm,
grp ? REDIR_F_GRP : 0);
if (ret != CC_SUCCESS) {
error("INT21: redirecting %s failed (err = %d)\n", path, ret);
if (get_lastdrive() < 7)
error("@Set LASTDRIVE=Z in your fdconfig.sys\n");
else if (config.boot_dos == FATFS_FD_D && (ret == 0x55 /* duplicate redirect */
if (config.boot_dos == FATFS_FD_D && (ret == 0x55 /* duplicate redirect */
|| ret == 0xf /* invalid drive */)) {
error("-d/-K is not supported with this freedos version\n");
leavedos(26);
@@ -2652,15 +2595,13 @@ static void redir_extra_drives(void)
{
int i, ret, drv;
if (syscomdrv.path) {
if (syscomdrv.drv_num != 0) {
drv = redir_one_drive(syscomdrv.path, 0, 0, 1, 0, syscomdrv.mfs_idx);
if (drv < 0) {
leavedos(26);
return;
}
/* notify all users about this drive */
for (i = 0; i < 1 + syscomdrv.num_scusers; i++)
*syscomdrv.drv_num[i] = drv;
syscomdrv.drv_num = drv;
}
for (i = 0; i < num_x_drives; i++) {
@@ -2841,10 +2782,6 @@ void dos_post_boot_reset(void)
if (clnup_handler)
clnup_handler();
clnup_handler = NULL;
syscomdrv.num_scusers = 0;
#ifdef USE_MHPDBG
mhp_reset_hma();
#endif
}
static void dos_post_boot(void)
@@ -2852,9 +2789,6 @@ static void dos_post_boot(void)
if (!post_boot) {
post_boot = 1;
post_boot_unrevect();
/* call vint_setup() again to avoid DOS STACKS hooks, see
* https://github.com/dosemu2/dosemu2/issues/1607 */
vint_setup();
if (config.force_redir) {
if (!redir_state) {
redir_it();
@@ -2863,22 +2797,13 @@ static void dos_post_boot(void)
enable_redirect();
}
}
#ifdef USE_MHPDBG
/*
* Let's set up the hma start address for dosdebug use. There's no
* specific reason it should be here other than it needs to be done
* sometime after DOS has started.
*/
mhp_init_hma();
#endif
start_pre_strokes();
}
}
/* KEYBOARD BUSY LOOP */
static int int28(void)
{
idle_enable(50, 0, "int28");
idle_enable(0, 50, 0, "int28");
return 1;
}
@@ -2938,7 +2863,7 @@ done:
static unsigned short do_get_psp(int parent)
{
/* don't care about parent, as command.com is primary */
/* dont care about parent, as command.com is primary */
return sda_cur_psp(sda);
}
@@ -2957,9 +2882,6 @@ static void do_run_cmd(struct lowstring *str, struct ae00_tab *cmd)
_AL = 0xff;
}
/* size not propagated through DOS API, so we cache it */
static int clipb_size;
static int int2f(int stk_offs, int revect)
{
reset_idle(0);
@@ -3021,16 +2943,14 @@ hint_done:
memcpy(cmdname, str->s, len);
cmdname[len] = 0;
ptr = cmdname + strspn(cmdname, " \t");
if (!ptr[0])
return 0;
tmp_ptr = ptr;
while (*tmp_ptr) { /* Check whether the name is valid */
if (iscntrlDOS(*tmp_ptr++))
return 0;
}
strcpy(title_current, title_hint);
if (!ptr[0]) {
change_window_title(title_current);
return 0;
}
snprintf(appname, sizeof(appname), "%s ( %s )",
title_current, strlowerDOS(ptr));
change_window_title(appname);
@@ -3092,7 +3012,7 @@ hint_done:
break;
case 0x80: /* give up time slice */
idle_enable(100, 0, "int2f_idle_magic");
idle_enable(0, 100, 0, "int2f_idle_magic");
if (config.hogthreshold) {
LO(ax) = 0;
return 1;
@@ -3101,11 +3021,8 @@ hint_done:
case 0x83:
if (dpmi_active() && win3x_mode != INACTIVE) {
LWORD(ebx) = 1; /* W95: number of virtual machine */
return 1;
}
break;
if (dpmi_active() && win3x_mode != INACTIVE)
LWORD(ebx) = 0; /* W95: number of virtual machine */
case 0x81: /* W95: enter critical section */
if (dpmi_active() && win3x_mode != INACTIVE) {
D_printf("WIN: enter critical section\n");
@@ -3141,81 +3058,13 @@ hint_done:
}
break;
case 0x17: /* MS Windows WINOLDAP functions */
switch (LO(ax)) {
case 0x00: /* IDENTIFY WinOldAp VERSION */
LO(ax) = 0x01; // major version
HI(ax) = 0x00; // minor version
v_printf("Check for WinOldAp\n"); // Installed == (AX != 1700)
return 1;
case 0x01: /* OPEN CLIPBOARD */
LWORD(eax) = 1; // success (AX != 0)
v_printf("Open clipboard\n");
return 1;
case 0x02: /* EMPTY CLIPBOARD */
v_printf("Clear clipboard\n");
if (Clipboard && Clipboard->clear)
LWORD(eax) = Clipboard->clear();
else
LWORD(eax) = 0;
return 1;
case 0x03: /* WRITE CLIPBOARD */
v_printf("Write clipboard\n");
if (Clipboard && Clipboard->write) {
char *pbuf = MK_FP32(SREG(es), LWORD(ebx));
unsigned int bsize = LWORD(esi) << 16 | LWORD(ecx);
LWORD(eax) = Clipboard->write(LWORD(edx), pbuf, bsize);
} else
LWORD(eax) = 0;
return 1;
case 0x04: /* GET CLIPBOARD DATA SIZE */
v_printf("Get clipboard size\n");
if (Clipboard && Clipboard->getsize) {
clipb_size = Clipboard->getsize(LWORD(edx));
LWORD(edx) = (clipb_size >> 16);
LWORD(eax) = (clipb_size & 0xffff);
} else {
LWORD(edx) = LWORD(eax) = 0;
}
return 1;
case 0x05: /* GET CLIPBOARD DATA */
v_printf("Get clipboard data\n");
if (Clipboard && Clipboard->getdata) {
char *pbuf = MK_FP32(SREG(es), LWORD(ebx));
LWORD(eax) = Clipboard->getdata(LWORD(edx), pbuf,
clipb_size);
} else
LWORD(eax) = 0;
return 1;
case 0x08: /* CLOSE CLIPBOARD */
LWORD(eax) = 1; // success (AX != 0)
v_printf("Close clipboard\n");
return 1;
case 0x09: /* COMPACT CLIPBOARD */
// SI:CX = desired size in bytes
// DX:AX = number of bytes in largest block of free memory
LWORD(edx) = 0;
LWORD(eax) = 0x1000; // 4K should indicate enough room
v_printf("Compact clipboard\n");
return 1;
case 0x0a: /* GET DEVICE CAPABILITIES */
LWORD(eax) = 0; // Not sure if we should "support" this
// function, but doesn't seem possible to
// indicate otherwise.
v_printf("Get device capabilities (0x%02x)\n", LWORD(edx));
return 1;
default:
v_printf("BAD WinOldAp func int 2f/ax=0x%04x\n", LWORD(eax));
}
break;
case INT2F_XMS_MAGIC:
if (!xms_intdrv())
break;
switch (LO(ax)) {
case 0: /* check for XMS */
x_printf("Check for XMS\n");
LWORD(eax) = xms_install_check();
LO(ax) = 0x80;
break;
case 0x10:
x_printf("Get XMSControl address\n");
@@ -3413,7 +3262,7 @@ void do_int(int i)
}
#endif
if (test_bit(i, &vm86s.int_revectored) && !mhp_revectored(i)) {
if (is_revectored(i, &vm86s.int_revectored) && !mhp_revectored(i)) {
assert(int_handlers[i].interrupt_function[REVECT]);
if (debug_level('#') > 2)
debug_int("Do rvc", i);
@@ -3526,10 +3375,10 @@ void fake_iret(void)
ssp = SEGOFF2LINEAR(SREG(ss), 0);
sp = LWORD(esp);
_SP += 6;
_IP = popw(ssp, sp);
_CS = popw(ssp, sp);
set_FLAGS(popw(ssp, sp));
_SP += 6;
#ifdef USE_MHPDBG
if (mhpdbg.active && old_tf)
set_TF();
@@ -3548,12 +3397,6 @@ void do_eoi2_iret(void)
_IP = EOI2_OFF;
}
void do_iret(void)
{
_CS = BIOSSEG;
_IP = IRET_OFF;
}
static void rvc_int_pre(int tid, void *arg, void *arg2)
{
coopth_push_user_data(tid, (void *) (long) get_FLAGS(REG(eflags)));
@@ -3592,14 +3435,6 @@ static int _int##n##_(int stk_offs, int revect) \
return int##n(); \
}
/* Needed for int16, which can clash with type name.
* Under clang, both _int16 and __int16 are also occupied. */
#define INT_WRP2(n) \
static int _int##n##_(int stk_offs, int revect) \
{ \
return ___int##n(); \
}
INT_WRP(05)
INT_WRP(10)
INT_WRP(11)
@@ -3607,7 +3442,7 @@ INT_WRP(12)
INT_WRP(13)
INT_WRP(14)
INT_WRP(15)
INT_WRP2(16)
INT_WRP(16)
INT_WRP(17)
INT_WRP(18)
INT_WRP(19)
@@ -3635,7 +3470,7 @@ static void revect_setup(void)
if (config.force_revect != 0) {
for (i = 0; i < 0x100; i++) {
if (int_handlers[i].interrupt_function[REVECT])
set_bit(i, &vm86s.int_revectored);
set_revectored(i, &vm86s.int_revectored);
}
}
@@ -3736,15 +3571,10 @@ void setup_interrupts(void)
void int_try_disable_revect(void)
{
int i;
if (config.force_revect != -1)
return;
config.force_revect = 0;
for (i = 0; i < 256; i++) {
if (test_bit(i, &vm86s.int_revectored) && !mhp_revectored(i))
clear_bit(i, &vm86s.int_revectored);
}
memset(&vm86s.int_revectored, 0x00, sizeof(vm86s.int_revectored));
}
void update_xtitle(void)
@@ -3893,7 +3723,7 @@ far_t get_int_vector(int vec)
{
far_t addr;
if (test_bit(vec, &vm86s.int_revectored)) {
if (is_revectored(vec, &vm86s.int_revectored)) {
addr.segment = INT_RVC_SEG;
switch (vec) {
case 0x21: