diff --git a/bin/loader.cpp b/bin/loader.cpp index eb53c83..5a747b5 100644 --- a/bin/loader.cpp +++ b/bin/loader.cpp @@ -254,6 +254,7 @@ uint32_t load(const char *file) return returnAddress; } +#if 0 void InitializeMPW(int argc, char **argv) { @@ -446,6 +447,28 @@ void InitializeMPW(int argc, char **argv) WriteLong(Memory, 0x0a06, 0xffffffff); + // todo -- expects high stack, low heap. + // the allocator currently works from the top down, + // so put stack at top of memory? + + // 0x0130 -- ApplLimit + WriteLong(Memory, 0x0130, Flags.ram - 1); + +} +#endif + +void GlobalInit() +{ + // todo -- move this somewhere better. + + // 0x031a - Lo3Bytes + WriteLong(Memory, 0x031a, 0x00ffffff); + // 0x0a02 - OneOne + WriteLong(Memory, 0x0a02, 0x00010001); + // 0x0a06 - MinusOne + WriteLong(Memory, 0x0a06, 0xffffffff); + + // todo -- expects high stack, low heap. // the allocator currently works from the top down, // so put stack at top of memory? @@ -695,12 +718,10 @@ int main(int argc, char **argv) uint32_t address = load(argv[0]); - InitializeMPW(argc, argv); + //InitializeMPW(argc, argv); + GlobalInit(); - MPW::Init(); - MPW::Trace = Flags.traceMPW; - ToolBox::Trace = Flags.traceToolBox; if (!Flags.stack) { @@ -736,12 +757,22 @@ int main(int argc, char **argv) cpuInitializeFromNewPC(address); MM::Init(Memory, MemorySize, HighWater); + + MPW::Init(argc, argv); + + + MPW::Trace = Flags.traceMPW; + ToolBox::Trace = Flags.traceToolBox; + if (Flags.traceCPU || Flags.traceMacsbug) { cpuSetInstructionLoggingFunc(InstructionLogger); } + + + for (;;) { uint32_t pc = cpuGetPC(); diff --git a/mpw/mpw.cpp b/mpw/mpw.cpp index adebc7e..52be834 100644 --- a/mpw/mpw.cpp +++ b/mpw/mpw.cpp @@ -10,18 +10,22 @@ #include #include - +#include #include #include #include +#include + namespace MPW { namespace Internal { // for dup counts, etc. std::vector FDTable; + uint32_t MacProgramInfo = 0; + } } @@ -78,7 +82,7 @@ namespace MPW } - void Init() + uint16_t Init(int argc, char **argv) { FDTable.resize(16); @@ -86,7 +90,211 @@ namespace MPW FDTable[STDOUT_FILENO] = 1; FDTable[STDERR_FILENO] = 1; - // todo -- should eventually set up the mpw environment. + + argv[0] = basename(argv[0]); + + + // 0x0910 CurApName + { + char str32[32]; + + char * name = argv[0]; + int l = strlen(name); + l = std::min(l, 32); + str32[0] = l; + std::memcpy(str32 + 1, name, l); + while (l < 32) str32[l++] = 0; + + std::memcpy(memoryPointer(0x0910), str32, 32); + } + + + uint32_t argvptr = 0; + uint32_t envptr = 0; + uint32_t ioptr = 0; + uint32_t devptr = 0; + uint32_t fptr = 0; + + uint16_t error; + + // create the argv-data. + { + uint32_t size = 0; + + size = 4 * (argc + 1); // argv data. + + for (int i = 0; i < argc; ++i) + { + int l = strlen(argv[i]) + 1; + if (l & 0x01) l++; + size += l; + } + + error = MM::Native::NewPtr(size, true, argvptr); + if (error) return error; + + + uint8_t *xptr = memoryPointer(argvptr); + uint32_t offset = 0; + + offset = 4 * (argc + 1); + + for (int i = 0; i < argc; ++i) + { + memoryWriteLong(argvptr + offset, argvptr + 4 * i); + + // just use strcat? + int l = strlen(argv[i]) + 1; + if (l & 0x01) l++; + + strcpy((char *)xptr + offset, argv[i]); + + offset += l; + } + + // null-terminate it. + memoryWriteLong(0, argvptr + 4 * argc); + + } + + // todo -- do the same for envp. + // scan the native environment for MPW-name variables? + // values are stored as key\0value\0, not key=value\0 + { + uint32_t size = 4; + error = MM::Native::NewPtr(size, true, envptr); + if (error) return error; + + memoryWriteLong(0, envptr); + } + + // ftable + { + // these are ftraps for emulated/native function ptrs. + uint32_t size = 6 * 4; + + error = MM::Native::NewPtr(size, true, fptr); + + if (error) return error; + + memoryWriteWord(fQuit, fptr + 0); + memoryWriteWord(0x4E75, fptr + 2); // rts + + memoryWriteWord(fAccess, fptr + 4); + memoryWriteWord(0x4E75, fptr + 6); // rts + + memoryWriteWord(fClose, fptr + 8); + memoryWriteWord(0x4E75, fptr + 10); // rts + + memoryWriteWord(fRead, fptr + 12); + memoryWriteWord(0x4E75, fptr + 14); // rts + + memoryWriteWord(fWrite, fptr + 16); + memoryWriteWord(0x4E75, fptr + 18); // rts + + memoryWriteWord(fIOCtl, fptr + 20); + memoryWriteWord(0x4E75, fptr + 22); // rts + + } + + + // dev table + { + uint32_t size = 0x78; + + error = MM::Native::NewPtr(size, true, devptr); + + if (error) return error; + + memoryWriteLong(0x46535953, devptr + 0); // 'FSYS' + memoryWriteLong(fptr + 4, devptr + 4); + memoryWriteLong(fptr + 8, devptr + 8); + memoryWriteLong(fptr + 12, devptr + 12); + memoryWriteLong(fptr + 16, devptr + 16); + memoryWriteLong(fptr + 20, devptr + 20); + + memoryWriteLong(0x45434f4e, devptr + 24); // 'ECON' -- not implemented. + memoryWriteLong(0x53595354, devptr + 48); // 'SYST' -- not implemented. + + } + + // io table. + { + + uint32_t size = 0x3c; + uint32_t ptr; + + error = MM::Native::NewPtr(size, true, ioptr); + + if (error) return error; + + ptr = ioptr; + // stdin + memoryWriteWord(0x0001, ptr + 0); // open flags (read) + memoryWriteWord(0x0000, ptr + 2); // os err + memoryWriteLong(devptr, ptr + 4); // -> 'FSYS' + memoryWriteLong(STDIN_FILENO, ptr + 8); // cookie + memoryWriteLong(0, ptr + 12); // transfer count. + memoryWriteLong(0, ptr + 16); // buffer + + ptr = ioptr + 20; + // stdout + memoryWriteWord(0x0002, ptr + 0); // open flags (write) + memoryWriteWord(0x0000, ptr + 2); // os err + memoryWriteLong(devptr, ptr + 4); // -> 'FSYS' + memoryWriteLong(STDOUT_FILENO, ptr + 8); // cookie + memoryWriteLong(0, ptr + 12); // transfer count. + memoryWriteLong(0, ptr + 16); // buffer + + ptr = ioptr + 40; + // stderr + memoryWriteWord(0x0002, ptr + 0); // open flags (write) + memoryWriteWord(0x0000, ptr + 2); // os err + memoryWriteLong(devptr, ptr + 4); // -> 'FSYS' + memoryWriteLong(STDERR_FILENO, ptr + 8); // cookie + memoryWriteLong(0, ptr + 12); // transfer count. + memoryWriteLong(0, ptr + 16); // buffer + + } + + + + uint32_t mpi = 0; + + error = MM::Native::NewPtr(8 + 0x30, true, mpi); + if (error) return error; + + MacProgramInfo = mpi + 8; + + memoryWriteLong(0x4d50474d, mpi); // 'MPGM' - magic + memoryWriteLong(mpi + 8, mpi + 4); + + memoryWriteLong(mpi, 0x0316); + + mpi += 8; + memoryWriteWord(0x5348, mpi + 0x00); // 'SH' - more magic + + memoryWriteLong(argc, mpi + 0x02); + memoryWriteLong(argvptr, mpi + 0x06); + memoryWriteLong(envptr, mpi + 0x0a); + + // 0x0e = exit code + + // ??? default fd table size? + memoryWriteWord(0x190, mpi + 0x1a); + + // io table - stdin/stdout/stderr + memoryWriteLong(ioptr, mpi + 0x1c); + + + return 0; + } + + uint32_t ExitStatus() + { + if (!MacProgramInfo) return -1; + + return memoryReadLong(MacProgramInfo + 0x0e); } diff --git a/mpw/mpw.h b/mpw/mpw.h index 313e244..ef55c43 100644 --- a/mpw/mpw.h +++ b/mpw/mpw.h @@ -93,7 +93,10 @@ namespace MPW { // should add argc/argv/envp... - void Init(); + uint16_t Init(int argc, char **argv); + + uint32_t ExitStatus(); + void dispatch(uint16_t trap);