Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LIM-EMS support #31

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
CC=cc
CFLAGS=-O3 -flto -Wall -g -Werror=implicit-function-declaration -Werror=int-conversion
CFLAGS=-O3 -flto -Wall -g -Werror=implicit-function-declaration -Werror=int-conversion -DEMS_SUPPORT
LDLIBS=-lm
INSTALL=install
PREFIX=/usr
Expand All @@ -17,6 +17,7 @@ OBJS=\
timer.o\
utils.o\
video.o\
ems.o\


all: obj emu2
Expand All @@ -43,17 +44,19 @@ uninstall:

# Generated with gcc -MM src/*.c
obj/codepage.o: src/codepage.c src/codepage.h src/dbg.h src/env.h
obj/cpu.o: src/cpu.c src/cpu.h src/dbg.h src/dis.h src/emu.h
obj/cpu.o: src/cpu.c src/cpu.h src/dbg.h src/dis.h src/emu.h src/ems.h
obj/dbg.o: src/dbg.c src/dbg.h src/env.h
obj/dis.o: src/dis.c src/dis.h src/emu.h
obj/dis.o: src/dis.c src/dis.h src/emu.h src/ems.h
obj/dos.o: src/dos.c src/codepage.h src/dos.h src/dbg.h src/dosnames.h \
src/emu.h src/env.h src/keyb.h src/loader.h src/timer.h src/utils.h \
src/video.h
obj/dosnames.o: src/dosnames.c src/dbg.h src/dosnames.h src/emu.h src/env.h
src/video.h src/ems.h
obj/dosnames.o: src/dosnames.c src/dbg.h src/dosnames.h src/emu.h src/env.h \
src/ems.h
obj/keyb.o: src/keyb.c src/keyb.h src/dbg.h src/emu.h src/codepage.h
obj/loader.o: src/loader.c src/loader.h src/dbg.h src/emu.h
obj/main.o: src/main.c src/dbg.h src/dos.h src/dosnames.h src/emu.h \
src/keyb.h src/timer.h src/video.h
src/keyb.h src/timer.h src/video.h src/ems.h
obj/timer.o: src/timer.c src/dbg.h src/timer.h src/emu.h
obj/utils.o: src/utils.c src/utils.h src/dbg.h
obj/video.o: src/video.c src/video.h src/dbg.h src/emu.h src/codepage.h
obj/ems.o: src/ems.c src/emu.h src/ems.h
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ The available environment variables are:
"signed" comparison insructions (JLE instead of JBE).
This is needed at least for MASM versions 1.0 and 1.10.

- `EMU2_EMSMEM` Use LIM-EMS 4.0. Set this variable as available pages
between 0 (no use) to 2048 (32MiB).
The default is 0 (no use).

Simple Example
--------------
Expand Down
18 changes: 11 additions & 7 deletions src/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,22 @@ static uint16_t irq_mask; // IRQs pending

static uint8_t GetMemAbsB(uint32_t addr)
{
return memory[addr & 0xFFFFF];
return get8(addr);
}

static uint16_t GetMemAbsW(uint32_t addr)
{
return memory[addr & 0xFFFFF] + 256 * memory[(addr + 1) & 0xFFFFF];
return get16(addr);
}

static void SetMemAbsB(uint32_t addr, uint8_t val)
{
memory[0xFFFFF & addr] = val;
put8(addr, val);
}

static void SetMemAbsW(uint32_t addr, uint16_t x)
static void SetMemAbsW(uint32_t addr, uint16_t val)
{
memory[addr & 0xFFFFF] = x;
memory[(addr + 1) & 0xFFFFF] = x >> 8;
put16(addr, val);
}

static void SetMemB(uint16_t seg, uint16_t off, uint8_t val)
Expand All @@ -56,7 +55,7 @@ static void SetMemB(uint16_t seg, uint16_t off, uint8_t val)

static uint8_t GetMemB(int seg, uint16_t off)
{
return memory[0xFFFFF & (sregs[seg] * 16 + off)];
return GetMemAbsB(sregs[seg] * 16 + off);
}

static void SetMemW(uint16_t seg, uint16_t off, uint16_t val)
Expand Down Expand Up @@ -2636,6 +2635,11 @@ int cpuGetAddrES(uint16_t offset)
return 0xFFFFF & (sregs[ES] * 16 + offset);
}

int cpuGetAddrSS(uint16_t offset)
{
return 0xFFFFF & (sregs[ES] * 16 + offset);
}

