clang-format -i *.cc *.c *.h

This commit is contained in:
2025-09-29 18:54:48 +02:00
parent f3057e92be
commit f1b2902640
8 changed files with 194 additions and 249 deletions

28
crc16.c
View File

@@ -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,17 +19,15 @@ 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" " mov 8(%bp), %si \n"
" mov 8(%bp), %si \n" " push (%si) \n"
" push (%si) \n" " call crc16 \n"
" call crc16 \n" " add $0x2, %sp \n"
" add $0x2, %sp \n" " 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"
);

28
crt0.c
View File

@@ -3,24 +3,22 @@
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" "mov %ax, %ds \n\t"
"mov %ax, %ds \n\t" "mov %ax, %es \n\t"
"mov %ax, %es \n\t" "cli \n\t"
"cli \n\t" "mov %ax, %ss \n\t"
"mov %ax, %ss \n\t" "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
View File

@@ -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)) {

View File

@@ -11,5 +11,5 @@ int fat12_init(void* fat_addr, void* rootdir_addr);
* Returns: * Returns:
* -4 if file is not found * -4 if file is not found
* -5 if there is a disk error * -5 if there is a disk error
*/ */
int fat12_readfile(const char* name, void* addr); int fat12_readfile(const char* name, void* addr);

View File

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

View File

@@ -33,32 +33,31 @@ static void swapbuffers() {
uint8_t paracomm_nextbyte() { uint8_t paracomm_nextbyte() {
switch (mosi_state) { switch (mosi_state) {
case 0: case 0:
if (mosi_size == 0) {
swapbuffers();
if (mosi_size == 0) { if (mosi_size == 0) {
swapbuffers(); return kMosiIdleByte;
if (mosi_size == 0) {
return kMosiIdleByte;
}
} }
mosi_state = 1; }
return kMosiStartByte; mosi_state = 1;
case 1: return kMosiStartByte;
// assert(mosi_size > 0) case 1:
mosi_sent = 0; // assert(mosi_size > 0)
mosi_state = 2; mosi_sent = 0;
return mosi_size; mosi_state = 2;
case 2: return mosi_size;
{ case 2: {
uint8_t b = mosi_sendbuf[mosi_sent]; uint8_t b = mosi_sendbuf[mosi_sent];
mosi_sent += 1; mosi_sent += 1;
if (mosi_sent == mosi_size) { if (mosi_sent == mosi_size) {
swapbuffers(); swapbuffers();
mosi_state = 0; mosi_state = 0;
} }
return b; return b;
} }
} }
__builtin_unreachable(); __builtin_unreachable();
@@ -66,41 +65,39 @@ uint8_t paracomm_nextbyte() {
void paracomm_feed(uint8_t n) { void paracomm_feed(uint8_t n) {
switch (miso_state) { switch (miso_state) {
case 0: case 0:
if (n == kMisoStartNibble) { if (n == kMisoStartNibble) {
miso_state = 1; miso_state = 1;
} else if (n == kMisoIdleNibble) { } else if (n == kMisoIdleNibble) {
} else { } else {
// error: spurious nibble // error: spurious nibble
} }
break; break;
case 1: case 1:
miso_size = n; miso_size = n;
miso_state = 2; miso_state = 2;
break; break;
case 2: case 2:
miso_size += n << 4; miso_size += n << 4;
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; } else {
} else { miso_recvbuf[idx] += n << 4;
miso_recvbuf[idx] += n << 4; }
} 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;
}
} }
break; miso_state = 0;
}
} break;
} }
} }

178
polmon.cc
View File

@@ -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)::"ah", "cc");
: "=r" (c)
:: "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" ::"r"(c)
"pop %%bp \n\t" : "ax", "bh", "cc");
:: "r" (c)
: "ax", "bh", "cc"
);
} }
#endif // WOZMON #endif // WOZMON
@@ -72,29 +66,28 @@ 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" " mov %al, %ah \n"
" mov %al, %ah \n" " mov %sp, %bp \n"
" mov %sp, %bp \n" " lea 6(%bp), %si \n" // 4 for pushed stuff, 2 for return addr
" lea 6(%bp), %si \n" // 4 for pushed stuff, 2 for return addr "0: \n"
"0: \n" " test %dx, %dx \n"
" test %dx, %dx \n" " jz 1f \n"
" jz 1f \n" " push (%si) \n"
" push (%si) \n" " dec %dx \n"
" dec %dx \n" " add $2, %si \n"
" add $2, %si \n" " jmp 0b \n"
" jmp 0b \n" "1: \n"
"1: \n" " int $0x80 \n"
" int $0x80 \n" " mov %bp, %sp \n"
" mov %bp, %sp \n" " pop %bp \n"
" pop %bp \n" " 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 ( "mov %ax, %ds \n\t"
"movw $0x40, %ax \n\t" "int $0x18");
"mov %ax, %ds \n\t"
"int $0x18"
);
__builtin_unreachable(); __builtin_unreachable();
} }
@@ -213,30 +191,26 @@ 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" "movb $0x02, %%ah \n\t"
"movb $0x02, %%ah \n\t" "movw $77, %%dx \n\t"
"movw $77, %%dx \n\t" "int $0x10 \n\t"
"int $0x10 \n\t" "movb %0, %%al \n\t"
"movb %0, %%al \n\t" "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" ::"rm"(status),
"int $0x10" "l"(WriteUint8)
:: "rm" (status), "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,17 +243,14 @@ 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" WriteUint16(ret);
:: "r"(nargs)
);
WriteUint16(ret);
putchar('\r'); putchar('\r');
putchar('\n'); putchar('\n');
#endif // INT80H #endif // INT80H
@@ -324,7 +295,7 @@ void polmon() {
char* inptr = inbuf; char* inptr = inbuf;
ClearScreen(); ClearScreen();
#if SHOWTITLE #if SHOWTITLE
puts("PolMon 0.2\r\n"); puts("PolMon 0.2\r\n");
#endif // SHOWTITLE #endif // SHOWTITLE
DisplayPrompt(); DisplayPrompt();
@@ -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();
} }

View File

@@ -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)::"ah", "cc");
: "=r" (c)
:: "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" ::"r"(c)
"pop %%bp \n\t" : "ax", "bh", "cc");
:: "r" (c)
: "ax", "bh", "cc"
);
return 0; return 0;
} }