aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Serpell <daniel.serpell@gmail.com>2019-12-21 22:01:09 -0300
committerDaniel Serpell <daniel.serpell@gmail.com>2019-12-21 22:01:09 -0300
commit5a83c30b56d86aeaa221439bf3ff20628a82f96c (patch)
treec5334bb80d86c89afa34614781f4b58f175c4ff8
parent989b852bfd18b844737f80320a705b8d0c1c9052 (diff)
downloademu2-5a83c30b56d86aeaa221439bf3ff20628a82f96c.tar.gz
Use get*/put* functions, adds "getstr" function.
-rw-r--r--src/dos.c54
-rw-r--r--src/dosnames.c29
-rw-r--r--src/dosnames.h4
-rw-r--r--src/emu.h14
-rw-r--r--src/loader.c25
-rw-r--r--src/timer.c5
6 files changed, 65 insertions, 66 deletions
diff --git a/src/dos.c b/src/dos.c
index 13b46aa..cd12cbd 100644
--- a/src/dos.c
+++ b/src/dos.c
@@ -254,9 +254,7 @@ static void dos_show_fcb()
return;
int addr = cpuGetAddrDS(cpuGetDX());
- char name[12];
- memcpy(name, &memory[addr+1], 11);
-
+ char *name = getstr(addr+1, 11);
debug(debug_dos,"\tFCB:"
"[d=%02x:n=%.8s.%.3s:bn=%04x:rs=%04x:fs=%08x:h=%04x:rn=%02x:ra=%08x]\n",
memory[addr], name, name+8, get16(addr+0x0C), get16(addr+0x0E),
@@ -561,7 +559,7 @@ static void dos_find_next(int first)
put32(dosDTA+0x1A, 0);
}
// Fills dos file name
- memcpy(memory + dosDTA + 0x1E, d->dosname, 13);
+ putmem(dosDTA + 0x1E, d->dosname, 13);
// Next file
p->find_first_ptr++;
cpuClrFlag(cpuFlag_CF);
@@ -608,7 +606,7 @@ static void dos_find_next_fcb(void)
// Fills output FCB at DTA - use extended or normal depending on input
int ofcb = memory[get_ex_fcb()] == 0xFF ? dosDTA + 7 : dosDTA;
int pos = 1;
- for(char *c = d->dosname; *c; c++)
+ for(uint8_t *c = d->dosname; *c; c++)
{
if( *c != '.' )
memory[ofcb+pos++] = *c;
@@ -778,7 +776,7 @@ static int run_emulator(char *file, const char *prgname, char *cmdline, char *en
drv[1] = dos_get_default_drive() + 'A';
setenv(ENV_DEF_DRIVE, drv, 1);
// and CWD
- setenv(ENV_CWD, dos_get_cwd(dos_get_default_drive()), 1);
+ setenv(ENV_CWD, (const char *)dos_get_cwd(dos_get_default_drive()), 1);
// pass open file descriptors to child process
for(unsigned i = 0; i < 3; i++)
if(handles[i])
@@ -1013,12 +1011,12 @@ void int21()
case 0x27: // BLOCK READ FROM FCB
case 0x28: // BLOCK WRITE TO FCB
{
+ dos_show_fcb();
int fcb = get_fcb();
unsigned count = cpuGetCX();
unsigned rsize = get16(0x0E + fcb);
unsigned e = 0;
int target = dosDTA;
- dos_show_fcb();
while( !e && count )
{
@@ -1041,16 +1039,16 @@ void int21()
case 0x29: // PARSE FILENAME TO FCB
{
// TODO: length could be more than 64 bytes!
- uint8_t *fname = getptr(cpuGetAddrDS(cpuGetSI()), 64);
- uint8_t *orig = fname;
+ char *fname = getstr(cpuGetAddrDS(cpuGetSI()), 64);
+ char *orig = fname;
uint8_t *dst = getptr(cpuGetAddrES(cpuGetDI()), 37);
- if(!fname || !dst)
+ if(!dst)
{
- debug(debug_dos, "\tinvalid source / destination\n");
+ debug(debug_dos, "\tinvalid destination\n");
cpuSetAX(cpuGetAX() | 0x00FF);
break;
}
- debug(debug_dos, "\t'%.63s' -> ", fname);
+ debug(debug_dos, "\t'%s' -> ", fname);
if(ax & 1)
// Skip separator
if(*fname && strchr(":;.,=+", *fname))
@@ -1474,9 +1472,9 @@ void int21()
case 0x47: // GET CWD
{
// Note: ignore drive letter in DL
- const char *path = dos_get_cwd(cpuGetDX() & 0xFF);
+ const uint8_t *path = dos_get_cwd(cpuGetDX() & 0xFF);
debug(debug_dos, "\tcwd '%c' = '%s'\n", '@' + (cpuGetDX() & 0xFF), path);
- memcpy(memory + cpuGetAddrDS(cpuGetSI()), path, 64);
+ putmem(cpuGetAddrDS(cpuGetSI()), path, 64);
cpuSetAX(0x0100);
cpuClrFlag(cpuFlag_CF);
break;
@@ -1548,26 +1546,32 @@ void int21()
}
else
cpuClrFlag(cpuFlag_CF);
- free(fname);
}
else if((ax & 0xFF) == 0)
{
- // Get executable file name:
- char prgname[64];
- memcpy(prgname, memory + cpuGetAddrDS(cpuGetDX()), 64);
- prgname[63] = 0;
debug(debug_dos, "\texec: '%s'\n", fname);
+ // Get executable file name:
+ char *prgname = getstr(cpuGetAddrDS(cpuGetDX()), 64);
// Read command line parameters:
int pb = cpuGetAddrES(cpuGetBX());
int cmd_addr = cpuGetAddress(get16(pb + 4), get16(pb + 2));
int clen = memory[cmd_addr];
- char *cmdline = malloc(clen + 1);
- memcpy(cmdline, memory + cmd_addr + 1, clen);
- cmdline[clen] = 0;
+ char *cmdline = getstr(cmd_addr, clen);
debug(debug_dos, "\texec command line: '%s %.*s'\n", fname, clen, cmdline);
char *env = "\0\0";
if(get16(pb) != 0)
- env = (char *)memory + cpuGetAddress(get16(pb), 0);
+ {
+ // Sanitize env
+ int eaddr = cpuGetAddress(get16(pb), 0);
+ while( memory[eaddr] != 0 && eaddr < 0xFFFFF )
+ {
+ while( memory[eaddr] != 0 && eaddr < 0xFFFFF )
+ eaddr ++;
+ eaddr ++;
+ }
+ if( eaddr < 0xFFFFF )
+ env = (char *)(memory + cpuGetAddress(get16(pb), 0));
+ }
if(run_emulator(fname, prgname, cmdline, env))
{
cpuSetAX(5); // access denied
@@ -1575,8 +1579,6 @@ void int21()
}
else
cpuClrFlag(cpuFlag_CF);
- free(cmdline);
- free(fname);
}
else
{
@@ -1584,8 +1586,8 @@ void int21()
fname, ax & 0xFF);
cpuSetFlag(cpuFlag_CF);
cpuSetAX(1);
- free(fname);
}
+ free(fname);
break;
}
case 0x4C: // EXIT
diff --git a/src/dosnames.c b/src/dosnames.c
index d0aac31..de27dcc 100644
--- a/src/dosnames.c
+++ b/src/dosnames.c
@@ -30,7 +30,7 @@ static char dos_valid_char(char c)
}
// Converts the Unix filename "u" to a Dos filename "d".
-static int unix_to_dos(char *d, const char *u)
+static int unix_to_dos(uint8_t *d, const char *u)
{
int dot;
int k;
@@ -64,11 +64,11 @@ static int unix_to_dos(char *d, const char *u)
}
// Search a name in the current directory list
-static int dos_search_name(const struct dos_file_list *dl, const char *name)
+static int dos_search_name(const struct dos_file_list *dl, const uint8_t *name)
{
for(; dl->unixname; dl++)
{
- if(!strcmp(dl->dosname, name))
+ if(!strncmp((const char *)dl->dosname, (const char *)name, 13))
return 1;
}
return 0;
@@ -116,7 +116,7 @@ static int dos_unix_sort(const struct dirent **s1, const struct dirent **s2)
}
// GLOB
-static int dos_glob(const char *n, const char *g)
+static int dos_glob(const uint8_t *n, const char *g)
{
while(*n && *g)
{
@@ -359,7 +359,7 @@ static char *dos_unix_path_rec(const char *upath, const char *dospath, int force
}
// CWD for all drives - 'A' to 'Z'
-static char dos_cwd[26][64];
+static uint8_t dos_cwd[26][64];
static int dos_default_drive = 2; // C:
void dos_set_default_drive(int drive)
@@ -483,7 +483,7 @@ static const char *get_base_path(int drive)
return base;
}
-const char *dos_get_cwd(int drive)
+const uint8_t *dos_get_cwd(int drive)
{
drive = drive?drive-1:dos_default_drive;
return dos_cwd[drive];
@@ -511,18 +511,13 @@ int dos_change_cwd(char *path)
// changes CWD
int dos_change_dir(int addr)
{
- char path[64];
- memcpy(path, &memory[addr], 63);
- path[63] = 0;
- return dos_change_cwd(path);
+ return dos_change_cwd(getstr(addr,63));
}
// Converts a DOS full path to equivalent Unix filename
char *dos_unix_path(int addr, int force)
{
- char path[64];
- memcpy(path, &memory[addr], 63);
- path[63] = 0;
+ char *path = getstr(addr, 63);
debug(debug_dos, "\tconvert dos path '%s'\n", path);
// Check for standard paths:
if( *path && (!strcasecmp(path, "NUL") || !strcasecmp(path+1,":NUL")) )
@@ -540,8 +535,6 @@ char *dos_unix_path(int addr, int force)
// Converts a FCB path to equivalent Unix filename
char *dos_unix_path_fcb(int addr, int force)
{
- char path[64];
- char fcb_name[12];
int opos = 0;
// Copy drive number from the FCB structure:
int drive = memory[addr] & 0xFF;
@@ -550,11 +543,11 @@ char *dos_unix_path_fcb(int addr, int force)
else
drive = drive - 1;
// And copy file name
- memcpy(fcb_name, &memory[addr+1], 11);
- fcb_name[11] = 0;
+ char *fcb_name = getstr(addr+1, 11);
debug(debug_dos, "\tconvert dos fcb name %c:'%s'\n", drive + 'A', fcb_name);
- // Copy current directory
+ // Build complete path, copy current directory and add FCB file name
+ char path[64];
memcpy(path, dos_cwd[drive], 64);
opos = strlen(path);
diff --git a/src/dosnames.h b/src/dosnames.h
index e7181ed..63a5771 100644
--- a/src/dosnames.h
+++ b/src/dosnames.h
@@ -23,7 +23,7 @@ int dos_change_cwd(char *path);
int dos_change_dir(int addr);
// Gets current working directory
-const char *dos_get_cwd(int drive);
+const uint8_t *dos_get_cwd(int drive);
// Sets/gets default drive
void dos_set_default_drive(int drive);
@@ -32,7 +32,7 @@ int dos_get_default_drive(void);
// Struct used as return to dosFindFirstFile
struct dos_file_list
{
- char dosname[13];
+ uint8_t dosname[13];
char *unixname;
};
diff --git a/src/emu.h b/src/emu.h
index c367573..6300082 100644
--- a/src/emu.h
+++ b/src/emu.h
@@ -125,4 +125,18 @@ static inline uint8_t *getptr(uint32_t addr, unsigned size)
return memory + addr;
}
+// Get a copy of CPU memory forcing a nul byte at end.
+// Four static buffers are used, so at most 4 results can be in use.
+static inline char *getstr(uint32_t addr, unsigned size)
+{
+ static int cbuf = 0;
+ static char buf[256][4];
+
+ cbuf = (cbuf + 1) & 3;
+ memset(buf[cbuf], 0, 256);
+ if(size < 255 && addr < 0x100000 && size + addr < 0x100000)
+ memcpy(buf[cbuf], memory + addr, size);
+ return buf[cbuf];
+}
+
#endif // EMU_H
diff --git a/src/loader.c b/src/loader.c
index 9f79baf..172cb7d 100644
--- a/src/loader.c
+++ b/src/loader.c
@@ -20,10 +20,8 @@ static void mcb_new(int mcb, int owner, int size, int last)
if(mcb < 0)
return;
memory[mcb * 16 + 0] = last ? 'Z' : 'M';
- memory[mcb * 16 + 1] = owner & 0xFF;
- memory[mcb * 16 + 2] = owner >> 8;
- memory[mcb * 16 + 3] = size & 0xFF;
- memory[mcb * 16 + 4] = size >> 8;
+ put16(mcb * 16 + 1, owner);
+ put16(mcb * 16 + 3, size);
debug(debug_dos, "\tmcb_new: mcb:$%04X type:%c owner:$%04X size:$%04X\n",
mcb, last ? 'Z' : 'M', owner, size);
}
@@ -32,30 +30,28 @@ static int mcb_size(int mcb)
{
if(mcb < 0)
return 0;
- return memory[mcb * 16 + 3] + 256 * memory[mcb * 16 + 4];
+ return get16(mcb * 16 + 3);
}
static void mcb_set_size(int mcb, int sz)
{
if(mcb < 0)
return;
- memory[mcb * 16 + 3] = sz & 0xFF;
- memory[mcb * 16 + 4] = sz >> 8;
+ put16(mcb * 16 + 3, sz);
}
static int mcb_owner(int mcb)
{
if(mcb < 0 || mcb >= 0x10000)
return 0;
- return memory[mcb * 16 + 1] + 256 * memory[mcb * 16 + 2];
+ return get16(mcb * 16 + 1);
}
static void mcb_set_owner(int mcb, int owner)
{
if(mcb < 0)
return;
- memory[mcb * 16 + 1] = owner & 0xFF;
- memory[mcb * 16 + 2] = owner >> 8;
+ put16(mcb * 16 + 1, owner);
}
static int mcb_ok(int mcb)
@@ -297,8 +293,7 @@ uint16_t create_PSP(const char *cmdline, const char *environment,
// Copy environment:
memcpy(memory + env_seg * 16, environment, env_size);
// Then, a word == 1
- memory[env_seg * 16 + env_size] = 1;
- memory[env_seg * 16 + env_size + 1] = 0;
+ put16(env_seg * 16 + env_size, 1);
// And the program name
if(progname)
{
@@ -401,8 +396,7 @@ int dos_load_exe(FILE *f, uint16_t psp_mcb)
fread(memory + mem, 1, max, f);
// Fill top program address in PSP
- memory[psp_mcb * 16 + 16 + 2] = (psp_mcb + mcb_size(psp_mcb) + 1) & 0xFF;
- memory[psp_mcb * 16 + 16 + 3] = (psp_mcb + mcb_size(psp_mcb) + 1) >> 8;
+ put16(psp_mcb * 16 + 16 + 2, psp_mcb + mcb_size(psp_mcb) + 1);
cpuSetIP(0x100);
cpuSetCS(psp_mcb + 1);
@@ -455,8 +449,7 @@ int dos_load_exe(FILE *f, uint16_t psp_mcb)
exe_sz, g16(buf + 10), g16(buf + 12), mcb_size(psp_mcb));
// Fill top program address in PSP
- memory[psp_mcb * 16 + 16 + 2] = (psp_mcb + mcb_size(psp_mcb) + 1) & 0xFF;
- memory[psp_mcb * 16 + 16 + 3] = (psp_mcb + mcb_size(psp_mcb) + 1) >> 8;
+ put16(psp_mcb * 16 + 16 + 2, psp_mcb + mcb_size(psp_mcb) + 1);
// Seek to start of data and read
fseek(f, head_size, SEEK_SET);
diff --git a/src/timer.c b/src/timer.c
index db8a026..a8a2703 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -24,10 +24,7 @@ void update_timer(void)
bios_timer = cnt % 0x1800B0;
bios_dater = cnt / 0x1800B0;
- memory[0x46C] = bios_timer & 0xFF;
- memory[0x46D] = (bios_timer >> 8) & 0xFF;
- memory[0x46E] = (bios_timer >> 16) & 0xFF;
- memory[0x46F] = (bios_timer >> 24) & 0xFF;
+ put32(0x46C, bios_timer);
memory[0x470] = bios_dater & 0xFF;
}
Un proyecto texto-plano.xyz