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
|
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
135
polmon.cc
@@ -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
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