From de41328677e664b2347ec2bea1f33deb4787518a Mon Sep 17 00:00:00 2001 From: Paul Mathieu Date: Mon, 29 Sep 2025 17:52:21 +0200 Subject: [PATCH] polmon: refactor jump & stdlib --- Makefile | 4 +- polmon.cc | 135 ++++++++++++++++++++++++++++-------------------------- stdlib.c | 31 +++++++++++++ 3 files changed, 102 insertions(+), 68 deletions(-) create mode 100644 stdlib.c diff --git a/Makefile b/Makefile index eb21e32..f48a8ec 100644 --- a/Makefile +++ b/Makefile @@ -31,8 +31,8 @@ fat12boot.elf: LDFLAGS += -T bootsect.ld fat12boot.bin: fat12boot.elf -polmon.elf: LDFLAGS += -T flat0600.ld -polmon.elf: polmon.o +polmon.elf: LDFLAGS += -T flat1000.ld +polmon.elf: polmon.o stdlib.o wozmon.o: polmon.cc diff --git a/polmon.cc b/polmon.cc index 76c3df2..4a5b166 100644 --- a/polmon.cc +++ b/polmon.cc @@ -1,4 +1,5 @@ #include +#include #ifndef WOZMON #define WOZMON 0 @@ -8,7 +9,7 @@ #define BACKSPACE 0 #define ASCIIDUMP 0 #define CLEARSCREENCMD 0 -#define FARCALL 0 +#define INT80H 0 #define SHOWTITLE 0 #define BOOTSTRAP 0 #endif // WOZMON @@ -25,8 +26,8 @@ #define CLEARSCREENCMD 1 #endif -#ifndef FARCALL -#define FARCALL 1 +#ifndef INT80H +#define INT80H 1 #endif #ifndef SHOWTITLE @@ -39,10 +40,10 @@ namespace { -constexpr int kDumpSize = 16; +#if WOZMON -uint8_t getc() { - register uint8_t c asm ("al"); +int getchar() { + register char c asm ("al"); asm volatile ( "movb $0x00, %%ah\n\t" "int $0x16" @@ -52,10 +53,10 @@ uint8_t getc() { return c; } -void putc(uint8_t c) { +void putchar(int c) { asm volatile ( "push %%bp \n\t" - "movb %0, %%al \n\t" + "mov %0, %%ax \n\t" "movb $0x0e, %%ah \n\t" "movb $0, %%bh \n\t" "int $0x10 \n\t" @@ -65,40 +66,32 @@ void putc(uint8_t c) { ); } -void puts(const char* s) { - while (*s) { - putc(*s++); - } -} +#endif // WOZMON + +constexpr int kDumpSize = 16; // arguments on the stack in reverse order -extern "C" uint16_t FarJump(uint16_t addr, uint16_t seg, int nargs); +extern "C" uint16_t Int80h(uint8_t fun, int nargs); asm ( - ".section .text.FarJump \n" - "FarJump: \n" - " push %bx \n" + ".section .text.Int80h \n" + "Int80h: \n" " push %si \n" - " push %di \n" " push %bp \n" - " push %cx \n" // seg - " push %ax \n" // addr - " movw %sp, %bp \n" - " movw %dx, %si \n" // nargs - " add %si, %si \n" - "j0: \n" - " test %si, %si \n" - " jz j1 \n" - " lea 12(%bp,%si), %di\n" - " push %di \n" - " sub $2, %si \n" - " jmp j0 \n" - "j1: \n" - " lcall *(%bp) \n" - " add $4, %sp \n" + " mov %al, %ah \n" + " mov %sp, %bp \n" + " lea 6(%bp), %si \n" // 4 for pushed stuff, 2 for return addr + "0: \n" + " test %dx, %dx \n" + " jz 1f \n" + " push (%si) \n" + " dec %dx \n" + " add $2, %si \n" + " jmp 0b \n" + "1: \n" + " int $0x80 \n" + " mov %bp, %sp \n" " pop %bp \n" - " pop %di \n" " pop %si \n" - " pop %bx \n" " ret" // return value in ax ); @@ -136,9 +129,9 @@ uint16_t ReadUint16(const char* buf) { void WriteHexNibble(uint8_t c) { if (c > 9) { - putc('a' + c - 10); + putchar('a' + c - 10); } else { - putc('0' + c); + putchar('0' + c); } } @@ -187,19 +180,19 @@ inline static void __basic__() { void Dump(uint16_t addr, uint16_t seg, int count) { for (int i = 0; i < count; i++) { - putc(' '); + putchar(' '); uint8_t d = __get_far_u8__(addr + i, seg); WriteUint8(d); } #if ASCIIDUMP - putc(' '); - putc(' '); + putchar(' '); + putchar(' '); for (int i = 0; i < count; i++) { uint8_t d = __get_far_u8__(addr + i, seg); if (d > 31 && d < 127) { - putc(d); + putchar(d); } else { - putc('.'); + putchar('.'); } } #endif @@ -208,15 +201,15 @@ void Dump(uint16_t addr, uint16_t seg, int count) { void DumpHex(uint16_t addr, uint16_t seg) { addr &= -kDumpSize; - putc('['); + putchar('['); WriteUint16(seg); - putc(':'); + putchar(':'); WriteUint16(addr); - putc(']'); - putc(':'); + putchar(']'); + putchar(':'); Dump(addr, seg, kDumpSize); - putc('\r'); - putc('\n'); + putchar('\r'); + putchar('\n'); } void ClearScreen() { @@ -255,11 +248,21 @@ bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) { ptr += 5; } else if (*ptr == '$') { __basic__(); - } else if (*ptr == 'r') { + } else if (*ptr == 'j') { + dump = false; + ptr++; + auto jump = reinterpret_cast(cur_addr); + uint16_t ret = jump(); + WriteUint16(ret); + putchar('\r'); + putchar('\n'); +#if INT80H + } else if (*ptr == 'i') { dump = false; -#if FARCALL int nargs = 0; ptr++; + int fun = ReadUint8(ptr); + ptr += 2; for (; *ptr;) { if (*ptr == ' ') { ptr++; @@ -270,19 +273,16 @@ bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) { nargs++; ptr += 4; } - uint16_t ret = FarJump(cur_addr, cur_seg, nargs); + uint16_t ret = Int80h(fun, nargs); asm volatile ( "shl %0 \n\t" "add %0, %%sp" :: "r"(nargs) ); WriteUint16(ret); - putc('\r'); putc('\n'); -#else // FARCALL - auto jump = reinterpret_cast(cur_addr); - jump(); -#endif // FARCALL - ptr++; + putchar('\r'); + putchar('\n'); +#endif // INT80H #if CLEARSCREENCMD } else if (*ptr == 'l') { dump = false; @@ -311,7 +311,10 @@ bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) { return dump; } -const char* prompt = "> "; +void DisplayPrompt() { + putchar('>'); + putchar(' '); +} void polmon() { uint16_t cur_addr = 0; @@ -324,11 +327,11 @@ void polmon() { #if SHOWTITLE puts("PolMon 0.2\r\n"); #endif // SHOWTITLE - puts(prompt); + DisplayPrompt(); while (1) { - uint8_t c = getc(); - putc(c); // echo + uint8_t c = getchar(); + putchar(c); // echo if (c == '\r') { *inptr = 0; if (inbuf[0] == 0) { @@ -336,7 +339,7 @@ void polmon() { cur_addr += kDumpSize; } } else { - putc('\n'); + putchar('\n'); } if (ParseCommand(inbuf, cur_addr, cur_seg)) { @@ -344,17 +347,17 @@ void polmon() { }; first = false; inptr = inbuf; - puts(prompt); + DisplayPrompt(); #if BACKSPACE } else if (c == kBackspace || c == kOtherBackspace) { inptr--; if (inptr < inbuf) { inptr = inbuf; - putc(' '); + putchar(' '); continue; } - putc(' '); - putc(kOtherBackspace); + putchar(' '); + putchar(kOtherBackspace); #endif } else { *inptr = c; diff --git a/stdlib.c b/stdlib.c new file mode 100644 index 0000000..0cf55e2 --- /dev/null +++ b/stdlib.c @@ -0,0 +1,31 @@ +int getchar() { + register char c asm ("al"); + asm volatile ( + "movb $0x00, %%ah\n\t" + "int $0x16" + : "=r" (c) + :: "ah", "cc" + ); + return c; +} + +int putchar(int c) { + asm volatile ( + "push %%bp \n\t" + "mov %0, %%ax \n\t" + "movb $0x0e, %%ah \n\t" + "movb $0, %%bh \n\t" + "int $0x10 \n\t" + "pop %%bp \n\t" + :: "r" (c) + : "ax", "bh", "cc" + ); + return 0; +} + +int puts(const char* s) { + while (*s) { + putchar(*s++); + } + return 0; +}