diff --git a/polmon.cc b/polmon.cc index 3bc55bf..a11c3fe 100644 --- a/polmon.cc +++ b/polmon.cc @@ -224,20 +224,66 @@ void Status(uint8_t status) { : "ax", "bh", "dx", "cx", "di", "cc"); } +char toupper(char c) { + if (c >= 'a' && c <= 'z') { + return c - ('a' - 'A'); + } + return c; +} + +void tofatname(const char* name, char* fatname) { + for (int i = 0; i < 11; i++) { + if (*name == 0 || *name == '.') { + fatname[i] = ' '; + } else { + fatname[i] = toupper(*name++); + } + if (i == 7 && *name == '.') { + name++; + } + } +} + void LaunchFile(const char* name) { constexpr uint16_t kSegment = 0x200; constexpr uint16_t kAddress = 0x100; + constexpr uint16_t kHeaderAddress = (kSegment << 4); constexpr uint16_t kFlatAddress = (kSegment << 4) + kAddress; + constexpr uint8_t kTrampoline[] = { 0xe8, 0xfd, 0x00, 0xcb }; - asm volatile("mov %1, %%ax \n\t" - "push %%ax \n\t" - "mov %0, %%ax \n\t" - "push %%ax \n\t" - "mov $04, %%ah \n\t" - "int $0x80 \n\t" - "ljmp %2,%3" ::"rmi"(name), - "rmi"(kFlatAddress), "i"(kSegment), "i"(kAddress) - : "ax", "memory"); + char fatname[11]; + tofatname(name, fatname); + + auto* ptr = reinterpret_cast(kHeaderAddress); + memcpy(ptr, kTrampoline, sizeof(kTrampoline)); + + asm volatile("mov %1, %%ax \n\t" + "push %%ax \n\t" + "mov %0, %%ax \n\t" + "push %%ax \n\t" + "mov $04, %%ah \n\t" + "int $0x80 \n\t" + "add $4, %%sp \n\t" + "mov %2, %%ax \n\t" + "mov %%ax, %%ds \n\t" + "mov %%ax, %%es \n\t" + "cli \n\t" + "mov %%ax, %%ss \n\t" + "mov %3, %%ax \n\t" + "xchg %%ax, %%sp \n\t" + "sti \n\t" + "push %%ax \n\t" + "lcall %2,$0 \n\t" + "xor %%ax, %%ax \n\t" + "mov %%ax, %%ds \n\t" + "mov %%ax, %%es \n\t" + "cli \n\t" + "pop %%sp \n\t" + "mov %%ax, %%ss \n\t" + "sti" + :: "rmi"(fatname), + "rmi"(kFlatAddress), "i"(kSegment), "i"(kHeaderAddress) + : "ax", "bx", "cx", "dx", "memory"); } #if CTRLBREAK @@ -320,12 +366,13 @@ bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) { } else if (*ptr == 'r') { dump = false; ptr++; + while (*ptr == ' ') { + ptr++; + } int l = 0; for (; ptr[l]; l++) { } - if (l >= 11) { - LaunchFile(ptr); - } + LaunchFile(ptr); ptr += l; #endif // LAUNCH } else if (*ptr == 'w') { @@ -364,7 +411,7 @@ void polmon() { ClearScreen(); #if SHOWTITLE - puts("PolMon 0.2\r\n"); + puts("PolMon for Workgroups 3.1\r\n"); #endif // SHOWTITLE DisplayPrompt();