polmon: refactor jump & stdlib
This commit is contained in:
4
Makefile
4
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
|
||||
|
135
polmon.cc
135
polmon.cc
@@ -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
31
stdlib.c
Normal 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;
|
||||
}
|
Reference in New Issue
Block a user