From 8e8fcd1628849b2afb946bcaf81a2e8c1ba1203f Mon Sep 17 00:00:00 2001 From: "E. C. Masloch" Date: Sun, 19 May 2024 23:22:42 +0200 Subject: [PATCH] sys: fix, work on DOS versions that clobber di in int 25h/26h Running on DR-DOS v7.03, the int 25h call zeroes di leading to a crash here when di is expected to preserve the stack pointer. So push di twice and pop it twice. The second pop always gets the saved sp, regardless of whether int 21h or int 25h/26h are used. Refer to https://github.com/SvarDOS/edrdos/issues/57#issuecomment-2119360035 --- sys/sys.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/sys.c b/sys/sys.c index 5ad0b48..ca2a0d2 100644 --- a/sys/sys.c +++ b/sys/sys.c @@ -122,7 +122,12 @@ int int86(int ivec, union REGS *in, union REGS *out) { /* must save sp for int25/26 */ asm("mov %5, (1f+1); jmp 0f; 0:push %%ds; mov %%di, %%dx; mov %%sp, %%di;" - "1:int $0x00; mov %%di, %%sp; pop %%ds; sbb %0, %0" : + "push %%di; push %%di;" + /* push twice to work both for int 25h/26h and int 21h */ + "1:int $0x00; pop %%di; pop %%di;" + /* second pop always reads the correct SP value. + the first pop may read the FL left on stack. */ + "mov %%di, %%sp; pop %%ds; sbb %0, %0" : "=r"(out->x.cflag), "=a"(out->x.ax), "=b"(out->x.bx), "=c"(out->x.cx), "=d"(out->x.dx) : "q"((unsigned char)ivec), "a"(in->x.ax), "b"(in->x.bx),