diff options
author | Daniel Serpell <daniel.serpell@gmail.com> | 2019-12-21 22:01:09 -0300 |
---|---|---|
committer | Daniel Serpell <daniel.serpell@gmail.com> | 2019-12-21 22:01:09 -0300 |
commit | 5a83c30b56d86aeaa221439bf3ff20628a82f96c (patch) | |
tree | c5334bb80d86c89afa34614781f4b58f175c4ff8 | |
parent | 989b852bfd18b844737f80320a705b8d0c1c9052 (diff) | |
download | emu2-5a83c30b56d86aeaa221439bf3ff20628a82f96c.tar.gz |
Use get*/put* functions, adds "getstr" function.
-rw-r--r-- | src/dos.c | 54 | ||||
-rw-r--r-- | src/dosnames.c | 29 | ||||
-rw-r--r-- | src/dosnames.h | 4 | ||||
-rw-r--r-- | src/emu.h | 14 | ||||
-rw-r--r-- | src/loader.c | 25 | ||||
-rw-r--r-- | src/timer.c | 5 |
6 files changed, 65 insertions, 66 deletions
@@ -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; }; @@ -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; } |