clang-format -i *.cc *.c *.h
This commit is contained in:
8
crc16.c
8
crc16.c
@@ -1,6 +1,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define kDataAddr ((uint8_t*) 0x0000)
|
#define kDataAddr ((uint8_t*)0x0000)
|
||||||
|
|
||||||
uint16_t crc16(int data_len) {
|
uint16_t crc16(int data_len) {
|
||||||
const uint8_t* data = kDataAddr;
|
const uint8_t* data = kDataAddr;
|
||||||
@@ -19,8 +19,7 @@ uint16_t crc16(int data_len) {
|
|||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
asm (
|
asm(".global main \n"
|
||||||
".global main \n"
|
|
||||||
"main: \n"
|
"main: \n"
|
||||||
" push %bp \n"
|
" push %bp \n"
|
||||||
" mov %sp, %bp \n"
|
" mov %sp, %bp \n"
|
||||||
@@ -31,5 +30,4 @@ asm (
|
|||||||
" mov 6(%bp), %di \n"
|
" mov 6(%bp), %di \n"
|
||||||
" mov %ax, (%di) \n"
|
" mov %ax, (%di) \n"
|
||||||
" pop %bp \n"
|
" pop %bp \n"
|
||||||
" lret $4 \n"
|
" lret $4 \n");
|
||||||
);
|
|
||||||
|
8
crt0.c
8
crt0.c
@@ -3,8 +3,7 @@
|
|||||||
|
|
||||||
int main();
|
int main();
|
||||||
|
|
||||||
asm (
|
asm(".section .init \n"
|
||||||
".section .init \n"
|
|
||||||
".global _start \n"
|
".global _start \n"
|
||||||
"_start: \n\t"
|
"_start: \n\t"
|
||||||
"mov %cs, %ax \n\t"
|
"mov %cs, %ax \n\t"
|
||||||
@@ -15,12 +14,11 @@ asm (
|
|||||||
"mov $0x1000, %ax \n\t"
|
"mov $0x1000, %ax \n\t"
|
||||||
"mov %ax, %sp \n\t"
|
"mov %ax, %sp \n\t"
|
||||||
"sti \n\t"
|
"sti \n\t"
|
||||||
"jmp main"
|
"jmp main");
|
||||||
);
|
|
||||||
|
|
||||||
void* memset(void* ptr, int val, size_t len) {
|
void* memset(void* ptr, int val, size_t len) {
|
||||||
uint8_t* p = ptr;
|
uint8_t* p = ptr;
|
||||||
while(len--) {
|
while (len--) {
|
||||||
*p++ = val;
|
*p++ = val;
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
|
38
fat12.c
38
fat12.c
@@ -6,8 +6,7 @@
|
|||||||
#define kHeads 2
|
#define kHeads 2
|
||||||
#define kFatSizeSectors 2
|
#define kFatSizeSectors 2
|
||||||
#define kRootDirSizeSectors 7
|
#define kRootDirSizeSectors 7
|
||||||
#define kDataRegionStartSector (1 + kFatSizeSectors*2 + kRootDirSizeSectors)
|
#define kDataRegionStartSector (1 + kFatSizeSectors * 2 + kRootDirSizeSectors)
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char name[8];
|
char name[8];
|
||||||
@@ -24,22 +23,22 @@ static uint8_t* gFat;
|
|||||||
static direntry* gRootdir;
|
static direntry* gRootdir;
|
||||||
|
|
||||||
static int readsector(int c, int h, int s, uint8_t* addr) {
|
static int readsector(int c, int h, int s, uint8_t* addr) {
|
||||||
register uint8_t* dest asm ("bx") = addr;
|
register uint8_t* dest asm("bx") = addr;
|
||||||
register uint8_t nsects asm ("al") = 1;
|
register uint8_t nsects asm("al") = 1;
|
||||||
register uint8_t func asm ("ah") = 0x02;
|
register uint8_t func asm("ah") = 0x02;
|
||||||
register uint8_t sect asm ("cl") = s;
|
register uint8_t sect asm("cl") = s;
|
||||||
register uint8_t cyl asm ("ch") = c;
|
register uint8_t cyl asm("ch") = c;
|
||||||
register uint8_t head asm ("dh") = h;
|
register uint8_t head asm("dh") = h;
|
||||||
register uint8_t drive asm ("dl") = 0;
|
register uint8_t drive asm("dl") = 0;
|
||||||
register uint16_t seg asm ("es") = 0;
|
register uint16_t seg asm("es") = 0;
|
||||||
|
|
||||||
register uint8_t ret asm("ah");
|
register uint8_t ret asm("ah");
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
asm volatile ("int $0x13"
|
asm volatile("int $0x13"
|
||||||
: "=r" (ret)
|
: "=r"(ret)
|
||||||
: "r" (dest), "r" (nsects), "r" (func), "r" (sect),
|
: "r"(dest), "r"(nsects), "r"(func), "r"(sect), "r"(cyl),
|
||||||
"r" (cyl), "r" (head), "r" (drive), "r" (seg));
|
"r"(head), "r"(drive), "r"(seg));
|
||||||
if (ret != 0x80) {
|
if (ret != 0x80) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -52,20 +51,21 @@ static int readcluster(int cluster) {
|
|||||||
int offs = cluster * 3 / 2;
|
int offs = cluster * 3 / 2;
|
||||||
if (cluster % 2) {
|
if (cluster % 2) {
|
||||||
// high nibble is lsb + whole byte
|
// high nibble is lsb + whole byte
|
||||||
return ((gFat[offs] & 0xf0) >> 4) + (gFat[offs+1] << 4);
|
return ((gFat[offs] & 0xf0) >> 4) + (gFat[offs + 1] << 4);
|
||||||
} else {
|
} else {
|
||||||
return gFat[offs] + ((gFat[offs+1] & 0x0f) << 8);
|
return gFat[offs] + ((gFat[offs + 1] & 0x0f) << 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cluster2chs(int cluster, int* c, int* h, int* s) {
|
static void cluster2chs(int cluster, int* c, int* h, int* s) {
|
||||||
int logicalsector = kDataRegionStartSector + (cluster - 2) * kSectorsPerCluster;
|
int logicalsector =
|
||||||
|
kDataRegionStartSector + (cluster - 2) * kSectorsPerCluster;
|
||||||
*s = (logicalsector % kSectorsPerTrack) + 1;
|
*s = (logicalsector % kSectorsPerTrack) + 1;
|
||||||
*h = (logicalsector / kSectorsPerTrack) % kHeads;
|
*h = (logicalsector / kSectorsPerTrack) % kHeads;
|
||||||
*c = logicalsector / (kHeads * kSectorsPerTrack);
|
*c = logicalsector / (kHeads * kSectorsPerTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int strncmp(const char* s1, const char *s2, size_t len) {
|
static int strncmp(const char* s1, const char* s2, size_t len) {
|
||||||
for (int i = 0; i < len && s1[i]; i++) {
|
for (int i = 0; i < len && s1[i]; i++) {
|
||||||
if (s1[i] != s2[i]) {
|
if (s1[i] != s2[i]) {
|
||||||
return 1;
|
return 1;
|
||||||
@@ -77,7 +77,7 @@ static int strncmp(const char* s1, const char *s2, size_t len) {
|
|||||||
|
|
||||||
static int loadfile(direntry* entry, void* addr) {
|
static int loadfile(direntry* entry, void* addr) {
|
||||||
int cluster = entry->cluster;
|
int cluster = entry->cluster;
|
||||||
for (int i = 0; i < entry->size; i+=1024) {
|
for (int i = 0; i < entry->size; i += 1024) {
|
||||||
int c, h, s;
|
int c, h, s;
|
||||||
cluster2chs(cluster, &c, &h, &s);
|
cluster2chs(cluster, &c, &h, &s);
|
||||||
if (readsector(c, h, s, addr + i)) {
|
if (readsector(c, h, s, addr + i)) {
|
||||||
|
34
fat12boot.c
34
fat12boot.c
@@ -7,15 +7,12 @@
|
|||||||
#define kFatAddress ((void*)0x1000)
|
#define kFatAddress ((void*)0x1000)
|
||||||
#define kRootDirAddress ((void*)0x1200)
|
#define kRootDirAddress ((void*)0x1200)
|
||||||
|
|
||||||
|
|
||||||
static int putchar(int c) {
|
static int putchar(int c) {
|
||||||
register uint8_t khar asm ("al") = c;
|
register uint8_t khar asm("al") = c;
|
||||||
register uint8_t func asm ("ah") = 0x0e;
|
register uint8_t func asm("ah") = 0x0e;
|
||||||
register uint8_t page asm ("bh") = 0;
|
register uint8_t page asm("bh") = 0;
|
||||||
|
|
||||||
asm volatile ("int $0x10"
|
asm volatile("int $0x10" ::"r"(khar), "r"(func), "r"(page) : "bp");
|
||||||
:: "r" (khar), "r" (func), "r" (page)
|
|
||||||
: "bp");
|
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -27,37 +24,30 @@ static int puts(const char* msg) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn)) static void die(const char* msg) {
|
||||||
static void die(const char* msg) {
|
|
||||||
puts(msg);
|
puts(msg);
|
||||||
while (1) {
|
while (1) {
|
||||||
}
|
}
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn)) static void jump(void* addr) {
|
||||||
static void jump(void* addr) {
|
asm volatile("ljmp $0,%0" ::"i"(addr));
|
||||||
asm volatile ("ljmp $0,%0" :: "i"(addr));
|
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn)) static void loadpolmon() {
|
||||||
static void loadpolmon() {
|
|
||||||
if (fat12_init(kFatAddress, kRootDirAddress)) {
|
if (fat12_init(kFatAddress, kRootDirAddress)) {
|
||||||
die("fi");
|
die("fi");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fat12_readfile("POLIO COM", kPolmonAddress)) {
|
while (fat12_readfile("POLIO COM", kPolmonAddress)) {
|
||||||
asm volatile (
|
asm volatile("mov $00, %%ah \n\t"
|
||||||
"mov $00, %%ah \n\t"
|
"int $0x16 \n\t" ::
|
||||||
"int $0x16 \n\t"
|
: "ax");
|
||||||
::: "ax"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jump(kPolmonAddress);
|
jump(kPolmonAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() { loadpolmon(); }
|
||||||
loadpolmon();
|
|
||||||
}
|
|
||||||
|
11
paracomm.c
11
paracomm.c
@@ -47,8 +47,7 @@ uint8_t paracomm_nextbyte() {
|
|||||||
mosi_sent = 0;
|
mosi_sent = 0;
|
||||||
mosi_state = 2;
|
mosi_state = 2;
|
||||||
return mosi_size;
|
return mosi_size;
|
||||||
case 2:
|
case 2: {
|
||||||
{
|
|
||||||
uint8_t b = mosi_sendbuf[mosi_sent];
|
uint8_t b = mosi_sendbuf[mosi_sent];
|
||||||
mosi_sent += 1;
|
mosi_sent += 1;
|
||||||
|
|
||||||
@@ -83,8 +82,7 @@ void paracomm_feed(uint8_t n) {
|
|||||||
miso_received_nibbles = 0;
|
miso_received_nibbles = 0;
|
||||||
miso_state = 3;
|
miso_state = 3;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3: {
|
||||||
{
|
|
||||||
uint8_t idx = miso_received_nibbles / 2;
|
uint8_t idx = miso_received_nibbles / 2;
|
||||||
if (miso_received_nibbles % 2 == 0) {
|
if (miso_received_nibbles % 2 == 0) {
|
||||||
miso_recvbuf[idx] = n;
|
miso_recvbuf[idx] = n;
|
||||||
@@ -93,14 +91,13 @@ void paracomm_feed(uint8_t n) {
|
|||||||
}
|
}
|
||||||
miso_received_nibbles += 1;
|
miso_received_nibbles += 1;
|
||||||
|
|
||||||
if (miso_received_nibbles == 2*miso_size) {
|
if (miso_received_nibbles == 2 * miso_size) {
|
||||||
if (miso_cb != 0) {
|
if (miso_cb != 0) {
|
||||||
miso_cb(miso_recvbuf, miso_size);
|
miso_cb(miso_recvbuf, miso_size);
|
||||||
}
|
}
|
||||||
miso_state = 0;
|
miso_state = 0;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
102
polmon.cc
102
polmon.cc
@@ -43,27 +43,21 @@ namespace {
|
|||||||
#if WOZMON
|
#if WOZMON
|
||||||
|
|
||||||
int getchar() {
|
int getchar() {
|
||||||
register char 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"
|
||||||
: "=r" (c)
|
: "=r"(c)::"ah", "cc");
|
||||||
:: "ah", "cc"
|
|
||||||
);
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void putchar(int c) {
|
void putchar(int c) {
|
||||||
asm volatile (
|
asm volatile("push %%bp \n\t"
|
||||||
"push %%bp \n\t"
|
|
||||||
"mov %0, %%ax \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"
|
||||||
"pop %%bp \n\t"
|
"pop %%bp \n\t" ::"r"(c)
|
||||||
:: "r" (c)
|
: "ax", "bh", "cc");
|
||||||
: "ax", "bh", "cc"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // WOZMON
|
#endif // WOZMON
|
||||||
@@ -72,8 +66,7 @@ constexpr int kDumpSize = 16;
|
|||||||
|
|
||||||
// arguments on the stack in reverse order
|
// arguments on the stack in reverse order
|
||||||
extern "C" uint16_t Int80h(uint8_t fun, int nargs);
|
extern "C" uint16_t Int80h(uint8_t fun, int nargs);
|
||||||
asm (
|
asm(".section .text.Int80h \n"
|
||||||
".section .text.Int80h \n"
|
|
||||||
"Int80h: \n"
|
"Int80h: \n"
|
||||||
" push %si \n"
|
" push %si \n"
|
||||||
" push %bp \n"
|
" push %bp \n"
|
||||||
@@ -94,7 +87,7 @@ asm (
|
|||||||
" pop %si \n"
|
" pop %si \n"
|
||||||
" ret"
|
" ret"
|
||||||
// return value in ax
|
// return value in ax
|
||||||
);
|
);
|
||||||
|
|
||||||
constexpr uint8_t kBackspace = 0x7f;
|
constexpr uint8_t kBackspace = 0x7f;
|
||||||
constexpr uint8_t kOtherBackspace = 0x08;
|
constexpr uint8_t kOtherBackspace = 0x08;
|
||||||
@@ -119,13 +112,9 @@ uint16_t ReadUintN(int n, const char* buf) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ReadUint8(const char* buf) {
|
uint8_t ReadUint8(const char* buf) { return ReadUintN(2, buf); }
|
||||||
return ReadUintN(2, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t ReadUint16(const char* buf) {
|
uint16_t ReadUint16(const char* buf) { return ReadUintN(4, buf); }
|
||||||
return ReadUintN(4, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteHexNibble(uint8_t c) {
|
void WriteHexNibble(uint8_t c) {
|
||||||
if (c > 9) {
|
if (c > 9) {
|
||||||
@@ -146,35 +135,24 @@ void WriteUint16(uint16_t a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t __get_far_u8__(uint16_t addr, uint16_t seg) {
|
uint8_t __get_far_u8__(uint16_t addr, uint16_t seg) {
|
||||||
register uint16_t ad asm ("si") = addr;
|
register uint16_t ad asm("si") = addr;
|
||||||
register uint16_t sg asm ("ds") = seg;
|
register uint16_t sg asm("ds") = seg;
|
||||||
register uint8_t ret asm ("al");
|
register uint8_t ret asm("al");
|
||||||
asm (
|
asm("lodsb \n\t" : "=r"(ret) : "r"(ad), "r"(sg));
|
||||||
"lodsb \n\t"
|
|
||||||
: "=r" (ret)
|
|
||||||
: "r" (ad), "r" (sg)
|
|
||||||
);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __set_far_u8__(uint16_t addr, uint16_t seg, uint8_t val) {
|
void __set_far_u8__(uint16_t addr, uint16_t seg, uint8_t val) {
|
||||||
register uint16_t ad asm ("di") = addr;
|
register uint16_t ad asm("di") = addr;
|
||||||
register uint16_t sg asm ("es") = seg;
|
register uint16_t sg asm("es") = seg;
|
||||||
register uint8_t v asm ("al") = val;
|
register uint8_t v asm("al") = val;
|
||||||
asm (
|
asm("stosb \n\t" ::"r"(sg), "r"(ad), "r"(v) : "memory");
|
||||||
"stosb \n\t"
|
|
||||||
:: "r" (sg), "r" (ad), "r" (v)
|
|
||||||
: "memory"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn)) inline static void __basic__() {
|
||||||
inline static void __basic__() {
|
asm volatile("movw $0x40, %ax \n\t"
|
||||||
asm volatile (
|
|
||||||
"movw $0x40, %ax \n\t"
|
|
||||||
"mov %ax, %ds \n\t"
|
"mov %ax, %ds \n\t"
|
||||||
"int $0x18"
|
"int $0x18");
|
||||||
);
|
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,16 +191,13 @@ void DumpHex(uint16_t addr, uint16_t seg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClearScreen() {
|
void ClearScreen() {
|
||||||
asm volatile (
|
asm volatile("movw $0x0002, %%ax \n\t"
|
||||||
"movw $0x0002, %%ax \n\t"
|
"int $0x10" ::
|
||||||
"int $0x10"
|
: "ax", "cc");
|
||||||
::: "ax", "cc"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status(uint8_t status) {
|
void Status(uint8_t status) {
|
||||||
asm volatile (
|
asm volatile("xorb %%bh, %%bh \n\t"
|
||||||
"xorb %%bh, %%bh \n\t"
|
|
||||||
"movb $0x03, %%ah \n\t"
|
"movb $0x03, %%ah \n\t"
|
||||||
"int $0x10 \n\t"
|
"int $0x10 \n\t"
|
||||||
"mov %%dx, %%di \n\t"
|
"mov %%dx, %%di \n\t"
|
||||||
@@ -233,10 +208,9 @@ void Status(uint8_t status) {
|
|||||||
"call %1 \n\t"
|
"call %1 \n\t"
|
||||||
"movb $0x02, %%ah \n\t"
|
"movb $0x02, %%ah \n\t"
|
||||||
"movw %%di, %%dx \n\t"
|
"movw %%di, %%dx \n\t"
|
||||||
"int $0x10"
|
"int $0x10" ::"rm"(status),
|
||||||
:: "rm" (status), "l" (WriteUint8)
|
"l"(WriteUint8)
|
||||||
: "ax", "bh", "dx", "cx", "di", "cc"
|
: "ax", "bh", "dx", "cx", "di", "cc");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) {
|
bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) {
|
||||||
@@ -244,14 +218,14 @@ bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) {
|
|||||||
for (const char* ptr = buf; *ptr;) {
|
for (const char* ptr = buf; *ptr;) {
|
||||||
if (*ptr == 's') {
|
if (*ptr == 's') {
|
||||||
cur_addr = 0;
|
cur_addr = 0;
|
||||||
cur_seg = ReadUint16(ptr+1);
|
cur_seg = ReadUint16(ptr + 1);
|
||||||
ptr += 5;
|
ptr += 5;
|
||||||
} else if (*ptr == '$') {
|
} else if (*ptr == '$') {
|
||||||
__basic__();
|
__basic__();
|
||||||
} else if (*ptr == 'j') {
|
} else if (*ptr == 'j') {
|
||||||
dump = false;
|
dump = false;
|
||||||
ptr++;
|
ptr++;
|
||||||
auto jump = reinterpret_cast<uint16_t(*)()>(cur_addr);
|
auto jump = reinterpret_cast<uint16_t (*)()>(cur_addr);
|
||||||
uint16_t ret = jump();
|
uint16_t ret = jump();
|
||||||
WriteUint16(ret);
|
WriteUint16(ret);
|
||||||
putchar('\r');
|
putchar('\r');
|
||||||
@@ -269,16 +243,13 @@ bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint16_t d = ReadUint16(ptr);
|
uint16_t d = ReadUint16(ptr);
|
||||||
asm volatile ("push %0" :: "r" (d));
|
asm volatile("push %0" ::"r"(d));
|
||||||
nargs++;
|
nargs++;
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
}
|
}
|
||||||
uint16_t ret = Int80h(fun, nargs);
|
uint16_t ret = Int80h(fun, nargs);
|
||||||
asm volatile (
|
asm volatile("shl %0 \n\t"
|
||||||
"shl %0 \n\t"
|
"add %0, %%sp" ::"r"(nargs));
|
||||||
"add %0, %%sp"
|
|
||||||
:: "r"(nargs)
|
|
||||||
);
|
|
||||||
WriteUint16(ret);
|
WriteUint16(ret);
|
||||||
putchar('\r');
|
putchar('\r');
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
@@ -368,13 +339,10 @@ void polmon() {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int main() {
|
int main() { polmon(); }
|
||||||
polmon();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if BOOTSTRAP
|
#if BOOTSTRAP
|
||||||
__attribute__((section(".init"), noreturn, used))
|
__attribute__((section(".init"), noreturn, used)) void _start() {
|
||||||
void _start() {
|
|
||||||
main();
|
main();
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
18
stdlib.c
18
stdlib.c
@@ -1,25 +1,19 @@
|
|||||||
int getchar() {
|
int getchar() {
|
||||||
register char 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"
|
||||||
: "=r" (c)
|
: "=r"(c)::"ah", "cc");
|
||||||
:: "ah", "cc"
|
|
||||||
);
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
int putchar(int c) {
|
int putchar(int c) {
|
||||||
asm volatile (
|
asm volatile("push %%bp \n\t"
|
||||||
"push %%bp \n\t"
|
|
||||||
"mov %0, %%ax \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"
|
||||||
"pop %%bp \n\t"
|
"pop %%bp \n\t" ::"r"(c)
|
||||||
:: "r" (c)
|
: "ax", "bh", "cc");
|
||||||
: "ax", "bh", "cc"
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user