uint16_t cpuGetStack(uint16_t disp)
{
return GetMemW(SS, wregs[SP] + disp);
Expand Down
76 changes: 68 additions & 8 deletions src/dos.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "timer.h"
#include "utils.h"
#include "video.h"
#include "ems.h"

#include <errno.h>
#include <fcntl.h>
Expand Down Expand Up @@ -369,6 +370,15 @@ static int dos_rw_record_fcb(int addr, int write, int update, int seq)
pos = rsize * (0xFFFFFF & get32(0x21 + fcb));

uint8_t *buf = getptr(addr, rsize);
#ifdef EMS_SUPPORT
int buf_allocated = 0;
if (in_ems_pageframe2(addr, rsize)) {
buf_allocated = 1;
buf = malloc(rsize);
if (buf && write)
ems_getmem(buf, addr, rsize);
}
#endif
if(!buf || !rsize)
{
debug(debug_dos, "\tbuffer pointer invalid\n");
Expand All @@ -392,16 +402,21 @@ static int dos_rw_record_fcb(int addr, int write, int update, int seq)
if(write && (pos + n > get32(fcb + 0x10)))
put32(fcb + 0x10, pos + n);

for(unsigned i = n; i < rsize; i++)
buf[i] = 0;
#ifdef EMS_SUPPORT
if (buf_allocated) {
if (!write)
ems_putmem(addr, buf, rsize);
free(buf);
}
#endif
if(n == rsize)
return 0; // read/write full record
else if(!n || write)
return 1; // EOF on read, disk full on write
else
{
for(unsigned i = n; i < rsize; i++)
buf[i] = 0;
return 3; // read partial record
}
}

// Converts Unix time_t to DOS time/date
Expand Down Expand Up @@ -1417,7 +1432,16 @@ void int21()
cpuSetAX(6); // invalid handle
break;
}
uint8_t *buf = getptr(cpuGetAddrDS(cpuGetDX()), cpuGetCX());
int len = cpuGetCX();
uint32_t addr = cpuGetAddrDS(cpuGetDX());
uint8_t *buf = getptr(addr, len);
#ifdef EMS_SUPPORT
int buf_allocated = 0;
if (in_ems_pageframe2(addr, len)) {
buf_allocated = 1;
buf = malloc(len);
}
#endif
if(!buf)
{
debug(debug_dos, "\tbuffer pointer invalid\n");
Expand All @@ -1429,14 +1453,20 @@ void int21()
if(devinfo[cpuGetBX()] == 0x80D3)
{
suspend_keyboard();
cpuSetAX(line_input(f, buf, cpuGetCX()));
cpuSetAX(line_input(f, buf, len));
}
else
{
unsigned n = fread(buf, 1, cpuGetCX(), f);
unsigned n = fread(buf, 1, len, f);
cpuSetAX(n);
}
cpuClrFlag(cpuFlag_CF);
#ifdef EMS_SUPPORT
if (buf_allocated) {
ems_putmem(addr, buf, len);
free(buf);
}
#endif
break;
}
case 0x40: // WRITE
Expand All @@ -1449,7 +1479,18 @@ void int21()
return;
}
unsigned len = cpuGetCX();
uint8_t *buf = getptr(cpuGetAddrDS(cpuGetDX()), len);
uint32_t addr = cpuGetAddrDS(cpuGetDX());
uint8_t *buf = getptr(addr, len);
#ifdef EMS_SUPPORT
int buf_allocated = 0;
if (in_ems_pageframe2(addr, len)) {
buf_allocated = 1;
buf = malloc(len);
if (buf) {
ems_getmem(buf, addr, len);
}
}
#endif
if(!buf)
{
debug(debug_dos, "\tbuffer pointer invalid\n");
Expand All @@ -1469,6 +1510,10 @@ void int21()
cpuSetAX(n);
}
cpuClrFlag(cpuFlag_CF);
#ifdef EMS_SUPPORT
if (buf_allocated)
free(buf);
#endif
break;
}
case 0x41: // UNLINK
Expand Down Expand Up @@ -2113,6 +2158,21 @@ void init_dos(int argc, char **argv)
// Patch an INT 21 at address 0x000C0, this is for the CP/M emulation code
memory[0x000C0] = 0xCD;
memory[0x000C1] = 0x21;

#ifdef EMS_SUPPORT
const char *emsmem = getenv(ENV_EMSMEM);
int ems_pages = 0;
if (emsmem != NULL) {
char *ep;
ems_pages = strtol(emsmem, &ep, 0);
if (*ep || ems_pages < 0 || ems_pages > 2048)
print_error("%s must be set between 0 to 2048\n", ENV_EMSMEM);
}
if (ems_pages != 0) {
debug(debug_dos, "set EMS pages = %d\n", ems_pages);
init_ems(ems_pages);
}
#endif

// Init memory handling - available start address at 0x800,
// ending address at 0xA0000.
Expand Down
5 changes: 5 additions & 0 deletions src/dosnames.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,11 @@ char *dos_unix_path(int addr, int force, const char *append)
return strdup("/dev/null");
if(*path && (!strcasecmp(path, "CON") || !strcasecmp(path + 1, ":CON")))
return strdup("/dev/tty");
#ifdef EMS_SUPPORT
if(use_ems && *path && (!strcasecmp(path, "EMMXXXX0") ||
!strcasecmp(path + 1, ":EMMXXXX0")))
return strdup("/dev/null");
#endif
// Try to convert
char *result = dos_unix_path_base(path, force);
// Be done if the path is found, or no append.
Expand Down
Loading