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
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

135
polmon.cc
View File

@@ -1,4 +1,5 @@
#include <cstdint>
#include <cstdio>
#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<uint16_t(*)()>(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<void(*)()>(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;

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