diff --git a/app/src/main/assets/armeabi-v7a/pdos_new.exe b/app/src/main/assets/armeabi-v7a/pdos_new.exe new file mode 100644 index 0000000..c08c8f3 Binary files /dev/null and b/app/src/main/assets/armeabi-v7a/pdos_new.exe differ diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt index 21950c7..f4a3cf1 100644 --- a/app/src/main/cpp/CMakeLists.txt +++ b/app/src/main/cpp/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.18.1) project("pdos_pdandro") if (${ANDROID_ABI} STREQUAL "armeabi-v7a" OR ${ANDROID_ABI} STREQUAL "x86") -#if (${ANDROID_ABI} STREQUAL "armeabi-v7a") +#if (${ANDROID_ABI} STREQUAL "x86") add_subdirectory(${CMAKE_SOURCE_DIR}/pdpclib/${ANDROID_ABI}) add_subdirectory(${CMAKE_SOURCE_DIR}/bios/${ANDROID_ABI}) #add_subdirectory(${CMAKE_SOURCE_DIR}/pcomm/${ANDROID_ABI}) diff --git a/app/src/main/cpp/bios/armeabi-v7a/bios.c b/app/src/main/cpp/bios/armeabi-v7a/bios.c index 8bd97dc..68381dc 100644 --- a/app/src/main/cpp/bios/armeabi-v7a/bios.c +++ b/app/src/main/cpp/bios/armeabi-v7a/bios.c @@ -1,454 +1,459 @@ -/*********************************************************************/ -/* */ -/* This Program Written by Paul Edwards. */ -/* Released to the Public Domain */ -/* */ -/*********************************************************************/ -/*********************************************************************/ -/* */ -/* bios - generic BIOS that exports the C library */ -/* */ -/*********************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "__os.h" -#include "exeload.h" - -extern int __genstart; -extern int (*__genmain)(int argc, char **argv); - -/* A BIOS is meant to be machine-specific, so this is not a big deal */ -#if 1 -#define PATH "" -/* #define PATH "./" */ -#else -#define PATH "/storage/emulated/0/Download/" -#endif - -#define MEMAMT 24*1000*1000 - -#if defined(__gnu_linux__) || defined(__ARM__) -extern int __start(int argc, char **argv); -#else -extern int __start(char *p); -#endif - -int their_start(char *parm); - -#ifndef __SUBC__ -static int getmainargs(int *_Argc, - char ***_Argv); -#endif - -void *PosGetDTA(void); - -#if defined(__gnu_linux__) || defined(__ARM__) -#include - -static int dirfile; - -static DTA origdta; - -int PosFindFirst(char *pat, int attrib); -int PosFindNext(void); -#endif - -static OS bios = { their_start, 0, 0, NULL, NULL, printf, 0, malloc, NULL, NULL, - fopen, fseek, fread, fclose, fwrite, fgets, strchr, - strcmp, strncmp, strcpy, strlen, fgetc, fputc, - fflush, setvbuf, - PosGetDTA, -#if defined(__gnu_linux__) || defined(__ARM__) - PosFindFirst, PosFindNext, -#else - 0, 0, -#endif - 0, 0, - ctime, time, -#if defined(__gnu_linux__) || defined(__ARM__) - PosChangeDir, PosMakeDir, PosRemoveDir, -#else - 0, 0, 0, -#endif - remove, - memcpy, strncpy, strcat, 0 /* stderr */, free, abort, memset, fputs, fprintf, - getenv, memmove, exit, memcmp, _errno, tmpnam, vfprintf, ungetc, vsprintf, - sprintf, signal, raise, calloc, realloc, atoi, strtol, strtoul, qsort, - bsearch, localtime, clock, strerror, strrchr, strstr, strpbrk, strspn, - strcspn, memchr, ftell, abs, setlocale, perror, rewind, strncat, sscanf, - isalnum, isxdigit, rename, clearerr, _assert, atof, -}; - -static char buf[400]; -static char cmd[300]; - -static int (*genstart)(OS *bios); - -int main(int argc, char **argv) -{ - unsigned char *p; - unsigned char *entry_point; - int rc; - char *prog_name; - int need_usage = 0; - int valid = 0; - int shell = 0; - FILE *scr = NULL; - int quiet = 0; - - bios.mem_amt = MEMAMT; - bios.Xstdin = stdin; - bios.Xstdout = stdout; - bios.Xstderr = stderr; - __genstart = 1; - bios.main = &__genmain; - - /* parameters override everything */ - if (argc > 1) - { - if (strcmp(argv[1], "-quiet") == 0) - { - quiet = 1; - argc--; - argv++; - } - if (argc > 1) - { - if (strcmp(argv[1], "-shell") == 0) - { - shell = 1; - argc--; - argv++; - } - } - if (argc > 1) - { - if (strcmp(argv[1], "-quiet") == 0) - { - quiet = 1; - argc--; - argv++; - } - } - /* if they've typed in --help or anything, give them usage */ - if (argv[1][0] == '-') - { - need_usage = 1; - } - else if (argc == 2) - { - bios.prog_name = argv[1]; - bios.prog_parm = ""; - valid = 1; - } - else if (argc == 3) - { - bios.prog_name = argv[1]; - bios.prog_parm = argv[2]; - valid = 1; - } - else - { - need_usage = 1; - } - } - if (!quiet && !need_usage) - { - printf("bios starting\n"); - } - if (!valid && !need_usage) - { - /* an individual command(s) overrides a shell */ - scr = fopen("biosauto.cmd", "r"); - if (scr != NULL) - { - valid = 1; - } - else - { - scr = fopen("biosauto.shl", "r"); - if (scr != NULL) - { - valid = 1; - shell = 1; - } - } - } - if (!valid && !need_usage) - { - scr = stdin; - printf("enter commands, press enter to exit\n"); - } - do - { - if (need_usage) break; /* should put this before do */ - if (scr != NULL) - { - if (fgets(buf, sizeof buf, scr) == NULL) - { - break; - } - p = strchr(buf, '\n'); - if (p != NULL) - { - *p = '\0'; - } - if (buf[0] == '\0') - { - if (scr == stdin) - { - break; - } - continue; - } - if (buf[0] == '#') - { - continue; - } - bios.prog_name = buf; - p = strchr(buf, ' '); - if (p != NULL) - { - *p = '\0'; - bios.prog_parm = p + 1; - } - else - { - bios.prog_parm = ""; - } - } - - p = calloc(1, 5000000); - if (p == NULL) - { - printf("insufficient memory\n"); - return (EXIT_FAILURE); - } - if (exeloadDoload(&entry_point, bios.prog_name, &p) != 0) - { - printf("failed to load executable\n"); - return (EXIT_FAILURE); - } - genstart = (void *)entry_point; - /* printf("first byte of code is %02X\n", *(unsigned char *)entry_point); */ - -#ifdef NEED_DELAY - for (rc = 0; rc < 3; rc++) - { - printf("please accept a delay before we execute program " - "in BSS memory\n"); - } -#endif - -#if 1 - rc = genstart(&bios); -#else - rc = 0; -#endif - if (!quiet) - { - printf("return from called program is %d\n", rc); - } - free(p); - - if (scr == NULL) - { - break; - } - } while (1); - - if (need_usage) - { - printf("usage: bios [options] [single parm]\n"); - printf("allows execution of non-standard executables\n"); - printf("if no parameters are given and biosauto.cmd is given,\n"); - printf("commands are read, executed and there will be a pause\n"); - printf("otherwise, biosauto.shl is looked for, and there will be\n"); - printf("no pause, because it is assumed to be a shell\n"); - printf("valid options are -quiet and -shell\n"); - printf("e.g. bios -shell pdos.exe uc8086.vhd\n"); - printf("e.g. bios pcomm.exe\n"); - return (EXIT_FAILURE); - } - if (scr == stdin) - { - /* pause has already been done, effectively */ - } - else if (!shell) - { - printf("press enter to exit\n"); - fgets(buf, sizeof buf, stdin); - } - if ((scr != NULL) && (scr != stdin)) - { - fclose(scr); - } - if (!quiet) - { - printf("bios exiting\n"); - } - return (0); -} - -int their_start(char *parm) -{ -#if defined(__gnu_linux__) || defined(__ARM__) - int argc; - char **argv; - getmainargs(&argc, &argv); - __start(argc, argv); -#else - __start(parm); -#endif -} - - -#define MAXPARMS 50 - -#ifndef __SUBC__ -static int getmainargs(int *_Argc, - char ***_Argv) -{ - char *p; - int x; - int argc; - static char *argv[MAXPARMS + 1]; - static char *env[] = {NULL}; - - p = cmd; - - argv[0] = p; - p = strchr(p, ' '); - if (p == NULL) - { - p = ""; - } - else - { - *p = '\0'; - p++; - } - - while (*p == ' ') - { - p++; - } - if (*p == '\0') - { - argv[1] = NULL; - argc = 1; - } - else - { - for (x = 1; x < MAXPARMS; ) - { - char srch = ' '; - - if (*p == '"') - { - p++; - srch = '"'; - } - argv[x] = p; - x++; - p = strchr(p, srch); - if (p == NULL) - { - break; - } - else - { - *p = '\0'; - p++; - while (*p == ' ') p++; - if (*p == '\0') break; /* strip trailing blanks */ - } - } - argv[x] = NULL; - argc = x; - } - - *_Argc = argc; - *_Argv = argv; - return (0); -} -#endif - -#if defined(__gnu_linux__) || defined(__ARM__) - -void *PosGetDTA(void) -{ - return (&origdta); -} - -static int ff_search(void) -{ - static unsigned char buf[500]; - static size_t upto = 0; - static size_t avail = 0; - - if (avail <= 0) - { - avail = __getdents(dirfile, buf, 500); - if (avail <= 0) - { - __close(dirfile); - return (1); - } - } - strncpy(origdta.file_name, buf + upto + 10, sizeof origdta.file_name); - origdta.file_name[sizeof origdta.file_name - 1] = '\0'; - strncpy(origdta.lfn, buf + upto + 10, sizeof origdta.lfn); - origdta.lfn[sizeof origdta.lfn - 1] = '\0'; - upto += *(short *)(buf + upto + 8); - if (upto >= avail) - { - upto = avail = 0; - } - return (0); -} - -int PosFindFirst(char *pat, int attrib) -{ - dirfile = __open(".", 0, 0); - if (dirfile < 0) return (1); - return (ff_search()); -} - -int PosFindNext(void) -{ - return (ff_search()); -} - -int PosChangeDir(const char *to) -{ - return (__chdir(to)); -} - -int PosMakeDir(const char *dname) -{ - return (__mkdir(dname, 0777)); -} - -int PosRemoveDir(const char *dname) -{ - return (__rmdir(dname)); -} - -#else - -void *PosGetDTA(void) -{ - return (NULL); -} - -#endif +/*********************************************************************/ +/* */ +/* This Program Written by Paul Edwards. */ +/* Released to the Public Domain */ +/* */ +/*********************************************************************/ +/*********************************************************************/ +/* */ +/* bios - generic BIOS that exports the C library */ +/* */ +/*********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "__os.h" +#include "exeload.h" + +extern int __genstart; +extern int (*__genmain)(int argc, char **argv); + +/* A BIOS is meant to be machine-specific, so this is not a big deal */ +#if 1 +#define PATH "" +/* #define PATH "./" */ +#else +#define PATH "/storage/emulated/0/Download/" +#endif + +#define MEMAMT 24*1000*1000 + +#if defined(__gnu_linux__) || defined(__ARM__) || defined(__EFI__) +extern int __start(int argc, char **argv); +#else +extern int __start(char *p); +#endif + +int their_start(char *parm); + +#ifndef __SUBC__ +static int getmainargs(int *_Argc, + char ***_Argv); +#endif + +void *PosGetDTA(void); + +#if defined(__gnu_linux__) || defined(__ARM__) +#include + +static int dirfile; + +static DTA origdta; + +int PosFindFirst(char *pat, int attrib); +int PosFindNext(void); +#endif + +static OS bios = { their_start, 0, 0, NULL, NULL, printf, 0, malloc, NULL, NULL, + fopen, fseek, fread, fclose, fwrite, fgets, strchr, + strcmp, strncmp, strcpy, strlen, fgetc, fputc, + fflush, setvbuf, + PosGetDTA, +#if defined(__gnu_linux__) || defined(__ARM__) + PosFindFirst, PosFindNext, +#else + 0, 0, +#endif + 0, 0, + ctime, time, +#if defined(__gnu_linux__) || defined(__ARM__) + PosChangeDir, PosMakeDir, PosRemoveDir, +#else + 0, 0, 0, +#endif + remove, + memcpy, strncpy, strcat, 0 /* stderr */, free, abort, memset, fputs, fprintf, + getenv, memmove, exit, memcmp, _errno, tmpnam, vfprintf, ungetc, vsprintf, + sprintf, signal, raise, calloc, realloc, atoi, strtol, strtoul, qsort, + bsearch, localtime, clock, strerror, strrchr, strstr, strpbrk, strspn, + strcspn, memchr, ftell, abs, setlocale, perror, rewind, strncat, sscanf, + isalnum, isxdigit, rename, clearerr, _assert, atof, +}; + +static char buf[400]; +static char cmd[300]; + +static int (*genstart)(OS *bios); + +int main(int argc, char **argv) +{ + unsigned char *p; + unsigned char *entry_point; + int rc; + char *prog_name; + int need_usage = 0; + int valid = 0; + int shell = 0; + FILE *scr = NULL; + int quiet = 0; + + bios.mem_amt = MEMAMT; + bios.Xstdin = stdin; + bios.Xstdout = stdout; + bios.Xstderr = stderr; + __genstart = 1; + bios.main = &__genmain; + + /* parameters override everything */ + if (argc > 1) + { + if (strcmp(argv[1], "-quiet") == 0) + { + quiet = 1; + argc--; + argv++; + } + if (argc > 1) + { + if (strcmp(argv[1], "-shell") == 0) + { + shell = 1; + argc--; + argv++; + } + } + if (argc > 1) + { + if (strcmp(argv[1], "-quiet") == 0) + { + quiet = 1; + argc--; + argv++; + } + } + /* if they've typed in --help or anything, give them usage */ + if (argv[1][0] == '-') + { + need_usage = 1; + } + else if (argc == 2) + { + bios.prog_name = argv[1]; + bios.prog_parm = ""; + valid = 1; + } + else if (argc == 3) + { + bios.prog_name = argv[1]; + bios.prog_parm = argv[2]; + valid = 1; + } + else + { + need_usage = 1; + } + } + if (!quiet && !need_usage) + { + printf("bios starting\n"); + } + if (!valid && !need_usage) + { + /* an individual command(s) overrides a shell */ + scr = fopen("biosauto.cmd", "r"); + if (scr != NULL) + { + valid = 1; + } + else + { + scr = fopen("biosauto.shl", "r"); + if (scr != NULL) + { + valid = 1; + shell = 1; + } + } + } + if (!valid && !need_usage) + { + scr = stdin; + printf("enter commands, press enter to exit\n"); + } + do + { + if (need_usage) break; /* should put this before do */ + if (scr != NULL) + { + if (fgets(buf, sizeof buf, scr) == NULL) + { + break; + } + p = strchr(buf, '\n'); + if (p != NULL) + { + *p = '\0'; + } + if (buf[0] == '\0') + { + if (scr == stdin) + { + break; + } + continue; + } + if (buf[0] == '#') + { + continue; + } + bios.prog_name = buf; + p = strchr(buf, ' '); + if (p != NULL) + { + *p = '\0'; + bios.prog_parm = p + 1; + } + else + { + bios.prog_parm = ""; + } + } + + p = calloc(1, 5000000); + if (p == NULL) + { + printf("insufficient memory\n"); + return (EXIT_FAILURE); + } + if (exeloadDoload(&entry_point, bios.prog_name, &p) != 0) + { + printf("failed to load executable\n"); + return (EXIT_FAILURE); + } + genstart = (void *)entry_point; + /* printf("first byte of code is %02X\n", *(unsigned char *)entry_point); */ + +#ifdef NEED_DELAY + for (rc = 0; rc < 500; rc++) + { + printf("please accept a delay before we execute program " + "in BSS memory\n"); + } +#endif + + printf("about to execute program\n"); +#if 1 + rc = genstart(&bios); +#else + rc = 0; +#endif + if (!quiet) + { + printf("return from called program is %d\n", rc); + } + free(p); + + if (scr == NULL) + { + break; + } + } while (1); + + if (need_usage) + { + printf("usage: bios [options] [single parm]\n"); + printf("allows execution of non-standard executables\n"); + printf("if no parameters are given and biosauto.cmd is given,\n"); + printf("commands are read, executed and there will be a pause\n"); + printf("otherwise, biosauto.shl is looked for, and there will be\n"); + printf("no pause, because it is assumed to be a shell\n"); + printf("valid options are -quiet and -shell\n"); + printf("e.g. bios -shell pdos.exe uc8086.vhd\n"); + printf("e.g. bios pcomm.exe\n"); + return (EXIT_FAILURE); + } + if (scr == stdin) + { + /* pause has already been done, effectively */ + } + else if (!shell) + { + printf("press enter to exit\n"); + fgets(buf, sizeof buf, stdin); + } + if ((scr != NULL) && (scr != stdin)) + { + fclose(scr); + } + if (!quiet) + { + printf("bios exiting\n"); + } + return (0); +} + +int their_start(char *parm) +{ + int rc; + +#if defined(__gnu_linux__) || defined(__ARM__) || defined(__EFI__) + int argc; + char **argv; + + getmainargs(&argc, &argv); + rc = __start(argc, argv); +#else + rc = __start(parm); +#endif + return (rc); +} + + +#define MAXPARMS 50 + +#ifndef __SUBC__ +static int getmainargs(int *_Argc, + char ***_Argv) +{ + char *p; + int x; + int argc; + static char *argv[MAXPARMS + 1]; + static char *env[] = {NULL}; + + p = cmd; + + argv[0] = p; + p = strchr(p, ' '); + if (p == NULL) + { + p = ""; + } + else + { + *p = '\0'; + p++; + } + + while (*p == ' ') + { + p++; + } + if (*p == '\0') + { + argv[1] = NULL; + argc = 1; + } + else + { + for (x = 1; x < MAXPARMS; ) + { + char srch = ' '; + + if (*p == '"') + { + p++; + srch = '"'; + } + argv[x] = p; + x++; + p = strchr(p, srch); + if (p == NULL) + { + break; + } + else + { + *p = '\0'; + p++; + while (*p == ' ') p++; + if (*p == '\0') break; /* strip trailing blanks */ + } + } + argv[x] = NULL; + argc = x; + } + + *_Argc = argc; + *_Argv = argv; + return (0); +} +#endif + +#if defined(__gnu_linux__) || defined(__ARM__) + +void *PosGetDTA(void) +{ + return (&origdta); +} + +static int ff_search(void) +{ + static unsigned char buf[500]; + static size_t upto = 0; + static size_t avail = 0; + + if (avail <= 0) + { + avail = __getdents(dirfile, buf, 500); + if (avail <= 0) + { + __close(dirfile); + return (1); + } + } + strncpy(origdta.file_name, buf + upto + 10, sizeof origdta.file_name); + origdta.file_name[sizeof origdta.file_name - 1] = '\0'; + strncpy(origdta.lfn, buf + upto + 10, sizeof origdta.lfn); + origdta.lfn[sizeof origdta.lfn - 1] = '\0'; + upto += *(short *)(buf + upto + 8); + if (upto >= avail) + { + upto = avail = 0; + } + return (0); +} + +int PosFindFirst(char *pat, int attrib) +{ + dirfile = __open(".", 0, 0); + if (dirfile < 0) return (1); + return (ff_search()); +} + +int PosFindNext(void) +{ + return (ff_search()); +} + +int PosChangeDir(const char *to) +{ + return (__chdir(to)); +} + +int PosMakeDir(const char *dname) +{ + return (__mkdir(dname, 0777)); +} + +int PosRemoveDir(const char *dname) +{ + return (__rmdir(dname)); +} + +#else + +void *PosGetDTA(void) +{ + return (NULL); +} + +#endif diff --git a/app/src/main/cpp/bios/armeabi-v7a/exeload.c b/app/src/main/cpp/bios/armeabi-v7a/exeload.c index dbeec25..292ce58 100644 --- a/app/src/main/cpp/bios/armeabi-v7a/exeload.c +++ b/app/src/main/cpp/bios/armeabi-v7a/exeload.c @@ -151,7 +151,8 @@ static int exeloadLoadAOUT(unsigned char **entry_point, unsigned char *zap; - if (/*(fseek(fp, 0, SEEK_SET) != 0) || */(fread(&firstbit, sizeof(firstbit), 1, fp) != 1)) + if ((fseek(fp, 0, SEEK_SET) != 0) + || (fread(&firstbit, sizeof(firstbit), 1, fp) != 1)) { return (1); } @@ -1671,6 +1672,14 @@ static int exeloadLoadPE(unsigned char **entry_point, *(unsigned char **)rel_target -= image_diff; else *(unsigned char **)rel_target += image_diff; } +#if TARGET_64BIT + else if (rel_type == IMAGE_REL_BASED_DIR64) + { + if (lower_exeStart) + *(unsigned char **)rel_target -= image_diff; + else *(unsigned char **)rel_target += image_diff; + } +#endif else { printf("Unknown PE relocation type: %u\n", @@ -2107,6 +2116,7 @@ static int exeloadLoadPEDLL(unsigned char *exeStart, } } +#ifndef NO_DLLENTRY /* Entry point is optional for DLLs. */ if (optional_hdr->AddressOfEntryPoint) { @@ -2124,6 +2134,7 @@ static int exeloadLoadPEDLL(unsigned char *exeStart, return (20); } } +#endif /* Frees memory not needed by the DLL. */ free(section_table); diff --git a/app/src/main/cpp/bios/x86/bios.c b/app/src/main/cpp/bios/x86/bios.c index 8bd97dc..68381dc 100644 --- a/app/src/main/cpp/bios/x86/bios.c +++ b/app/src/main/cpp/bios/x86/bios.c @@ -1,454 +1,459 @@ -/*********************************************************************/ -/* */ -/* This Program Written by Paul Edwards. */ -/* Released to the Public Domain */ -/* */ -/*********************************************************************/ -/*********************************************************************/ -/* */ -/* bios - generic BIOS that exports the C library */ -/* */ -/*********************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "__os.h" -#include "exeload.h" - -extern int __genstart; -extern int (*__genmain)(int argc, char **argv); - -/* A BIOS is meant to be machine-specific, so this is not a big deal */ -#if 1 -#define PATH "" -/* #define PATH "./" */ -#else -#define PATH "/storage/emulated/0/Download/" -#endif - -#define MEMAMT 24*1000*1000 - -#if defined(__gnu_linux__) || defined(__ARM__) -extern int __start(int argc, char **argv); -#else -extern int __start(char *p); -#endif - -int their_start(char *parm); - -#ifndef __SUBC__ -static int getmainargs(int *_Argc, - char ***_Argv); -#endif - -void *PosGetDTA(void); - -#if defined(__gnu_linux__) || defined(__ARM__) -#include - -static int dirfile; - -static DTA origdta; - -int PosFindFirst(char *pat, int attrib); -int PosFindNext(void); -#endif - -static OS bios = { their_start, 0, 0, NULL, NULL, printf, 0, malloc, NULL, NULL, - fopen, fseek, fread, fclose, fwrite, fgets, strchr, - strcmp, strncmp, strcpy, strlen, fgetc, fputc, - fflush, setvbuf, - PosGetDTA, -#if defined(__gnu_linux__) || defined(__ARM__) - PosFindFirst, PosFindNext, -#else - 0, 0, -#endif - 0, 0, - ctime, time, -#if defined(__gnu_linux__) || defined(__ARM__) - PosChangeDir, PosMakeDir, PosRemoveDir, -#else - 0, 0, 0, -#endif - remove, - memcpy, strncpy, strcat, 0 /* stderr */, free, abort, memset, fputs, fprintf, - getenv, memmove, exit, memcmp, _errno, tmpnam, vfprintf, ungetc, vsprintf, - sprintf, signal, raise, calloc, realloc, atoi, strtol, strtoul, qsort, - bsearch, localtime, clock, strerror, strrchr, strstr, strpbrk, strspn, - strcspn, memchr, ftell, abs, setlocale, perror, rewind, strncat, sscanf, - isalnum, isxdigit, rename, clearerr, _assert, atof, -}; - -static char buf[400]; -static char cmd[300]; - -static int (*genstart)(OS *bios); - -int main(int argc, char **argv) -{ - unsigned char *p; - unsigned char *entry_point; - int rc; - char *prog_name; - int need_usage = 0; - int valid = 0; - int shell = 0; - FILE *scr = NULL; - int quiet = 0; - - bios.mem_amt = MEMAMT; - bios.Xstdin = stdin; - bios.Xstdout = stdout; - bios.Xstderr = stderr; - __genstart = 1; - bios.main = &__genmain; - - /* parameters override everything */ - if (argc > 1) - { - if (strcmp(argv[1], "-quiet") == 0) - { - quiet = 1; - argc--; - argv++; - } - if (argc > 1) - { - if (strcmp(argv[1], "-shell") == 0) - { - shell = 1; - argc--; - argv++; - } - } - if (argc > 1) - { - if (strcmp(argv[1], "-quiet") == 0) - { - quiet = 1; - argc--; - argv++; - } - } - /* if they've typed in --help or anything, give them usage */ - if (argv[1][0] == '-') - { - need_usage = 1; - } - else if (argc == 2) - { - bios.prog_name = argv[1]; - bios.prog_parm = ""; - valid = 1; - } - else if (argc == 3) - { - bios.prog_name = argv[1]; - bios.prog_parm = argv[2]; - valid = 1; - } - else - { - need_usage = 1; - } - } - if (!quiet && !need_usage) - { - printf("bios starting\n"); - } - if (!valid && !need_usage) - { - /* an individual command(s) overrides a shell */ - scr = fopen("biosauto.cmd", "r"); - if (scr != NULL) - { - valid = 1; - } - else - { - scr = fopen("biosauto.shl", "r"); - if (scr != NULL) - { - valid = 1; - shell = 1; - } - } - } - if (!valid && !need_usage) - { - scr = stdin; - printf("enter commands, press enter to exit\n"); - } - do - { - if (need_usage) break; /* should put this before do */ - if (scr != NULL) - { - if (fgets(buf, sizeof buf, scr) == NULL) - { - break; - } - p = strchr(buf, '\n'); - if (p != NULL) - { - *p = '\0'; - } - if (buf[0] == '\0') - { - if (scr == stdin) - { - break; - } - continue; - } - if (buf[0] == '#') - { - continue; - } - bios.prog_name = buf; - p = strchr(buf, ' '); - if (p != NULL) - { - *p = '\0'; - bios.prog_parm = p + 1; - } - else - { - bios.prog_parm = ""; - } - } - - p = calloc(1, 5000000); - if (p == NULL) - { - printf("insufficient memory\n"); - return (EXIT_FAILURE); - } - if (exeloadDoload(&entry_point, bios.prog_name, &p) != 0) - { - printf("failed to load executable\n"); - return (EXIT_FAILURE); - } - genstart = (void *)entry_point; - /* printf("first byte of code is %02X\n", *(unsigned char *)entry_point); */ - -#ifdef NEED_DELAY - for (rc = 0; rc < 3; rc++) - { - printf("please accept a delay before we execute program " - "in BSS memory\n"); - } -#endif - -#if 1 - rc = genstart(&bios); -#else - rc = 0; -#endif - if (!quiet) - { - printf("return from called program is %d\n", rc); - } - free(p); - - if (scr == NULL) - { - break; - } - } while (1); - - if (need_usage) - { - printf("usage: bios [options] [single parm]\n"); - printf("allows execution of non-standard executables\n"); - printf("if no parameters are given and biosauto.cmd is given,\n"); - printf("commands are read, executed and there will be a pause\n"); - printf("otherwise, biosauto.shl is looked for, and there will be\n"); - printf("no pause, because it is assumed to be a shell\n"); - printf("valid options are -quiet and -shell\n"); - printf("e.g. bios -shell pdos.exe uc8086.vhd\n"); - printf("e.g. bios pcomm.exe\n"); - return (EXIT_FAILURE); - } - if (scr == stdin) - { - /* pause has already been done, effectively */ - } - else if (!shell) - { - printf("press enter to exit\n"); - fgets(buf, sizeof buf, stdin); - } - if ((scr != NULL) && (scr != stdin)) - { - fclose(scr); - } - if (!quiet) - { - printf("bios exiting\n"); - } - return (0); -} - -int their_start(char *parm) -{ -#if defined(__gnu_linux__) || defined(__ARM__) - int argc; - char **argv; - getmainargs(&argc, &argv); - __start(argc, argv); -#else - __start(parm); -#endif -} - - -#define MAXPARMS 50 - -#ifndef __SUBC__ -static int getmainargs(int *_Argc, - char ***_Argv) -{ - char *p; - int x; - int argc; - static char *argv[MAXPARMS + 1]; - static char *env[] = {NULL}; - - p = cmd; - - argv[0] = p; - p = strchr(p, ' '); - if (p == NULL) - { - p = ""; - } - else - { - *p = '\0'; - p++; - } - - while (*p == ' ') - { - p++; - } - if (*p == '\0') - { - argv[1] = NULL; - argc = 1; - } - else - { - for (x = 1; x < MAXPARMS; ) - { - char srch = ' '; - - if (*p == '"') - { - p++; - srch = '"'; - } - argv[x] = p; - x++; - p = strchr(p, srch); - if (p == NULL) - { - break; - } - else - { - *p = '\0'; - p++; - while (*p == ' ') p++; - if (*p == '\0') break; /* strip trailing blanks */ - } - } - argv[x] = NULL; - argc = x; - } - - *_Argc = argc; - *_Argv = argv; - return (0); -} -#endif - -#if defined(__gnu_linux__) || defined(__ARM__) - -void *PosGetDTA(void) -{ - return (&origdta); -} - -static int ff_search(void) -{ - static unsigned char buf[500]; - static size_t upto = 0; - static size_t avail = 0; - - if (avail <= 0) - { - avail = __getdents(dirfile, buf, 500); - if (avail <= 0) - { - __close(dirfile); - return (1); - } - } - strncpy(origdta.file_name, buf + upto + 10, sizeof origdta.file_name); - origdta.file_name[sizeof origdta.file_name - 1] = '\0'; - strncpy(origdta.lfn, buf + upto + 10, sizeof origdta.lfn); - origdta.lfn[sizeof origdta.lfn - 1] = '\0'; - upto += *(short *)(buf + upto + 8); - if (upto >= avail) - { - upto = avail = 0; - } - return (0); -} - -int PosFindFirst(char *pat, int attrib) -{ - dirfile = __open(".", 0, 0); - if (dirfile < 0) return (1); - return (ff_search()); -} - -int PosFindNext(void) -{ - return (ff_search()); -} - -int PosChangeDir(const char *to) -{ - return (__chdir(to)); -} - -int PosMakeDir(const char *dname) -{ - return (__mkdir(dname, 0777)); -} - -int PosRemoveDir(const char *dname) -{ - return (__rmdir(dname)); -} - -#else - -void *PosGetDTA(void) -{ - return (NULL); -} - -#endif +/*********************************************************************/ +/* */ +/* This Program Written by Paul Edwards. */ +/* Released to the Public Domain */ +/* */ +/*********************************************************************/ +/*********************************************************************/ +/* */ +/* bios - generic BIOS that exports the C library */ +/* */ +/*********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "__os.h" +#include "exeload.h" + +extern int __genstart; +extern int (*__genmain)(int argc, char **argv); + +/* A BIOS is meant to be machine-specific, so this is not a big deal */ +#if 1 +#define PATH "" +/* #define PATH "./" */ +#else +#define PATH "/storage/emulated/0/Download/" +#endif + +#define MEMAMT 24*1000*1000 + +#if defined(__gnu_linux__) || defined(__ARM__) || defined(__EFI__) +extern int __start(int argc, char **argv); +#else +extern int __start(char *p); +#endif + +int their_start(char *parm); + +#ifndef __SUBC__ +static int getmainargs(int *_Argc, + char ***_Argv); +#endif + +void *PosGetDTA(void); + +#if defined(__gnu_linux__) || defined(__ARM__) +#include + +static int dirfile; + +static DTA origdta; + +int PosFindFirst(char *pat, int attrib); +int PosFindNext(void); +#endif + +static OS bios = { their_start, 0, 0, NULL, NULL, printf, 0, malloc, NULL, NULL, + fopen, fseek, fread, fclose, fwrite, fgets, strchr, + strcmp, strncmp, strcpy, strlen, fgetc, fputc, + fflush, setvbuf, + PosGetDTA, +#if defined(__gnu_linux__) || defined(__ARM__) + PosFindFirst, PosFindNext, +#else + 0, 0, +#endif + 0, 0, + ctime, time, +#if defined(__gnu_linux__) || defined(__ARM__) + PosChangeDir, PosMakeDir, PosRemoveDir, +#else + 0, 0, 0, +#endif + remove, + memcpy, strncpy, strcat, 0 /* stderr */, free, abort, memset, fputs, fprintf, + getenv, memmove, exit, memcmp, _errno, tmpnam, vfprintf, ungetc, vsprintf, + sprintf, signal, raise, calloc, realloc, atoi, strtol, strtoul, qsort, + bsearch, localtime, clock, strerror, strrchr, strstr, strpbrk, strspn, + strcspn, memchr, ftell, abs, setlocale, perror, rewind, strncat, sscanf, + isalnum, isxdigit, rename, clearerr, _assert, atof, +}; + +static char buf[400]; +static char cmd[300]; + +static int (*genstart)(OS *bios); + +int main(int argc, char **argv) +{ + unsigned char *p; + unsigned char *entry_point; + int rc; + char *prog_name; + int need_usage = 0; + int valid = 0; + int shell = 0; + FILE *scr = NULL; + int quiet = 0; + + bios.mem_amt = MEMAMT; + bios.Xstdin = stdin; + bios.Xstdout = stdout; + bios.Xstderr = stderr; + __genstart = 1; + bios.main = &__genmain; + + /* parameters override everything */ + if (argc > 1) + { + if (strcmp(argv[1], "-quiet") == 0) + { + quiet = 1; + argc--; + argv++; + } + if (argc > 1) + { + if (strcmp(argv[1], "-shell") == 0) + { + shell = 1; + argc--; + argv++; + } + } + if (argc > 1) + { + if (strcmp(argv[1], "-quiet") == 0) + { + quiet = 1; + argc--; + argv++; + } + } + /* if they've typed in --help or anything, give them usage */ + if (argv[1][0] == '-') + { + need_usage = 1; + } + else if (argc == 2) + { + bios.prog_name = argv[1]; + bios.prog_parm = ""; + valid = 1; + } + else if (argc == 3) + { + bios.prog_name = argv[1]; + bios.prog_parm = argv[2]; + valid = 1; + } + else + { + need_usage = 1; + } + } + if (!quiet && !need_usage) + { + printf("bios starting\n"); + } + if (!valid && !need_usage) + { + /* an individual command(s) overrides a shell */ + scr = fopen("biosauto.cmd", "r"); + if (scr != NULL) + { + valid = 1; + } + else + { + scr = fopen("biosauto.shl", "r"); + if (scr != NULL) + { + valid = 1; + shell = 1; + } + } + } + if (!valid && !need_usage) + { + scr = stdin; + printf("enter commands, press enter to exit\n"); + } + do + { + if (need_usage) break; /* should put this before do */ + if (scr != NULL) + { + if (fgets(buf, sizeof buf, scr) == NULL) + { + break; + } + p = strchr(buf, '\n'); + if (p != NULL) + { + *p = '\0'; + } + if (buf[0] == '\0') + { + if (scr == stdin) + { + break; + } + continue; + } + if (buf[0] == '#') + { + continue; + } + bios.prog_name = buf; + p = strchr(buf, ' '); + if (p != NULL) + { + *p = '\0'; + bios.prog_parm = p + 1; + } + else + { + bios.prog_parm = ""; + } + } + + p = calloc(1, 5000000); + if (p == NULL) + { + printf("insufficient memory\n"); + return (EXIT_FAILURE); + } + if (exeloadDoload(&entry_point, bios.prog_name, &p) != 0) + { + printf("failed to load executable\n"); + return (EXIT_FAILURE); + } + genstart = (void *)entry_point; + /* printf("first byte of code is %02X\n", *(unsigned char *)entry_point); */ + +#ifdef NEED_DELAY + for (rc = 0; rc < 500; rc++) + { + printf("please accept a delay before we execute program " + "in BSS memory\n"); + } +#endif + + printf("about to execute program\n"); +#if 1 + rc = genstart(&bios); +#else + rc = 0; +#endif + if (!quiet) + { + printf("return from called program is %d\n", rc); + } + free(p); + + if (scr == NULL) + { + break; + } + } while (1); + + if (need_usage) + { + printf("usage: bios [options] [single parm]\n"); + printf("allows execution of non-standard executables\n"); + printf("if no parameters are given and biosauto.cmd is given,\n"); + printf("commands are read, executed and there will be a pause\n"); + printf("otherwise, biosauto.shl is looked for, and there will be\n"); + printf("no pause, because it is assumed to be a shell\n"); + printf("valid options are -quiet and -shell\n"); + printf("e.g. bios -shell pdos.exe uc8086.vhd\n"); + printf("e.g. bios pcomm.exe\n"); + return (EXIT_FAILURE); + } + if (scr == stdin) + { + /* pause has already been done, effectively */ + } + else if (!shell) + { + printf("press enter to exit\n"); + fgets(buf, sizeof buf, stdin); + } + if ((scr != NULL) && (scr != stdin)) + { + fclose(scr); + } + if (!quiet) + { + printf("bios exiting\n"); + } + return (0); +} + +int their_start(char *parm) +{ + int rc; + +#if defined(__gnu_linux__) || defined(__ARM__) || defined(__EFI__) + int argc; + char **argv; + + getmainargs(&argc, &argv); + rc = __start(argc, argv); +#else + rc = __start(parm); +#endif + return (rc); +} + + +#define MAXPARMS 50 + +#ifndef __SUBC__ +static int getmainargs(int *_Argc, + char ***_Argv) +{ + char *p; + int x; + int argc; + static char *argv[MAXPARMS + 1]; + static char *env[] = {NULL}; + + p = cmd; + + argv[0] = p; + p = strchr(p, ' '); + if (p == NULL) + { + p = ""; + } + else + { + *p = '\0'; + p++; + } + + while (*p == ' ') + { + p++; + } + if (*p == '\0') + { + argv[1] = NULL; + argc = 1; + } + else + { + for (x = 1; x < MAXPARMS; ) + { + char srch = ' '; + + if (*p == '"') + { + p++; + srch = '"'; + } + argv[x] = p; + x++; + p = strchr(p, srch); + if (p == NULL) + { + break; + } + else + { + *p = '\0'; + p++; + while (*p == ' ') p++; + if (*p == '\0') break; /* strip trailing blanks */ + } + } + argv[x] = NULL; + argc = x; + } + + *_Argc = argc; + *_Argv = argv; + return (0); +} +#endif + +#if defined(__gnu_linux__) || defined(__ARM__) + +void *PosGetDTA(void) +{ + return (&origdta); +} + +static int ff_search(void) +{ + static unsigned char buf[500]; + static size_t upto = 0; + static size_t avail = 0; + + if (avail <= 0) + { + avail = __getdents(dirfile, buf, 500); + if (avail <= 0) + { + __close(dirfile); + return (1); + } + } + strncpy(origdta.file_name, buf + upto + 10, sizeof origdta.file_name); + origdta.file_name[sizeof origdta.file_name - 1] = '\0'; + strncpy(origdta.lfn, buf + upto + 10, sizeof origdta.lfn); + origdta.lfn[sizeof origdta.lfn - 1] = '\0'; + upto += *(short *)(buf + upto + 8); + if (upto >= avail) + { + upto = avail = 0; + } + return (0); +} + +int PosFindFirst(char *pat, int attrib) +{ + dirfile = __open(".", 0, 0); + if (dirfile < 0) return (1); + return (ff_search()); +} + +int PosFindNext(void) +{ + return (ff_search()); +} + +int PosChangeDir(const char *to) +{ + return (__chdir(to)); +} + +int PosMakeDir(const char *dname) +{ + return (__mkdir(dname, 0777)); +} + +int PosRemoveDir(const char *dname) +{ + return (__rmdir(dname)); +} + +#else + +void *PosGetDTA(void) +{ + return (NULL); +} + +#endif diff --git a/app/src/main/cpp/bios/x86/exeload.c b/app/src/main/cpp/bios/x86/exeload.c index b836742..292ce58 100644 --- a/app/src/main/cpp/bios/x86/exeload.c +++ b/app/src/main/cpp/bios/x86/exeload.c @@ -151,7 +151,8 @@ static int exeloadLoadAOUT(unsigned char **entry_point, unsigned char *zap; - if (/*(fseek(fp, 0, SEEK_SET) != 0) || */(fread(&firstbit, sizeof(firstbit), 1, fp) != 1)) + if ((fseek(fp, 0, SEEK_SET) != 0) + || (fread(&firstbit, sizeof(firstbit), 1, fp) != 1)) { return (1); } @@ -790,7 +791,8 @@ static int exeloadLoadELF(unsigned char **entry_point, long newpos; size_t readbytes; - if (/*(fseek(fp, 0, SEEK_SET) != 0) || */(fread(&firstbit, sizeof firstbit, 1, fp) != 1) + if ((fseek(fp, 0, SEEK_SET) != 0) + || (fread(&firstbit, sizeof firstbit, 1, fp) != 1) || (memcmp(&firstbit, "\x7f" "ELF", 4) != 0)) { return (1); @@ -1670,6 +1672,14 @@ static int exeloadLoadPE(unsigned char **entry_point, *(unsigned char **)rel_target -= image_diff; else *(unsigned char **)rel_target += image_diff; } +#if TARGET_64BIT + else if (rel_type == IMAGE_REL_BASED_DIR64) + { + if (lower_exeStart) + *(unsigned char **)rel_target -= image_diff; + else *(unsigned char **)rel_target += image_diff; + } +#endif else { printf("Unknown PE relocation type: %u\n", @@ -2106,6 +2116,7 @@ static int exeloadLoadPEDLL(unsigned char *exeStart, } } +#ifndef NO_DLLENTRY /* Entry point is optional for DLLs. */ if (optional_hdr->AddressOfEntryPoint) { @@ -2123,6 +2134,7 @@ static int exeloadLoadPEDLL(unsigned char *exeStart, return (20); } } +#endif /* Frees memory not needed by the DLL. */ free(section_table); diff --git a/app/src/main/cpp/pdos.c b/app/src/main/cpp/pdos.c index 11c00d5..a2d5828 100644 --- a/app/src/main/cpp/pdos.c +++ b/app/src/main/cpp/pdos.c @@ -56,8 +56,7 @@ int run(char *cmd, char *arg1) } #define BIN_SIZE 32 * 1024 * 1024 -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { int n = 0; FILE *fp = stdin; int fd = STDIN_FILENO; @@ -65,34 +64,34 @@ int main(int argc, char *argv[]) char b[1024]; char *prompt = NULL; #if 0 // amd64 in RAM execution test -/* char assembly[] = {0x48, 0xc7, 0xc0, 0x10, 0x00, 0x00, 0x00, // movq $16, %rax - 0xc3}; // retq - */ // Arm32 - char assembly[] = {0x11, 0x00, 0xa0, 0xe3, // mov r0, #17 - 0x1e, 0xff, 0x2f, 0xe1}; // bx lr - - char *bin; - int ret; - char *err; - long pagesize = sysconf(_SC_PAGESIZE); - long memsize = (BIN_SIZE + pagesize -1) / pagesize * pagesize; - bin = (long)malloc(BIN_SIZE + pagesize - 1) / pagesize * pagesize; - //bin = malloc(pagesize); - memcpy(bin, assembly, sizeof(assembly)); - ret = mprotect(bin, memsize, PROT_EXEC|PROT_READ|PROT_WRITE); - if (ret != 0) { - err = strerror(errno); - write(STDOUT_FILENO, err, strlen(err)); + /* char assembly[] = {0x48, 0xc7, 0xc0, 0x10, 0x00, 0x00, 0x00, // movq $16, %rax + 0xc3}; // retq + */ // Arm32 + char assembly[] = {0x11, 0x00, 0xa0, 0xe3, // mov r0, #17 + 0x1e, 0xff, 0x2f, 0xe1}; // bx lr - } - ret = ((int(*)())bin)(); - snprintf(cmd, 10, "R%ld", ret); - sleep(1); - write(STDOUT_FILENO, cmd, strlen(cmd)); + char *bin; + int ret; + char *err; + long pagesize = sysconf(_SC_PAGESIZE); + long memsize = (BIN_SIZE + pagesize -1) / pagesize * pagesize; + bin = (long)malloc(BIN_SIZE + pagesize - 1) / pagesize * pagesize; + //bin = malloc(pagesize); + memcpy(bin, assembly, sizeof(assembly)); + ret = mprotect(bin, memsize, PROT_EXEC|PROT_READ|PROT_WRITE); + if (ret != 0) { + err = strerror(errno); + write(STDOUT_FILENO, err, strlen(err)); + + } + ret = ((int(*)())bin)(); + snprintf(cmd, 10, "R%ld", ret); + sleep(1); + write(STDOUT_FILENO, cmd, strlen(cmd)); #endif sleep(1); - + if (argc > 1) { write(STDOUT_FILENO, argv[1], strlen(argv[1])); } @@ -109,8 +108,26 @@ int main(int argc, char *argv[]) sleep(1); return 0; -#if 0 - prompt = "\nEnter \"bios\" to start PDOS.\nprompt>"; +#if 0 + if (argc > 1) { + write(STDOUT_FILENO, argv[1], strlen(argv[1])); + } + if (argc > 2) { + write(STDOUT_FILENO, "\n", 1); + write(STDOUT_FILENO, argv[2], strlen(argv[2])); + } + write(STDOUT_FILENO, "\n", 1); + //sleep(2); + + snprintf(b, sizeof(b), argv[1], "bios"); + snprintf(cmd, sizeof(cmd), "%s", b); + if (system(cmd) >= 0) { + sleep(3); + // return 0; + } + + + prompt = "\n*** DEBUG SHELL ****.\nprompt>"; write(STDOUT_FILENO, prompt, strlen(prompt)); prompt = NULL; old_mode = fcntl(STDIN_FILENO, F_GETFL); @@ -136,12 +153,12 @@ int main(int argc, char *argv[]) } else if (!strcmp(cmd, "test1")) { prompt = "\x1b[A\r\x1b[K\x1b[1;32mopened \x1b[1;4;34m%s\x1b[0;1;32m in your browser.\x1b[0m\n\x1b[1;1H"; write(STDOUT_FILENO, prompt, strlen(prompt)); - } else if (!strcmp(cmd, "LS")) { - snprintf(cmd, sizeof(cmd), argv[1], "ls"); - run(cmd, NULL/*argv[2]*/); - } else if (!strcmp(cmd, "bios")) { + } else if (!strcmp(cmd, "bios.exe")) { snprintf(cmd, sizeof(cmd), argv[1], "bios"); run(cmd, NULL); + } else if (!strcmp(cmd, "pcomm.exe")) { + snprintf(cmd, sizeof(cmd), argv[1], "pcomm"); + run(cmd, NULL); } else { system(cmd); } diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/armsupa.asm b/app/src/main/cpp/pdpclib/armeabi-v7a/armsupa.asm index 09ba5d6..23cd6eb 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/armsupa.asm +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/armsupa.asm @@ -94,13 +94,13 @@ ___exita: .align 2 __write: ___write: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r2,[sp,#12] @ len # ldr r1,[sp,#8] @ buf # ldr r0,[sp,#4] @ fd mov r7,#4 @ SYS_write swi 0 -wrtok: ldmia sp!,{pc} +wrtok: ldmia sp!,{r7,pc} # int ___read(int fd, void *buf, int len); @@ -110,13 +110,13 @@ wrtok: ldmia sp!,{pc} .align 2 __read: ___read: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r2,[sp,#12] @ len # ldr r1,[sp,#8] @ buf # ldr r0,[sp,#4] @ fd mov r7,#3 @ SYS_read swi 0 -redok: ldmia sp!,{pc} +redok: ldmia sp!,{r7,pc} # int ___seek(int fd, int pos, int how); @@ -126,14 +126,14 @@ redok: ldmia sp!,{pc} .align 2 __seek: ___seek: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r2,[sp,#12] @ how # ldr r1,[sp,#8] @ off_t # ldr r0,[sp,#4] @ fd - mov r7,#19 + mov r7,#19 @ SYS_lseek swi 0 lskok: - ldmia sp!,{pc} + ldmia sp!,{r7,pc} # int __creat(char *path, int mode); @@ -143,13 +143,13 @@ lskok: .align 2 __creat: ___creat: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r1,[sp,#8] @ mode mov r1,#0x1A4 @ 0644 # ldr r0,[sp,#4] @ path mov r7,#8 @ SYS_creat swi 0 -crtok: ldmia sp!,{pc} +crtok: ldmia sp!,{r7,pc} # int _open(char *path, int flags); @@ -159,13 +159,13 @@ crtok: ldmia sp!,{pc} .align 2 __open: ___open: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # mov r2,#0x1A4 @ 0644 # ldr r1,[sp,#8] @ flags # ldr r0,[sp,#4] @ path mov r7,#5 @ SYS_open swi 0 -opnok: ldmia sp!,{pc} +opnok: ldmia sp!,{r7,pc} # int _close(int fd); @@ -175,11 +175,11 @@ opnok: ldmia sp!,{pc} .align 2 __close: ___close: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r0,[sp,#4] @ fd mov r7,#6 @ SYS_close swi 0 -clsok: ldmia sp!,{pc} +clsok: ldmia sp!,{r7,pc} # int ___remove(char *path); @@ -189,11 +189,11 @@ clsok: ldmia sp!,{pc} .align 2 __remove: ___remove: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r0,[sp,#4] @ path mov r7,#10 @ SYS_unlink swi 0 -unlok: ldmia sp!,{pc} +unlok: ldmia sp!,{r7,pc} # int ___rename(char *old, char *new); @@ -203,12 +203,12 @@ unlok: ldmia sp!,{pc} .align 2 __rename: ___rename: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r1,[sp,#8] @ new # ldr r0,[sp,#4] @ old mov r7,#0x26 @ SYS_rename swi 0 -renok: ldmia sp!,{pc} +renok: ldmia sp!,{r7,pc} # int __time(void); @@ -218,7 +218,7 @@ renok: ldmia sp!,{pc} .align 2 __time: ___time: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} sub sp,sp,#16 @ struct timespec mov r1,sp mov r0,#0 @ CLOCK_REALTIME @@ -226,7 +226,7 @@ ___time: swi 0 timok: ldr r0,[sp] add sp,sp,#16 - ldmia sp!,{pc} + ldmia sp!,{r7,pc} # int ___mprotect(const void *buf, size_t len, int prot); @@ -236,13 +236,13 @@ timok: ldr r0,[sp] .align 2 __mprotect: ___mprotect: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r2,[sp,#12] @ prot # ldr r1,[sp,#8] @ len # ldr r0,[sp,#4] @ buf mov r7,#125 @ SYS_mprotect swi 0 -mpok: ldmia sp!,{pc} +mpok: ldmia sp!,{r7,pc} # int ___getdents(unsigned int fd, struct linux_dirent *dirent, int count); @@ -252,13 +252,13 @@ mpok: ldmia sp!,{pc} .align 2 __getdents: ___getdents: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r2,[sp,#12] @ count # ldr r1,[sp,#8] @ dirent # ldr r0,[sp,#4] @ fd mov r7,#141 @ SYS_getdents swi 0 -gdok: ldmia sp!,{pc} +gdok: ldmia sp!,{r7,pc} # int ___ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); @@ -268,13 +268,13 @@ gdok: ldmia sp!,{pc} .align 2 __ioctl: ___ioctl: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r2,[sp,#12] @ arg # ldr r1,[sp,#8] @ cmd # ldr r0,[sp,#4] @ fd mov r7,#54 @ SYS_ioctl swi 0 -iocok: ldmia sp!,{pc} +iocok: ldmia sp!,{r7,pc} # int ___chdir(const char *filename); @@ -284,11 +284,11 @@ iocok: ldmia sp!,{pc} .align 2 __chdir: ___chdir: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r0,[sp,#4] @ filename mov r7,#12 @ SYS_chdir swi 0 -cdok: ldmia sp!,{pc} +cdok: ldmia sp!,{r7,pc} # int ___mkdir(const char *pathname, unsigned int mode); @@ -298,12 +298,12 @@ cdok: ldmia sp!,{pc} .align 2 __mkdir: ___mkdir: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r1,[sp,#8] @ mode # ldr r0,[sp,#4] @ pathname mov r7,#39 @ SYS_mkdir swi 0 -mdok: ldmia sp!,{pc} +mdok: ldmia sp!,{r7,pc} # int ___rmdir(const char *pathname); @@ -313,11 +313,11 @@ mdok: ldmia sp!,{pc} .align 2 __rmdir: ___rmdir: - stmfd sp!,{lr} + stmfd sp!,{r7,lr} # ldr r0,[sp,#4] @ pathname mov r7,#40 @ SYS_rmdir swi 0 -rdok: ldmia sp!,{pc} +rdok: ldmia sp!,{r7,pc} .endif diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/linstart.c b/app/src/main/cpp/pdpclib/armeabi-v7a/linstart.c old mode 100644 new mode 100755 index 82bc8da..184f22a --- a/app/src/main/cpp/pdpclib/armeabi-v7a/linstart.c +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/linstart.c @@ -1,111 +1,111 @@ -/* Startup code for Linux */ -/* written by Paul Edwards */ -/* released to the public domain */ - -#include "errno.h" -#include "stddef.h" - -/* malloc calls get this */ -static char membuf[31000000]; -static char *newmembuf = membuf; - -extern int __start(int argc, char **argv); -extern int __exita(int rc); - -#ifdef NEED_MPROTECT -extern int __mprotect(void *buf, size_t len, int prot); - -#define PROT_READ 1 -#define PROT_WRITE 2 -#define PROT_EXEC 4 -#endif - -/* We can get away with a minimal startup code, plus make it - a C program. There is no return address. Instead, on the - stack is a count, followed by all the parameters as pointers */ - -int _start(char *p) -{ - int rc; - -#ifdef NEED_MPROTECT - /* make malloced memory executable */ - /* most environments already make the memory executable */ - /* but some certainly don't */ - /* there doesn't appear to be a syscall to get the page size to - ensure page alignment (as required), and I read that some - environments have 4k page sizes but mprotect requires 16k - alignment. So for now we'll just go with 16k */ - size_t blksize = 16 * 1024; - size_t numblks; - - newmembuf = membuf + blksize; /* could waste memory here */ - newmembuf = newmembuf - (unsigned int)newmembuf % blksize; - numblks = sizeof membuf / blksize; - numblks -= 2; /* if already aligned, we wasted an extra block */ - rc = __mprotect(newmembuf, - numblks * blksize, - PROT_READ | PROT_WRITE | PROT_EXEC); - if (rc != 0) return (rc); -#endif - - /* I don't know what the official rules for ARM are, but - looking at the stack on entry showed that this code - would work */ -#ifdef __ARM__ - -#if defined(__UNOPT__) - rc = __start(*(int *)(&p + 5), &p + 6); -#else - rc = __start(*(int *)(&p + 6), &p + 7); -#endif - -/* Note that a problem with this stack manipulation was found when - built with clang with optimization on. clang correctly determines - that it is undefined behavior (this sort of stack manipulation is), - but instead of doing what the programmer clearly intended to do - (ie the result you get without optimization), it decides to silently - drop the first parameter and pass whatever rubbish is on the stack - as argc. And they don't see anything wrong with that! - https://github.com/llvm/llvm-project/issues/61112 - I don't consider my code to be wrong (although it is obviously not - portable - I'm writing a C library, not a C program), so if you wish - to use clang, then switch off optimization. Otherwise use a better - compiler, not one "supported" by jackasses on the internet who have - no concept of the spirit of C. -*/ - -#else - rc = __start(*(int *)(&p - 1), &p); -#endif - __exita(rc); - return (rc); -} - - -void *__allocmem(size_t size) -{ - return (newmembuf); -} - - -#if defined(__WATCOMC__) - -#define CTYP __cdecl - -/* this is invoked by long double manipulations - in stdio.c and needs to be done properly */ - -int CTYP _CHP(void) -{ - return (0); -} - -/* don't know what these are */ - -void CTYP cstart_(void) { return; } -void CTYP _argc(void) { return; } -void CTYP argc(void) { return; } -void CTYP _8087(void) { return; } - -#endif +/* Startup code for Linux */ +/* written by Paul Edwards */ +/* released to the public domain */ + +#include "errno.h" +#include "stddef.h" + +/* malloc calls get this */ +static char membuf[31000000]; +static char *newmembuf = membuf; + +extern int __start(int argc, char **argv); +extern int __exita(int rc); + +#ifdef NEED_MPROTECT +extern int __mprotect(void *buf, size_t len, int prot); + +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 +#endif + +/* We can get away with a minimal startup code, plus make it + a C program. There is no return address. Instead, on the + stack is a count, followed by all the parameters as pointers */ + +int _start(char *p) +{ + int rc; + +#ifdef NEED_MPROTECT + /* make malloced memory executable */ + /* most environments already make the memory executable */ + /* but some certainly don't */ + /* there doesn't appear to be a syscall to get the page size to + ensure page alignment (as required), and I read that some + environments have 4k page sizes but mprotect requires 16k + alignment. So for now we'll just go with 16k */ + size_t blksize = 16 * 1024; + size_t numblks; + + newmembuf = membuf + blksize; /* could waste memory here */ + newmembuf = newmembuf - (unsigned int)newmembuf % blksize; + numblks = sizeof membuf / blksize; + numblks -= 2; /* if already aligned, we wasted an extra block */ + rc = __mprotect(newmembuf, + numblks * blksize, + PROT_READ | PROT_WRITE | PROT_EXEC); + if (rc != 0) return (rc); +#endif + + /* I don't know what the official rules for ARM are, but + looking at the stack on entry showed that this code + would work */ +#ifdef __ARM__ + +#if defined(__UNOPT__) + rc = __start(*(int *)(&p + 5), &p + 6); +#else + rc = __start(*(int *)(&p + 6), &p + 7); +#endif + +/* Note that a problem with this stack manipulation was found when + built with clang with optimization on. clang correctly determines + that it is undefined behavior (this sort of stack manipulation is), + but instead of doing what the programmer clearly intended to do + (ie the result you get without optimization), it decides to silently + drop the first parameter and pass whatever rubbish is on the stack + as argc. And they don't see anything wrong with that! + https://github.com/llvm/llvm-project/issues/61112 + I don't consider my code to be wrong (although it is obviously not + portable - I'm writing a C library, not a C program), so if you wish + to use clang, then switch off optimization. Otherwise use a better + compiler, not one "supported" by jackasses on the internet who have + no concept of the spirit of C. +*/ + +#else + rc = __start(*(int *)(&p - 1), &p); +#endif + __exita(rc); + return (rc); +} + + +void *__allocmem(size_t size) +{ + return (newmembuf); +} + + +#if defined(__WATCOMC__) + +#define CTYP __cdecl + +/* this is invoked by long double manipulations + in stdio.c and needs to be done properly */ + +int CTYP _CHP(void) +{ + return (0); +} + +/* don't know what these are */ + +void CTYP cstart_(void) { return; } +void CTYP _argc(void) { return; } +void CTYP argc(void) { return; } +void CTYP _8087(void) { return; } + +#endif diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/pgastart.c b/app/src/main/cpp/pdpclib/armeabi-v7a/pgastart.c index 5c89581..d82325b 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/pgastart.c +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/pgastart.c @@ -27,10 +27,18 @@ int __crt0(OS *os) return (__os->__start(0)); } -#ifdef __AMIGA__ +#if defined(__AMIGA__) || defined(NEED_UNDMAIN) /* needed for Amiga (gccami) */ void __main(void) { return; } #endif + +#if defined(NEED_EXIT) +void exit(int x) +{ + __os->Xexit(x); + return; +} +#endif diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/setjmp.h b/app/src/main/cpp/pdpclib/armeabi-v7a/setjmp.h index d9313bf..601e559 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/setjmp.h +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/setjmp.h @@ -14,7 +14,11 @@ #define __SETJMP_INCLUDED typedef struct { -#if defined(__MVS__) || defined(__CMS__) || defined(__VSE__) +#if defined(__64BIT__) + long long retval; + long long retaddr; + long long regs[10]; +#elif defined(__MVS__) || defined(__CMS__) || defined(__VSE__) int regs[15]; #elif defined(__AMIGA__) long a0; @@ -71,14 +75,24 @@ typedef struct { #else #error unknown system in setjmp.h #endif +#ifndef __64BIT__ int retval; +#endif } jmp_buf[1]; void longjmp(jmp_buf env, int val); -#ifdef __MSC__ +#if defined(__64BIT__) +#define setjmp(x) __setj(x) +int __setj(jmp_buf env); + +#elif defined(__MSC__) int setjmp(jmp_buf env); +#elif defined(__EFI__) +#define setjmp(x) __setj(x) +int __setj(jmp_buf env); + #elif defined(__ARM__) || defined(__ARMGEN__) /* it appears that gcc has _setjmp as a known keyword which is causing issues on ARM, so we change the name */ diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/start.c b/app/src/main/cpp/pdpclib/armeabi-v7a/start.c index 45b0256..e5a8e65 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/start.c +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/start.c @@ -258,6 +258,7 @@ void *DOSBase; #if defined(__EFI__) #include "efi.h" +extern EFI_FILE_PROTOCOL *__EfiRoot; #endif #if defined(__PDOS386__) @@ -366,12 +367,10 @@ int __start(char *plist, char *pgmname, char **eplist) int __start(char *p, char *pgmname, char *ep) #elif defined(__MVS__) int __start(char *p, char *pgmname, int tso) -#elif defined(__gnu_linux__) +#elif defined(__gnu_linux__) || defined(__EFI__) int __start(int argc, char **argv) #elif defined(__AMIGA__) int __start(unsigned long cmdlen, char *p, void *pdosbase) -#elif defined(__EFI__) -int __start(void) #elif defined(__SMALLERC__) __PDPCLIB_API__ int CTYP __start(char *p, unsigned short osver) #else @@ -380,14 +379,11 @@ __PDPCLIB_API__ int CTYP __start(char *p) { #ifdef __CMS__ char *p; -#endif -#ifdef __EFI__ - char *p = ""; #endif int x; int oldglobrc = globrc; jmp_buf oldjb; -#if !defined(__gnu_linux__) +#if !defined(__gnu_linux__) && !defined(__EFI__) int argc; static char *argv[MAXPARMS + 1]; #endif @@ -484,7 +480,7 @@ __PDPCLIB_API__ int CTYP __start(char *p) __stdin->hfile = Input(); __stdout->hfile = Output(); __stderr->hfile = Output(); -#else +#elif !defined(__EFI__) /* EFI will leave everything as NULL */ __stdin->hfile = 0; __stdout->hfile = 1; __stderr->hfile = 2; @@ -1159,7 +1155,7 @@ __PDPCLIB_API__ int CTYP __start(char *p) } } #endif -#if !defined(__gnu_linux__) +#if !defined(__gnu_linux__) && !defined(__EFI__) while (*p == ' ') { p++; @@ -1255,7 +1251,9 @@ __PDPCLIB_API__ int CTYP __start(char *p) #endif if (runnum == 1) { +#if !defined(__64BIT__) __exit(rc); +#endif } runnum--; return (rc); @@ -1285,6 +1283,10 @@ void __exit(int status) so that we don't get called again */ runnum--; /* and we can't go through another longjmp either */ + /* really? 64 bit needs a longjmp. */ +#ifdef __64BIT__ + longjmp(jb, status); +#endif return; } globrc = status; @@ -1350,6 +1352,14 @@ __PDPCLIB_API__ void _c_exit(void) SetConsoleMode(__stdout->hfile, stdout_dw); #endif +#if defined(__EFI__) + if (__EfiRoot != NULL) + { + __EfiRoot->Close(__EfiRoot); + __EfiRoot = NULL; + } +#endif + #if defined(__PDOS386__) PosSetDeviceInformation(0, stdin_dw); #endif diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/stdarg.h b/app/src/main/cpp/pdpclib/armeabi-v7a/stdarg.h index 342ea40..848cae9 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/stdarg.h +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/stdarg.h @@ -51,8 +51,13 @@ typedef char * va_list; #define va_arg(ap, type) *(type far *)(ap += sizeof(type), ap - sizeof(type)) #else #define va_start(ap, parmN) ap = (char *)&parmN + sizeof(parmN) +#ifdef __64BIT__ +#define va_arg(ap, type) *(type *)(ap += (sizeof(type) < 8) ? 8 : sizeof(type),\ + ap - ((sizeof(type) < 8) ? 8 : sizeof(type))) +#else #define va_arg(ap, type) *(type *)(ap += sizeof(type), ap - sizeof(type)) #endif +#endif #define va_end(ap) ap = (char *)0 #endif diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/stddef.h b/app/src/main/cpp/pdpclib/armeabi-v7a/stddef.h index 7a534ab..c956ec8 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/stddef.h +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/stddef.h @@ -13,10 +13,17 @@ #ifndef __STDDEF_INCLUDED #define __STDDEF_INCLUDED +#if defined(__64BIT__) +typedef long long ptrdiff_t; +#else typedef int ptrdiff_t; +#endif + #ifndef __SIZE_T_DEFINED #define __SIZE_T_DEFINED -#if (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ +#if defined(__64BIT__) +typedef unsigned long long size_t; +#elif (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ || defined(__CMS__) || defined(__VSE__) || defined(__SMALLERC__) \ || defined(__ARM__) || defined(__gnu_linux__) || defined(__PDOS386__) \ || defined(__SZ4__)) diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/stdio.c b/app/src/main/cpp/pdpclib/armeabi-v7a/stdio.c index 65853f0..7b80eaa 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/stdio.c +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/stdio.c @@ -118,6 +118,10 @@ extern void CTYP __rename(const char *old, const char *newnam); #ifdef __EFI__ #include "efi.h" +EFI_FILE_PROTOCOL *__EfiRoot = NULL; +#ifdef __EFIBIOS__ +static EFI_BLOCK_IO_PROTOCOL *bio_protocol = NULL; +#endif #endif #ifdef __OS2__ @@ -258,11 +262,11 @@ static const char *fnm; static const char *modus; static int modeType; -__PDPCLIB_API__ FILE **__gtin() +__PDPCLIB_API__ FILE **__gtin(void) { return(&__stdin_ptr); } -__PDPCLIB_API__ FILE **__gtout() +__PDPCLIB_API__ FILE **__gtout(void) { return(&__stdout_ptr); } -__PDPCLIB_API__ FILE **__gterr() +__PDPCLIB_API__ FILE **__gterr(void) { return(&__stderr_ptr); } #if defined(__WIN32__) && !defined(__STATIC__) @@ -754,6 +758,93 @@ static void osfopen(void) errno = 1; } #endif + + +#ifdef __EFI__ + +#define return_Status_if_fail(func) do { if ((Status = (func))) { err = 1; \ + errno = Status; return; }} while (0) + + int mode; + EFI_STATUS Status = EFI_SUCCESS; + static EFI_GUID li_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + EFI_LOADED_IMAGE_PROTOCOL *li_protocol; + static EFI_GUID sfs_protocol_guid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *sfs_protocol; + UINT64 OpenModeRead = {0x3, 0}; /* Read+Write */ + UINT64 OpenModeWrite = {0x3, 0x80000000}; /* Read+Write+Create */ + EFI_FILE_PROTOCOL *new_file; + static UINT64 Attributes = {0, 0}; + CHAR16 file_name[FILENAME_MAX]; + int x; + static EFI_GUID block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID; + + if (__EfiRoot == NULL) + { + return_Status_if_fail (__gBS->HandleProtocol (__gIH, &li_guid, (void **)&li_protocol)); + return_Status_if_fail (__gBS->HandleProtocol (li_protocol->DeviceHandle, &sfs_protocol_guid, (void **)&sfs_protocol)); + return_Status_if_fail (sfs_protocol->OpenVolume (sfs_protocol, &__EfiRoot)); +#ifdef __EFIBIOS__ + return_Status_if_fail (__gBS->HandleProtocol (li_protocol->DeviceHandle, &block_io_guid, (void **)&bio_protocol)); +#endif + } + + if ((modeType == 1) || (modeType == 4) + || (modeType == 7) || (modeType == 10)) + { + mode = 0; /* read */ + } + else if ((modeType == 2) || (modeType == 5) + || (modeType == 8) || (modeType == 11)) + { + mode = 1; /* write */ + } + else + { + mode = 2; /* append or otherwise unsupported */ + /* because we don't have append mode implemented + at the moment, just return with an + error immediately */ + err = 1; + errno = 2; + return; + } + +#ifdef __EFIBIOS__ + myfile->block = 0; + if (strcmp(fnm, "!BOOT") == 0) + { + myfile->block = 1; + myfile->sector = 0; + } + else +#endif + { + x = 0; + do { + file_name[x] = (CHAR16)fnm[x]; + } while (fnm[x++] != 0); + + if (mode) + { + return_Status_if_fail (__EfiRoot->Open (__EfiRoot, &new_file, file_name, OpenModeWrite, Attributes)); + } + else + { + return_Status_if_fail (__EfiRoot->Open (__EfiRoot, &new_file, file_name, OpenModeRead, Attributes)); + } + if (new_file == NULL) + { + err = 1; + errno = 1; + } + myfile->hfile = new_file; + + } + +#endif + + #ifdef __OS2__ APIRET rc; ULONG action; @@ -1573,6 +1664,12 @@ __PDPCLIB_API__ int fclose(FILE *stream) #ifdef __AMIGA__ Close(stream->hfile); #endif +#ifdef __EFI__ + if (stream->hfile != NULL) + { + ((EFI_FILE_PROTOCOL *)(stream->hfile))->Close(stream->hfile); + } +#endif #ifdef __OS2__ rc = DosClose(stream->hfile); #endif @@ -1688,6 +1785,13 @@ static void iread(FILE *stream, void *ptr, size_t toread, size_t *actualRead) #ifdef __AMIGA__ long tempRead; #endif +#ifdef __EFI__ + UINTN tempRead; + EFI_STATUS Status; +#ifdef __EFIBIOS__ + static EFI_LBA LBA = {1, 0}; +#endif +#endif #ifdef __OS2__ APIRET rc; ULONG tempRead; @@ -1713,6 +1817,102 @@ static void iread(FILE *stream, void *ptr, size_t toread, size_t *actualRead) *actualRead = tempRead; } #endif +#ifdef __EFI__ +#ifdef __EFIBIOS__ + tempRead = toread; + if (stream->block) + { + if (tempRead < bio_protocol->Media->BlockSize) + { + printf("sector size mismatch - freezing\n"); + printf("attempting to read %d\n", tempRead); + printf("but sector is %d\n", (int)bio_protocol->Media->BlockSize); + for (;;) ; + } + LBA.a = stream->sector; + Status = bio_protocol->ReadBlocks (bio_protocol, + bio_protocol->Media->MediaId, + LBA, + bio_protocol->Media->BlockSize, + ptr); + if (Status != EFI_SUCCESS) + { + *actualRead = 0; + stream->errorInd = 1; + } + else + { + *actualRead = tempRead; + } + } + else +#endif + { + if (stream->hfile == NULL) + { + UINTN Index; + EFI_INPUT_KEY input; + char c; + + for (tempRead = 0; tempRead < toread; tempRead++) + { + if ((__gST->BootServices->WaitForEvent (1, &__gST->ConIn->WaitForKey, &Index) != EFI_SUCCESS) + || (__gST->ConIn->ReadKeyStroke (__gST->ConIn, &input) != EFI_SUCCESS)) + { + *actualRead = 0; + stream->errorInd = 1; + break; + } + c = input.UnicodeChar; + if (c == '\r') + { + c = '\n'; + } + if ((c != '\b') || (tempRead > 0)) + { + printf("%c", c); + fflush(stdout); + } + *(((char *)ptr) + tempRead) = c; + if (c == '\n') + { + tempRead++; + break; + } + if (c == '\b') + { + if (tempRead > 0) + { + /* delete the backspace, unless we only have a backspace */ + tempRead--; + } + tempRead--; /* account for the previous character + - may go negative */ + } + } + if (!stream->errorInd) + { + *actualRead = tempRead; + } + } + else + { + Status = ((EFI_FILE_PROTOCOL *)(stream->hfile))->Read(stream->hfile, &tempRead, ptr); + if (Status != EFI_SUCCESS) + { + *actualRead = 0; + stream->errorInd = 1; + } + else + { + *actualRead = tempRead; + } + } + } + +#endif + + #ifdef __OS2__ rc = DosRead(stream->hfile, ptr, toread, &tempRead); if (rc != 0) @@ -2095,6 +2295,7 @@ static void iwrite(FILE *stream, #ifdef __EFI__ size_t tempWritten; static CHAR16 onechar[2] = {0, '\0'}; + EFI_STATUS Status; #endif #ifdef __AMIGA__ @@ -2137,16 +2338,33 @@ static void iwrite(FILE *stream, } #endif #ifdef __EFI__ - for (tempWritten = 0; tempWritten < towrite; tempWritten++) + if (stream->hfile == NULL) { - onechar[0] = *((unsigned char *)ptr + tempWritten); - if (onechar[0] == '\n') + for (tempWritten = 0; tempWritten < towrite; tempWritten++) { - onechar[0] = '\r'; + onechar[0] = *((unsigned char *)ptr + tempWritten); + if (onechar[0] == '\n') + { + onechar[0] = '\r'; + __gST->ConOut->OutputString(__gST->ConOut, onechar); + onechar[0] = '\n'; + } __gST->ConOut->OutputString(__gST->ConOut, onechar); - onechar[0] = '\n'; } - __gST->ConOut->OutputString(__gST->ConOut, onechar); + } + else + { + tempWritten = towrite; + Status = ((EFI_FILE_PROTOCOL *)(stream->hfile))->Write(stream->hfile, &tempWritten, ptr); + if (Status != EFI_SUCCESS) + { + *actualWritten = 0; + stream->errorInd = 1; + } + else + { + *actualWritten = tempWritten; + } } #endif *actualWritten = tempWritten; @@ -3533,6 +3751,10 @@ __PDPCLIB_API__ int fseek(FILE *stream, long int offset, int whence) #ifdef __AMIGA__ long retpos; #endif +#ifdef __EFI__ + UINT64 Position; + EFI_STATUS Status; +#endif #ifdef __OS2__ ULONG retpos; APIRET rc; @@ -3560,11 +3782,6 @@ __PDPCLIB_API__ int fseek(FILE *stream, long int offset, int whence) newpos = oldpos + offset; } - /*printf ("newpos: %ld\n", newpos); - printf ("bufStartR: %ld\n", stream->bufStartR); - printf ("endbuf: %ld\n", stream->endbuf); - printf ("fbuf: %ld\n", stream->fbuf);*/ - if (whence == SEEK_END) { char buf[1000]; @@ -3615,6 +3832,38 @@ __PDPCLIB_API__ int fseek(FILE *stream, long int offset, int whence) stream->bufStartR = newpos; } #endif +#ifdef __EFI__ +#ifdef __EFIBIOS__ + if (stream->block) + { + stream->sector = newpos / 512; + } + else + { +#endif + Position.a = newpos; + Status = ((EFI_FILE_PROTOCOL *)(stream->hfile))->SetPosition(stream->hfile, Position); + if (Status != EFI_SUCCESS) + { + return (-1); + } +#ifdef __EFIBIOS__ + } +#endif + stream->endbuf = stream->fbuf + stream->szfbuf; + if (stream->mode == __READ_MODE) + { + stream->upto = stream->endbuf; + stream->bufStartR = newpos - stream->szfbuf; + } + else + { + stream->upto = stream->fbuf; + stream->bufStartR = newpos; + } +#endif + + #ifdef __OS2__ rc = DosSetFilePtr(stream->hfile, newpos, FILE_BEGIN, &retpos); if ((rc != 0) || (retpos != newpos)) diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/stdio.h b/app/src/main/cpp/pdpclib/armeabi-v7a/stdio.h index 085bc00..67b3a02 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/stdio.h +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/stdio.h @@ -18,7 +18,9 @@ #ifndef __SIZE_T_DEFINED #define __SIZE_T_DEFINED -#if (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ +#if defined(__64BIT__) +typedef unsigned long long size_t; +#elif (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ || defined(__CMS__) || defined(__VSE__) || defined(__SMALLERC__) \ || defined(__ARM__) || defined(__gnu_linux__) || defined(__PDOS386__) \ || defined(__SZ4__)) @@ -63,11 +65,15 @@ typedef struct #elif (defined(__MSDOS__) || defined(__DOS__) || defined(__POWERC) \ || defined(__SMALLERC__)) int hfile; /* dos file handle */ -#elif defined(__WIN32__) || defined(__AMIGA__) +#elif defined(__WIN32__) || defined(__AMIGA__) || defined(__EFI__) void *hfile; -#elif defined(__gnu_linux__) || defined(__ARM__) || defined(__EFI__) +#elif defined(__gnu_linux__) || defined(__ARM__) int hfile; #endif +#if defined(__EFIBIOS__) + int block; + unsigned long sector; +#endif #if (defined(__MVS__) || defined(__CMS__) || defined(__VSE__)) void *hfile; void *asmbuf; diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/stdlib.c b/app/src/main/cpp/pdpclib/armeabi-v7a/stdlib.c index a7ba1cd..97987d4 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/stdlib.c +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/stdlib.c @@ -116,8 +116,11 @@ __PDPCLIB_API__ void *malloc(size_t size) #ifdef __EFI__ size_t *x = NULL; - __gBS->AllocPool(EfiLoaderData, size + sizeof(size_t), (void *)&x); - if (x == NULL) return (NULL); + if (__gBS->AllocatePool(EfiLoaderData, size + sizeof(size_t), (void **)&x) + != EFI_SUCCESS) + { + return (NULL); + } *x = size; return (x + 1); #endif diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/stdlib.h b/app/src/main/cpp/pdpclib/armeabi-v7a/stdlib.h index 7161bc2..c4a51b0 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/stdlib.h +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/stdlib.h @@ -15,7 +15,9 @@ #ifndef __SIZE_T_DEFINED #define __SIZE_T_DEFINED -#if (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ +#if defined(__64BIT__) +typedef unsigned long long size_t; +#elif (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ || defined(__CMS__) || defined(__VSE__) || defined(__SMALLERC__) \ || defined(__ARM__)|| defined(__gnu_linux__) || defined(__PDOS386__) \ || defined(__SZ4__)) diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/string.h b/app/src/main/cpp/pdpclib/armeabi-v7a/string.h index da60dce..81f3f76 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/string.h +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/string.h @@ -15,7 +15,9 @@ #ifndef __SIZE_T_DEFINED #define __SIZE_T_DEFINED -#if (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ +#if defined(__64BIT__) +typedef unsigned long long size_t; +#elif (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ || defined(__CMS__) || defined(__VSE__) || defined(__SMALLERC__) \ || defined(__ARM__) || defined(__gnu_linux__) || defined(__PDOS386__) \ || defined(__SZ4__)) diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/time.c b/app/src/main/cpp/pdpclib/armeabi-v7a/time.c index 4aa2177..a7f5ff1 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/time.c +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/time.c @@ -173,7 +173,7 @@ __PDPCLIB_API__ time_t time(time_t *timer) #elif defined(__ARM__) tt = __time(); #elif defined(__gnu_linux__) - tt = __time(NULL); + __time(&tt); #elif !defined(__WIN32__) && !defined(__AMIGA__) { diff --git a/app/src/main/cpp/pdpclib/armeabi-v7a/time.h b/app/src/main/cpp/pdpclib/armeabi-v7a/time.h index 782c38d..149c92a 100644 --- a/app/src/main/cpp/pdpclib/armeabi-v7a/time.h +++ b/app/src/main/cpp/pdpclib/armeabi-v7a/time.h @@ -20,7 +20,9 @@ typedef unsigned int clock_t; #ifndef __SIZE_T_DEFINED #define __SIZE_T_DEFINED -#if (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ +#if defined(__64BIT__) +typedef unsigned long long size_t; +#elif (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ || defined(__CMS__) || defined(__VSE__) || defined(__SMALLERC__) \ || defined(__ARM__) || defined(__gnu_linux__) || defined(__PDOS386__) \ || defined(__SZ4__)) diff --git a/app/src/main/cpp/pdpclib/x86/linstart.c b/app/src/main/cpp/pdpclib/x86/linstart.c old mode 100644 new mode 100755 index ea3d2ba..184f22a --- a/app/src/main/cpp/pdpclib/x86/linstart.c +++ b/app/src/main/cpp/pdpclib/x86/linstart.c @@ -1,96 +1,111 @@ -/* Startup code for Linux */ -/* written by Paul Edwards */ -/* released to the public domain */ - -#include "errno.h" -#include "stddef.h" - -/* malloc calls get this */ -static char membuf[31000000]; -static char *newmembuf = membuf; - -extern int __start(int argc, char **argv); -extern int __exita(int rc); - -#ifdef NEED_MPROTECT -extern int __mprotect(void *buf, size_t len, int prot); - -#define PROT_READ 1 -#define PROT_WRITE 2 -#define PROT_EXEC 4 -#endif - -/* We can get away with a minimal startup code, plus make it - a C program. There is no return address. Instead, on the - stack is a count, followed by all the parameters as pointers */ - -int _start(char *p) -{ - int rc; - -#ifdef NEED_MPROTECT - /* make malloced memory executable */ - /* most environments already make the memory executable */ - /* but some certainly don't */ - /* there doesn't appear to be a syscall to get the page size to - ensure page alignment (as required), and I read that some - environments have 4k page sizes but mprotect requires 16k - alignment. So for now we'll just go with 16k */ - size_t blksize = 16 * 1024; - size_t numblks; - - newmembuf = membuf + blksize; /* could waste memory here */ - newmembuf = newmembuf - (unsigned int)newmembuf % blksize; - numblks = sizeof membuf / blksize; - numblks -= 2; /* if already aligned, we wasted an extra block */ - rc = __mprotect(newmembuf, - numblks * blksize, - PROT_READ | PROT_WRITE | PROT_EXEC); - if (rc != 0) return (rc); -#endif - - /* I don't know what the official rules for ARM are, but - looking at the stack on entry showed that this code - would work */ -#ifdef __ARM__ - -#if defined(__UNOPT__) - rc = __start(*(int *)(&p + 5), &p + 6); -#else - rc = __start(*(int *)(&p + 6), &p + 7); -#endif - -#else - rc = __start(*(int *)(&p - 1), &p); -#endif - __exita(rc); - return (rc); -} - - -void *__allocmem(size_t size) -{ - return (newmembuf); -} - - -#if defined(__WATCOMC__) - -#define CTYP __cdecl - -/* this is invoked by long double manipulations - in stdio.c and needs to be done properly */ - -int CTYP _CHP(void) -{ - return (0); -} - -/* don't know what these are */ - -void CTYP cstart_(void) { return; } -void CTYP _argc(void) { return; } -void CTYP argc(void) { return; } -void CTYP _8087(void) { return; } - -#endif +/* Startup code for Linux */ +/* written by Paul Edwards */ +/* released to the public domain */ + +#include "errno.h" +#include "stddef.h" + +/* malloc calls get this */ +static char membuf[31000000]; +static char *newmembuf = membuf; + +extern int __start(int argc, char **argv); +extern int __exita(int rc); + +#ifdef NEED_MPROTECT +extern int __mprotect(void *buf, size_t len, int prot); + +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 +#endif + +/* We can get away with a minimal startup code, plus make it + a C program. There is no return address. Instead, on the + stack is a count, followed by all the parameters as pointers */ + +int _start(char *p) +{ + int rc; + +#ifdef NEED_MPROTECT + /* make malloced memory executable */ + /* most environments already make the memory executable */ + /* but some certainly don't */ + /* there doesn't appear to be a syscall to get the page size to + ensure page alignment (as required), and I read that some + environments have 4k page sizes but mprotect requires 16k + alignment. So for now we'll just go with 16k */ + size_t blksize = 16 * 1024; + size_t numblks; + + newmembuf = membuf + blksize; /* could waste memory here */ + newmembuf = newmembuf - (unsigned int)newmembuf % blksize; + numblks = sizeof membuf / blksize; + numblks -= 2; /* if already aligned, we wasted an extra block */ + rc = __mprotect(newmembuf, + numblks * blksize, + PROT_READ | PROT_WRITE | PROT_EXEC); + if (rc != 0) return (rc); +#endif + + /* I don't know what the official rules for ARM are, but + looking at the stack on entry showed that this code + would work */ +#ifdef __ARM__ + +#if defined(__UNOPT__) + rc = __start(*(int *)(&p + 5), &p + 6); +#else + rc = __start(*(int *)(&p + 6), &p + 7); +#endif + +/* Note that a problem with this stack manipulation was found when + built with clang with optimization on. clang correctly determines + that it is undefined behavior (this sort of stack manipulation is), + but instead of doing what the programmer clearly intended to do + (ie the result you get without optimization), it decides to silently + drop the first parameter and pass whatever rubbish is on the stack + as argc. And they don't see anything wrong with that! + https://github.com/llvm/llvm-project/issues/61112 + I don't consider my code to be wrong (although it is obviously not + portable - I'm writing a C library, not a C program), so if you wish + to use clang, then switch off optimization. Otherwise use a better + compiler, not one "supported" by jackasses on the internet who have + no concept of the spirit of C. +*/ + +#else + rc = __start(*(int *)(&p - 1), &p); +#endif + __exita(rc); + return (rc); +} + + +void *__allocmem(size_t size) +{ + return (newmembuf); +} + + +#if defined(__WATCOMC__) + +#define CTYP __cdecl + +/* this is invoked by long double manipulations + in stdio.c and needs to be done properly */ + +int CTYP _CHP(void) +{ + return (0); +} + +/* don't know what these are */ + +void CTYP cstart_(void) { return; } +void CTYP _argc(void) { return; } +void CTYP argc(void) { return; } +void CTYP _8087(void) { return; } + +#endif diff --git a/app/src/main/cpp/pdpclib/x86/linsupa.asm b/app/src/main/cpp/pdpclib/x86/linsupa.asm index 9e69ede..02043dc 100755 --- a/app/src/main/cpp/pdpclib/x86/linsupa.asm +++ b/app/src/main/cpp/pdpclib/x86/linsupa.asm @@ -369,7 +369,7 @@ mov %esp, %ebp push %ebx push %ecx push %edx -# function code 125 = mprotet +# function code 125 = mprotect movl $125, %eax # start movl 8(%ebp), %ebx diff --git a/app/src/main/cpp/pdpclib/x86/setjmp.c b/app/src/main/cpp/pdpclib/x86/setjmp.c index cdd321e..1508cdf 100644 --- a/app/src/main/cpp/pdpclib/x86/setjmp.c +++ b/app/src/main/cpp/pdpclib/x86/setjmp.c @@ -22,6 +22,10 @@ extern int CTYP __setj(jmp_buf env); extern int CTYP __longj(void *); +#ifdef __64BIT__ +#undef setjmp +#endif + #ifdef __MSC__ __PDPCLIB_API__ int setjmp(jmp_buf env) #else diff --git a/app/src/main/cpp/pdpclib/x86/setjmp.h b/app/src/main/cpp/pdpclib/x86/setjmp.h index d9313bf..601e559 100644 --- a/app/src/main/cpp/pdpclib/x86/setjmp.h +++ b/app/src/main/cpp/pdpclib/x86/setjmp.h @@ -14,7 +14,11 @@ #define __SETJMP_INCLUDED typedef struct { -#if defined(__MVS__) || defined(__CMS__) || defined(__VSE__) +#if defined(__64BIT__) + long long retval; + long long retaddr; + long long regs[10]; +#elif defined(__MVS__) || defined(__CMS__) || defined(__VSE__) int regs[15]; #elif defined(__AMIGA__) long a0; @@ -71,14 +75,24 @@ typedef struct { #else #error unknown system in setjmp.h #endif +#ifndef __64BIT__ int retval; +#endif } jmp_buf[1]; void longjmp(jmp_buf env, int val); -#ifdef __MSC__ +#if defined(__64BIT__) +#define setjmp(x) __setj(x) +int __setj(jmp_buf env); + +#elif defined(__MSC__) int setjmp(jmp_buf env); +#elif defined(__EFI__) +#define setjmp(x) __setj(x) +int __setj(jmp_buf env); + #elif defined(__ARM__) || defined(__ARMGEN__) /* it appears that gcc has _setjmp as a known keyword which is causing issues on ARM, so we change the name */ diff --git a/app/src/main/cpp/pdpclib/x86/start.c b/app/src/main/cpp/pdpclib/x86/start.c index 45b0256..e5a8e65 100644 --- a/app/src/main/cpp/pdpclib/x86/start.c +++ b/app/src/main/cpp/pdpclib/x86/start.c @@ -258,6 +258,7 @@ void *DOSBase; #if defined(__EFI__) #include "efi.h" +extern EFI_FILE_PROTOCOL *__EfiRoot; #endif #if defined(__PDOS386__) @@ -366,12 +367,10 @@ int __start(char *plist, char *pgmname, char **eplist) int __start(char *p, char *pgmname, char *ep) #elif defined(__MVS__) int __start(char *p, char *pgmname, int tso) -#elif defined(__gnu_linux__) +#elif defined(__gnu_linux__) || defined(__EFI__) int __start(int argc, char **argv) #elif defined(__AMIGA__) int __start(unsigned long cmdlen, char *p, void *pdosbase) -#elif defined(__EFI__) -int __start(void) #elif defined(__SMALLERC__) __PDPCLIB_API__ int CTYP __start(char *p, unsigned short osver) #else @@ -380,14 +379,11 @@ __PDPCLIB_API__ int CTYP __start(char *p) { #ifdef __CMS__ char *p; -#endif -#ifdef __EFI__ - char *p = ""; #endif int x; int oldglobrc = globrc; jmp_buf oldjb; -#if !defined(__gnu_linux__) +#if !defined(__gnu_linux__) && !defined(__EFI__) int argc; static char *argv[MAXPARMS + 1]; #endif @@ -484,7 +480,7 @@ __PDPCLIB_API__ int CTYP __start(char *p) __stdin->hfile = Input(); __stdout->hfile = Output(); __stderr->hfile = Output(); -#else +#elif !defined(__EFI__) /* EFI will leave everything as NULL */ __stdin->hfile = 0; __stdout->hfile = 1; __stderr->hfile = 2; @@ -1159,7 +1155,7 @@ __PDPCLIB_API__ int CTYP __start(char *p) } } #endif -#if !defined(__gnu_linux__) +#if !defined(__gnu_linux__) && !defined(__EFI__) while (*p == ' ') { p++; @@ -1255,7 +1251,9 @@ __PDPCLIB_API__ int CTYP __start(char *p) #endif if (runnum == 1) { +#if !defined(__64BIT__) __exit(rc); +#endif } runnum--; return (rc); @@ -1285,6 +1283,10 @@ void __exit(int status) so that we don't get called again */ runnum--; /* and we can't go through another longjmp either */ + /* really? 64 bit needs a longjmp. */ +#ifdef __64BIT__ + longjmp(jb, status); +#endif return; } globrc = status; @@ -1350,6 +1352,14 @@ __PDPCLIB_API__ void _c_exit(void) SetConsoleMode(__stdout->hfile, stdout_dw); #endif +#if defined(__EFI__) + if (__EfiRoot != NULL) + { + __EfiRoot->Close(__EfiRoot); + __EfiRoot = NULL; + } +#endif + #if defined(__PDOS386__) PosSetDeviceInformation(0, stdin_dw); #endif diff --git a/app/src/main/cpp/pdpclib/x86/stdarg.h b/app/src/main/cpp/pdpclib/x86/stdarg.h index 342ea40..848cae9 100644 --- a/app/src/main/cpp/pdpclib/x86/stdarg.h +++ b/app/src/main/cpp/pdpclib/x86/stdarg.h @@ -51,8 +51,13 @@ typedef char * va_list; #define va_arg(ap, type) *(type far *)(ap += sizeof(type), ap - sizeof(type)) #else #define va_start(ap, parmN) ap = (char *)&parmN + sizeof(parmN) +#ifdef __64BIT__ +#define va_arg(ap, type) *(type *)(ap += (sizeof(type) < 8) ? 8 : sizeof(type),\ + ap - ((sizeof(type) < 8) ? 8 : sizeof(type))) +#else #define va_arg(ap, type) *(type *)(ap += sizeof(type), ap - sizeof(type)) #endif +#endif #define va_end(ap) ap = (char *)0 #endif diff --git a/app/src/main/cpp/pdpclib/x86/stddef.h b/app/src/main/cpp/pdpclib/x86/stddef.h index 7a534ab..c956ec8 100644 --- a/app/src/main/cpp/pdpclib/x86/stddef.h +++ b/app/src/main/cpp/pdpclib/x86/stddef.h @@ -13,10 +13,17 @@ #ifndef __STDDEF_INCLUDED #define __STDDEF_INCLUDED +#if defined(__64BIT__) +typedef long long ptrdiff_t; +#else typedef int ptrdiff_t; +#endif + #ifndef __SIZE_T_DEFINED #define __SIZE_T_DEFINED -#if (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ +#if defined(__64BIT__) +typedef unsigned long long size_t; +#elif (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ || defined(__CMS__) || defined(__VSE__) || defined(__SMALLERC__) \ || defined(__ARM__) || defined(__gnu_linux__) || defined(__PDOS386__) \ || defined(__SZ4__)) diff --git a/app/src/main/cpp/pdpclib/x86/stdio.c b/app/src/main/cpp/pdpclib/x86/stdio.c index f880d07..7b80eaa 100644 --- a/app/src/main/cpp/pdpclib/x86/stdio.c +++ b/app/src/main/cpp/pdpclib/x86/stdio.c @@ -118,6 +118,10 @@ extern void CTYP __rename(const char *old, const char *newnam); #ifdef __EFI__ #include "efi.h" +EFI_FILE_PROTOCOL *__EfiRoot = NULL; +#ifdef __EFIBIOS__ +static EFI_BLOCK_IO_PROTOCOL *bio_protocol = NULL; +#endif #endif #ifdef __OS2__ @@ -258,11 +262,11 @@ static const char *fnm; static const char *modus; static int modeType; -__PDPCLIB_API__ FILE **__gtin() +__PDPCLIB_API__ FILE **__gtin(void) { return(&__stdin_ptr); } -__PDPCLIB_API__ FILE **__gtout() +__PDPCLIB_API__ FILE **__gtout(void) { return(&__stdout_ptr); } -__PDPCLIB_API__ FILE **__gterr() +__PDPCLIB_API__ FILE **__gterr(void) { return(&__stderr_ptr); } #if defined(__WIN32__) && !defined(__STATIC__) @@ -754,6 +758,93 @@ static void osfopen(void) errno = 1; } #endif + + +#ifdef __EFI__ + +#define return_Status_if_fail(func) do { if ((Status = (func))) { err = 1; \ + errno = Status; return; }} while (0) + + int mode; + EFI_STATUS Status = EFI_SUCCESS; + static EFI_GUID li_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + EFI_LOADED_IMAGE_PROTOCOL *li_protocol; + static EFI_GUID sfs_protocol_guid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *sfs_protocol; + UINT64 OpenModeRead = {0x3, 0}; /* Read+Write */ + UINT64 OpenModeWrite = {0x3, 0x80000000}; /* Read+Write+Create */ + EFI_FILE_PROTOCOL *new_file; + static UINT64 Attributes = {0, 0}; + CHAR16 file_name[FILENAME_MAX]; + int x; + static EFI_GUID block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID; + + if (__EfiRoot == NULL) + { + return_Status_if_fail (__gBS->HandleProtocol (__gIH, &li_guid, (void **)&li_protocol)); + return_Status_if_fail (__gBS->HandleProtocol (li_protocol->DeviceHandle, &sfs_protocol_guid, (void **)&sfs_protocol)); + return_Status_if_fail (sfs_protocol->OpenVolume (sfs_protocol, &__EfiRoot)); +#ifdef __EFIBIOS__ + return_Status_if_fail (__gBS->HandleProtocol (li_protocol->DeviceHandle, &block_io_guid, (void **)&bio_protocol)); +#endif + } + + if ((modeType == 1) || (modeType == 4) + || (modeType == 7) || (modeType == 10)) + { + mode = 0; /* read */ + } + else if ((modeType == 2) || (modeType == 5) + || (modeType == 8) || (modeType == 11)) + { + mode = 1; /* write */ + } + else + { + mode = 2; /* append or otherwise unsupported */ + /* because we don't have append mode implemented + at the moment, just return with an + error immediately */ + err = 1; + errno = 2; + return; + } + +#ifdef __EFIBIOS__ + myfile->block = 0; + if (strcmp(fnm, "!BOOT") == 0) + { + myfile->block = 1; + myfile->sector = 0; + } + else +#endif + { + x = 0; + do { + file_name[x] = (CHAR16)fnm[x]; + } while (fnm[x++] != 0); + + if (mode) + { + return_Status_if_fail (__EfiRoot->Open (__EfiRoot, &new_file, file_name, OpenModeWrite, Attributes)); + } + else + { + return_Status_if_fail (__EfiRoot->Open (__EfiRoot, &new_file, file_name, OpenModeRead, Attributes)); + } + if (new_file == NULL) + { + err = 1; + errno = 1; + } + myfile->hfile = new_file; + + } + +#endif + + #ifdef __OS2__ APIRET rc; ULONG action; @@ -1573,6 +1664,12 @@ __PDPCLIB_API__ int fclose(FILE *stream) #ifdef __AMIGA__ Close(stream->hfile); #endif +#ifdef __EFI__ + if (stream->hfile != NULL) + { + ((EFI_FILE_PROTOCOL *)(stream->hfile))->Close(stream->hfile); + } +#endif #ifdef __OS2__ rc = DosClose(stream->hfile); #endif @@ -1688,6 +1785,13 @@ static void iread(FILE *stream, void *ptr, size_t toread, size_t *actualRead) #ifdef __AMIGA__ long tempRead; #endif +#ifdef __EFI__ + UINTN tempRead; + EFI_STATUS Status; +#ifdef __EFIBIOS__ + static EFI_LBA LBA = {1, 0}; +#endif +#endif #ifdef __OS2__ APIRET rc; ULONG tempRead; @@ -1713,6 +1817,102 @@ static void iread(FILE *stream, void *ptr, size_t toread, size_t *actualRead) *actualRead = tempRead; } #endif +#ifdef __EFI__ +#ifdef __EFIBIOS__ + tempRead = toread; + if (stream->block) + { + if (tempRead < bio_protocol->Media->BlockSize) + { + printf("sector size mismatch - freezing\n"); + printf("attempting to read %d\n", tempRead); + printf("but sector is %d\n", (int)bio_protocol->Media->BlockSize); + for (;;) ; + } + LBA.a = stream->sector; + Status = bio_protocol->ReadBlocks (bio_protocol, + bio_protocol->Media->MediaId, + LBA, + bio_protocol->Media->BlockSize, + ptr); + if (Status != EFI_SUCCESS) + { + *actualRead = 0; + stream->errorInd = 1; + } + else + { + *actualRead = tempRead; + } + } + else +#endif + { + if (stream->hfile == NULL) + { + UINTN Index; + EFI_INPUT_KEY input; + char c; + + for (tempRead = 0; tempRead < toread; tempRead++) + { + if ((__gST->BootServices->WaitForEvent (1, &__gST->ConIn->WaitForKey, &Index) != EFI_SUCCESS) + || (__gST->ConIn->ReadKeyStroke (__gST->ConIn, &input) != EFI_SUCCESS)) + { + *actualRead = 0; + stream->errorInd = 1; + break; + } + c = input.UnicodeChar; + if (c == '\r') + { + c = '\n'; + } + if ((c != '\b') || (tempRead > 0)) + { + printf("%c", c); + fflush(stdout); + } + *(((char *)ptr) + tempRead) = c; + if (c == '\n') + { + tempRead++; + break; + } + if (c == '\b') + { + if (tempRead > 0) + { + /* delete the backspace, unless we only have a backspace */ + tempRead--; + } + tempRead--; /* account for the previous character + - may go negative */ + } + } + if (!stream->errorInd) + { + *actualRead = tempRead; + } + } + else + { + Status = ((EFI_FILE_PROTOCOL *)(stream->hfile))->Read(stream->hfile, &tempRead, ptr); + if (Status != EFI_SUCCESS) + { + *actualRead = 0; + stream->errorInd = 1; + } + else + { + *actualRead = tempRead; + } + } + } + +#endif + + #ifdef __OS2__ rc = DosRead(stream->hfile, ptr, toread, &tempRead); if (rc != 0) @@ -2095,6 +2295,7 @@ static void iwrite(FILE *stream, #ifdef __EFI__ size_t tempWritten; static CHAR16 onechar[2] = {0, '\0'}; + EFI_STATUS Status; #endif #ifdef __AMIGA__ @@ -2137,16 +2338,33 @@ static void iwrite(FILE *stream, } #endif #ifdef __EFI__ - for (tempWritten = 0; tempWritten < towrite; tempWritten++) + if (stream->hfile == NULL) { - onechar[0] = *((unsigned char *)ptr + tempWritten); - if (onechar[0] == '\n') + for (tempWritten = 0; tempWritten < towrite; tempWritten++) { - onechar[0] = '\r'; + onechar[0] = *((unsigned char *)ptr + tempWritten); + if (onechar[0] == '\n') + { + onechar[0] = '\r'; + __gST->ConOut->OutputString(__gST->ConOut, onechar); + onechar[0] = '\n'; + } __gST->ConOut->OutputString(__gST->ConOut, onechar); - onechar[0] = '\n'; } - __gST->ConOut->OutputString(__gST->ConOut, onechar); + } + else + { + tempWritten = towrite; + Status = ((EFI_FILE_PROTOCOL *)(stream->hfile))->Write(stream->hfile, &tempWritten, ptr); + if (Status != EFI_SUCCESS) + { + *actualWritten = 0; + stream->errorInd = 1; + } + else + { + *actualWritten = tempWritten; + } } #endif *actualWritten = tempWritten; @@ -3533,6 +3751,10 @@ __PDPCLIB_API__ int fseek(FILE *stream, long int offset, int whence) #ifdef __AMIGA__ long retpos; #endif +#ifdef __EFI__ + UINT64 Position; + EFI_STATUS Status; +#endif #ifdef __OS2__ ULONG retpos; APIRET rc; @@ -3610,6 +3832,38 @@ __PDPCLIB_API__ int fseek(FILE *stream, long int offset, int whence) stream->bufStartR = newpos; } #endif +#ifdef __EFI__ +#ifdef __EFIBIOS__ + if (stream->block) + { + stream->sector = newpos / 512; + } + else + { +#endif + Position.a = newpos; + Status = ((EFI_FILE_PROTOCOL *)(stream->hfile))->SetPosition(stream->hfile, Position); + if (Status != EFI_SUCCESS) + { + return (-1); + } +#ifdef __EFIBIOS__ + } +#endif + stream->endbuf = stream->fbuf + stream->szfbuf; + if (stream->mode == __READ_MODE) + { + stream->upto = stream->endbuf; + stream->bufStartR = newpos - stream->szfbuf; + } + else + { + stream->upto = stream->fbuf; + stream->bufStartR = newpos; + } +#endif + + #ifdef __OS2__ rc = DosSetFilePtr(stream->hfile, newpos, FILE_BEGIN, &retpos); if ((rc != 0) || (retpos != newpos)) diff --git a/app/src/main/cpp/pdpclib/x86/stdio.h b/app/src/main/cpp/pdpclib/x86/stdio.h index 085bc00..67b3a02 100644 --- a/app/src/main/cpp/pdpclib/x86/stdio.h +++ b/app/src/main/cpp/pdpclib/x86/stdio.h @@ -18,7 +18,9 @@ #ifndef __SIZE_T_DEFINED #define __SIZE_T_DEFINED -#if (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ +#if defined(__64BIT__) +typedef unsigned long long size_t; +#elif (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ || defined(__CMS__) || defined(__VSE__) || defined(__SMALLERC__) \ || defined(__ARM__) || defined(__gnu_linux__) || defined(__PDOS386__) \ || defined(__SZ4__)) @@ -63,11 +65,15 @@ typedef struct #elif (defined(__MSDOS__) || defined(__DOS__) || defined(__POWERC) \ || defined(__SMALLERC__)) int hfile; /* dos file handle */ -#elif defined(__WIN32__) || defined(__AMIGA__) +#elif defined(__WIN32__) || defined(__AMIGA__) || defined(__EFI__) void *hfile; -#elif defined(__gnu_linux__) || defined(__ARM__) || defined(__EFI__) +#elif defined(__gnu_linux__) || defined(__ARM__) int hfile; #endif +#if defined(__EFIBIOS__) + int block; + unsigned long sector; +#endif #if (defined(__MVS__) || defined(__CMS__) || defined(__VSE__)) void *hfile; void *asmbuf; diff --git a/app/src/main/cpp/pdpclib/x86/stdlib.c b/app/src/main/cpp/pdpclib/x86/stdlib.c index a7ba1cd..97987d4 100644 --- a/app/src/main/cpp/pdpclib/x86/stdlib.c +++ b/app/src/main/cpp/pdpclib/x86/stdlib.c @@ -116,8 +116,11 @@ __PDPCLIB_API__ void *malloc(size_t size) #ifdef __EFI__ size_t *x = NULL; - __gBS->AllocPool(EfiLoaderData, size + sizeof(size_t), (void *)&x); - if (x == NULL) return (NULL); + if (__gBS->AllocatePool(EfiLoaderData, size + sizeof(size_t), (void **)&x) + != EFI_SUCCESS) + { + return (NULL); + } *x = size; return (x + 1); #endif diff --git a/app/src/main/cpp/pdpclib/x86/stdlib.h b/app/src/main/cpp/pdpclib/x86/stdlib.h index 7161bc2..c4a51b0 100644 --- a/app/src/main/cpp/pdpclib/x86/stdlib.h +++ b/app/src/main/cpp/pdpclib/x86/stdlib.h @@ -15,7 +15,9 @@ #ifndef __SIZE_T_DEFINED #define __SIZE_T_DEFINED -#if (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ +#if defined(__64BIT__) +typedef unsigned long long size_t; +#elif (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ || defined(__CMS__) || defined(__VSE__) || defined(__SMALLERC__) \ || defined(__ARM__)|| defined(__gnu_linux__) || defined(__PDOS386__) \ || defined(__SZ4__)) diff --git a/app/src/main/cpp/pdpclib/x86/string.h b/app/src/main/cpp/pdpclib/x86/string.h index da60dce..81f3f76 100644 --- a/app/src/main/cpp/pdpclib/x86/string.h +++ b/app/src/main/cpp/pdpclib/x86/string.h @@ -15,7 +15,9 @@ #ifndef __SIZE_T_DEFINED #define __SIZE_T_DEFINED -#if (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ +#if defined(__64BIT__) +typedef unsigned long long size_t; +#elif (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ || defined(__CMS__) || defined(__VSE__) || defined(__SMALLERC__) \ || defined(__ARM__) || defined(__gnu_linux__) || defined(__PDOS386__) \ || defined(__SZ4__)) diff --git a/app/src/main/cpp/pdpclib/x86/time.c b/app/src/main/cpp/pdpclib/x86/time.c index 4aa2177..a7f5ff1 100644 --- a/app/src/main/cpp/pdpclib/x86/time.c +++ b/app/src/main/cpp/pdpclib/x86/time.c @@ -173,7 +173,7 @@ __PDPCLIB_API__ time_t time(time_t *timer) #elif defined(__ARM__) tt = __time(); #elif defined(__gnu_linux__) - tt = __time(NULL); + __time(&tt); #elif !defined(__WIN32__) && !defined(__AMIGA__) { diff --git a/app/src/main/cpp/pdpclib/x86/time.h b/app/src/main/cpp/pdpclib/x86/time.h index 782c38d..149c92a 100644 --- a/app/src/main/cpp/pdpclib/x86/time.h +++ b/app/src/main/cpp/pdpclib/x86/time.h @@ -20,7 +20,9 @@ typedef unsigned int clock_t; #ifndef __SIZE_T_DEFINED #define __SIZE_T_DEFINED -#if (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ +#if defined(__64BIT__) +typedef unsigned long long size_t; +#elif (defined(__OS2__) || defined(__32BIT__) || defined(__MVS__) \ || defined(__CMS__) || defined(__VSE__) || defined(__SMALLERC__) \ || defined(__ARM__) || defined(__gnu_linux__) || defined(__PDOS386__) \ || defined(__SZ4__)) diff --git a/app/src/main/java/com/cod5/pdos_pdandro/MainActivity.kt b/app/src/main/java/com/cod5/pdos_pdandro/MainActivity.kt index 3f7e43f..70cf85d 100644 --- a/app/src/main/java/com/cod5/pdos_pdandro/MainActivity.kt +++ b/app/src/main/java/com/cod5/pdos_pdandro/MainActivity.kt @@ -722,7 +722,7 @@ class MainActivity : AppCompatActivity(), OnClickListener { }, 1000, 1000) } - /*private fun isEqual(is1: InputStream, is2: InputStream) : Boolean { + private fun isEqual(is1: InputStream, is2: InputStream) : Boolean { is1.use { src -> is2.use { dest -> var ch : Int @@ -734,7 +734,7 @@ class MainActivity : AppCompatActivity(), OnClickListener { } } return true; - }*/ + } /* copy files and run native executable */ fun init_app(dir: File) { diff --git a/app/src/main/res/raw/uc8086.vhd b/app/src/main/res/raw/uc8086.vhd index da7cdf7..7c79442 100644 Binary files a/app/src/main/res/raw/uc8086.vhd and b/app/src/main/res/raw/uc8086.vhd differ