polmon: refactor jump & stdlib

This commit is contained in:
2025-09-29 17:52:21 +02:00
parent 8a06693456
commit de41328677
3 changed files with 102 additions and 68 deletions

View File

@@ -31,8 +31,8 @@ fat12boot.elf: LDFLAGS += -T bootsect.ld
fat12boot.bin: fat12boot.elf fat12boot.bin: fat12boot.elf
polmon.elf: LDFLAGS += -T flat0600.ld polmon.elf: LDFLAGS += -T flat1000.ld
polmon.elf: polmon.o polmon.elf: polmon.o stdlib.o
wozmon.o: polmon.cc wozmon.o: polmon.cc

135
polmon.cc
View File

@@ -1,4 +1,5 @@
#include <cstdint> #include <cstdint>
#include <cstdio>
#ifndef WOZMON #ifndef WOZMON
#define WOZMON 0 #define WOZMON 0
@@ -8,7 +9,7 @@
#define BACKSPACE 0 #define BACKSPACE 0
#define ASCIIDUMP 0 #define ASCIIDUMP 0
#define CLEARSCREENCMD 0 #define CLEARSCREENCMD 0
#define FARCALL 0 #define INT80H 0
#define SHOWTITLE 0 #define SHOWTITLE 0
#define BOOTSTRAP 0 #define BOOTSTRAP 0
#endif // WOZMON #endif // WOZMON
@@ -25,8 +26,8 @@
#define CLEARSCREENCMD 1 #define CLEARSCREENCMD 1
#endif #endif
#ifndef FARCALL #ifndef INT80H
#define FARCALL 1 #define INT80H 1
#endif #endif
#ifndef SHOWTITLE #ifndef SHOWTITLE
@@ -39,10 +40,10 @@
namespace { namespace {
constexpr int kDumpSize = 16; #if WOZMON
uint8_t getc() { int getchar() {
register uint8_t c asm ("al"); register char c asm ("al");
asm volatile ( asm volatile (
"movb $0x00, %%ah\n\t" "movb $0x00, %%ah\n\t"
"int $0x16" "int $0x16"
@@ -52,10 +53,10 @@ uint8_t getc() {
return c; return c;
} }
void putc(uint8_t c) { void putchar(int c) {
asm volatile ( asm volatile (
"push %%bp \n\t" "push %%bp \n\t"
"movb %0, %%al \n\t" "mov %0, %%ax \n\t"
"movb $0x0e, %%ah \n\t" "movb $0x0e, %%ah \n\t"
"movb $0, %%bh \n\t" "movb $0, %%bh \n\t"
"int $0x10 \n\t" "int $0x10 \n\t"
@@ -65,40 +66,32 @@ void putc(uint8_t c) {
); );
} }
void puts(const char* s) { #endif // WOZMON
while (*s) {
putc(*s++); constexpr int kDumpSize = 16;
}
}
// arguments on the stack in reverse order // 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 ( asm (
".section .text.FarJump \n" ".section .text.Int80h \n"
"FarJump: \n" "Int80h: \n"
" push %bx \n"
" push %si \n" " push %si \n"
" push %di \n"
" push %bp \n" " push %bp \n"
" push %cx \n" // seg " mov %al, %ah \n"
" push %ax \n" // addr " mov %sp, %bp \n"
" movw %sp, %bp \n" " lea 6(%bp), %si \n" // 4 for pushed stuff, 2 for return addr
" movw %dx, %si \n" // nargs "0: \n"
" add %si, %si \n" " test %dx, %dx \n"
"j0: \n" " jz 1f \n"
" test %si, %si \n" " push (%si) \n"
" jz j1 \n" " dec %dx \n"
" lea 12(%bp,%si), %di\n" " add $2, %si \n"
" push %di \n" " jmp 0b \n"
" sub $2, %si \n" "1: \n"
" jmp j0 \n" " int $0x80 \n"
"j1: \n" " mov %bp, %sp \n"
" lcall *(%bp) \n"
" add $4, %sp \n"
" pop %bp \n" " pop %bp \n"
" pop %di \n"
" pop %si \n" " pop %si \n"
" pop %bx \n"
" ret" " ret"
// return value in ax // return value in ax
); );
@@ -136,9 +129,9 @@ uint16_t ReadUint16(const char* buf) {
void WriteHexNibble(uint8_t c) { void WriteHexNibble(uint8_t c) {
if (c > 9) { if (c > 9) {
putc('a' + c - 10); putchar('a' + c - 10);
} else { } 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) { void Dump(uint16_t addr, uint16_t seg, int count) {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
putc(' '); putchar(' ');
uint8_t d = __get_far_u8__(addr + i, seg); uint8_t d = __get_far_u8__(addr + i, seg);
WriteUint8(d); WriteUint8(d);
} }
#if ASCIIDUMP #if ASCIIDUMP
putc(' '); putchar(' ');
putc(' '); putchar(' ');
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
uint8_t d = __get_far_u8__(addr + i, seg); uint8_t d = __get_far_u8__(addr + i, seg);
if (d > 31 && d < 127) { if (d > 31 && d < 127) {
putc(d); putchar(d);
} else { } else {
putc('.'); putchar('.');
} }
} }
#endif #endif
@@ -208,15 +201,15 @@ void Dump(uint16_t addr, uint16_t seg, int count) {
void DumpHex(uint16_t addr, uint16_t seg) { void DumpHex(uint16_t addr, uint16_t seg) {
addr &= -kDumpSize; addr &= -kDumpSize;
putc('['); putchar('[');
WriteUint16(seg); WriteUint16(seg);
putc(':'); putchar(':');
WriteUint16(addr); WriteUint16(addr);
putc(']'); putchar(']');
putc(':'); putchar(':');
Dump(addr, seg, kDumpSize); Dump(addr, seg, kDumpSize);
putc('\r'); putchar('\r');
putc('\n'); putchar('\n');
} }
void ClearScreen() { void ClearScreen() {
@@ -255,11 +248,21 @@ bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) {
ptr += 5; ptr += 5;
} else if (*ptr == '$') { } else if (*ptr == '$') {
__basic__(); __basic__();
} else if (*ptr == 'r') { } else if (*ptr == 'j') {
dump = false;
ptr++;
auto jump = reinterpret_cast<uint16_t(*)()>(cur_addr);
uint16_t ret = jump();
WriteUint16(ret);
putchar('\r');
putchar('\n');
#if INT80H
} else if (*ptr == 'i') {
dump = false; dump = false;
#if FARCALL
int nargs = 0; int nargs = 0;
ptr++; ptr++;
int fun = ReadUint8(ptr);
ptr += 2;
for (; *ptr;) { for (; *ptr;) {
if (*ptr == ' ') { if (*ptr == ' ') {
ptr++; ptr++;
@@ -270,19 +273,16 @@ bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) {
nargs++; nargs++;
ptr += 4; ptr += 4;
} }
uint16_t ret = FarJump(cur_addr, cur_seg, nargs); uint16_t ret = Int80h(fun, nargs);
asm volatile ( asm volatile (
"shl %0 \n\t" "shl %0 \n\t"
"add %0, %%sp" "add %0, %%sp"
:: "r"(nargs) :: "r"(nargs)
); );
WriteUint16(ret); WriteUint16(ret);
putc('\r'); putc('\n'); putchar('\r');
#else // FARCALL putchar('\n');
auto jump = reinterpret_cast<void(*)()>(cur_addr); #endif // INT80H
jump();
#endif // FARCALL
ptr++;
#if CLEARSCREENCMD #if CLEARSCREENCMD
} else if (*ptr == 'l') { } else if (*ptr == 'l') {
dump = false; dump = false;
@@ -311,7 +311,10 @@ bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) {
return dump; return dump;
} }
const char* prompt = "> "; void DisplayPrompt() {
putchar('>');
putchar(' ');
}
void polmon() { void polmon() {
uint16_t cur_addr = 0; uint16_t cur_addr = 0;
@@ -324,11 +327,11 @@ void polmon() {
#if SHOWTITLE #if SHOWTITLE
puts("PolMon 0.2\r\n"); puts("PolMon 0.2\r\n");
#endif // SHOWTITLE #endif // SHOWTITLE
puts(prompt); DisplayPrompt();
while (1) { while (1) {
uint8_t c = getc(); uint8_t c = getchar();
putc(c); // echo putchar(c); // echo
if (c == '\r') { if (c == '\r') {
*inptr = 0; *inptr = 0;
if (inbuf[0] == 0) { if (inbuf[0] == 0) {
@@ -336,7 +339,7 @@ void polmon() {
cur_addr += kDumpSize; cur_addr += kDumpSize;
} }
} else { } else {
putc('\n'); putchar('\n');
} }
if (ParseCommand(inbuf, cur_addr, cur_seg)) { if (ParseCommand(inbuf, cur_addr, cur_seg)) {
@@ -344,17 +347,17 @@ void polmon() {
}; };
first = false; first = false;
inptr = inbuf; inptr = inbuf;
puts(prompt); DisplayPrompt();
#if BACKSPACE #if BACKSPACE
} else if (c == kBackspace || c == kOtherBackspace) { } else if (c == kBackspace || c == kOtherBackspace) {
inptr--; inptr--;
if (inptr < inbuf) { if (inptr < inbuf) {
inptr = inbuf; inptr = inbuf;
putc(' '); putchar(' ');
continue; continue;
} }
putc(' '); putchar(' ');
putc(kOtherBackspace); putchar(kOtherBackspace);
#endif #endif
} else { } else {
*inptr = c; *inptr = c;

31
stdlib.c Normal file
View File

@@ -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;
}