From dfc5ef65a43300c41f00bf482c498242d6613423 Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Tue, 2 Jan 2024 11:50:12 +1100 Subject: [PATCH] Install the full printf() and printn(), patched to avoid Lnnn label conflicts --- README.md | 6 ++- bi.c | 80 ++++++--------------------------- brt.s | 30 +++++-------- n.sh | 2 +- printf.s | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ printn.s | 62 +++++++++++++++++++++++++ 6 files changed, 225 insertions(+), 87 deletions(-) create mode 100644 printf.s create mode 100644 printn.s diff --git a/README.md b/README.md index 9f4fe64..167fa0b 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,10 @@ As a first step to test the interpreter and run some real programs, a minimal B library consisting of basic character, console and file handling was added to `/bi.c`. This replaces the assembly-language B library, which is given for reference in `/doc/libb`. Note that a few of the library calls (e.g. `printf`) -are compiled from B. At the moment, just a basic `printf()` is implemented in -`/bi.c`, and the full `printf()` will be installed later as interpreted code. +are compiled from B. At the moment we manually assemble these sources into any +program that needs them, but they have to be patched to avoid conflicts with +the Lnnn labels (because we do not use a linker and assemble `*.s` together). +To allow proper multiple-module B programs, we would have to use the linker. This was sufficient for Papenhoff's B compiler `/bc.b` and `/ba.b` to compile itself. I use Papenhoff's `/bc.s`, `/ba.s` for bootstrapping for now. See diff --git a/bi.c b/bi.c index 8499ea7..5d7113f 100644 --- a/bi.c +++ b/bi.c @@ -89,20 +89,18 @@ enum sys { SYS_LINK = (uint16_t)-80, SYS_MAKDIR = (uint16_t)-84, SYS_OPEN = (uint16_t)-88, - SYS_PRINTF = (uint16_t)-92, - SYS_PRINTN = (uint16_t)-96, - SYS_PUTCHAR = (uint16_t)-100, - SYS_QUIT = (uint16_t)-104, - SYS_READ = (uint16_t)-108, - SYS_SEEK = (uint16_t)-112, - SYS_SETUID = (uint16_t)-116, - SYS_SLEEP = (uint16_t)-120, - SYS_STAT = (uint16_t)-124, - SYS_STTY = (uint16_t)-128, - SYS_TIME = (uint16_t)-132, - SYS_UNLINK = (uint16_t)-136, - SYS_WAIT = (uint16_t)-140, - SYS_WRITE = (uint16_t)-144, + SYS_PUTCHAR = (uint16_t)-92, + SYS_QUIT = (uint16_t)-96, + SYS_READ = (uint16_t)-100, + SYS_SEEK = (uint16_t)-104, + SYS_SETUID = (uint16_t)-108, + SYS_SLEEP = (uint16_t)-112, + SYS_STAT = (uint16_t)-116, + SYS_STTY = (uint16_t)-120, + SYS_TIME = (uint16_t)-124, + SYS_UNLINK = (uint16_t)-128, + SYS_WAIT = (uint16_t)-132, + SYS_WRITE = (uint16_t)-136, }; #define MEM_BASE 0x4000 #define MEM_LIMIT SYS_WRITE @@ -339,13 +337,12 @@ int main(int argc, char **argv) { mem[((addr + 2) >> 1) & MEM_MASK] = OP_N7; } mem[((SYS_LCHAR + 2) >> 1) & MEM_MASK] = OP_N11; // void return - mem[((SYS_PRINTF + 2) >> 1) & MEM_MASK] = OP_N11; // void return // run - uint16_t arg0, arg1, arg2, len; + uint16_t arg0, arg1, arg2; temp = malloc(temp_size); mode_t mode; - uint8_t ch, octal[8]; // room for "-100000" + uint8_t ch; rassert(temp); while (true) { @@ -495,55 +492,6 @@ int main(int argc, char **argv) { #endif mem[(((r5 += 2) - 2) >> 1) & MEM_MASK] = data; break; - case (uint16_t)(SYS_PRINTF + 2): - r5 = r4 + 42; // s; 42 - arg0 = mem[((r4 + 4) >> 1) & MEM_MASK]; - addr = r4 + 6; // argument pointer -#if TRACE - fprintf(stderr, "printf(%04x, ...)\n", arg0); -#endif - size = temp_strlen(arg0) + 1; - temp_ensure(size); - temp_set(arg0, size); -#if TRACE - fprintf(stderr, "\"%s\"\n", temp); -#endif - for (uint8_t *p = temp; (ch = *p++) != 0; ) { - if (ch == '%') { - data = mem[(((addr += 2) - 2) >> 1) & MEM_MASK]; // argument - switch (ch = *p++) { - case 'c': - ch = data; - write(mem[(fout >> 1) & MEM_MASK], &ch, 1); - break; - case 'o': - write( - mem[(fout >> 1) & MEM_MASK], - octal, - (int16_t)data < 0 ? - sprintf((char *)octal, "-%o", -(int16_t)data) : - sprintf((char *)octal, "%o", (int16_t)data) - ); - break; - case 's': - len = temp_strlen(data); - temp_ensure(len + 1); - temp_set(data, len + 1); - write(mem[(fout >> 1) & MEM_MASK], temp, len); - temp_set(arg0, size); - break; - default: - fprintf(stderr, "fprintf() %%%c not implemented\n", ch); - exit(EXIT_FAILURE); - } - } - else - write(mem[(fout >> 1) & MEM_MASK], &ch, 1); - } - break; - case (uint16_t)(SYS_PRINTN + 2): - fprintf(stderr, "printn() not implemented\n"); - exit(EXIT_FAILURE); case (uint16_t)(SYS_PUTCHAR + 2): r5 = r4 + 6; // s; 6 arg0 = mem[((r4 + 4) >> 1) & MEM_MASK]; diff --git a/brt.s b/brt.s index ec7f32c..645036c 100644 --- a/brt.s +++ b/brt.s @@ -228,47 +228,41 @@ z = 54. / switch .globl .open .open = -88. -.globl .printf -.printf = -92. - -.globl .printn -.printn = -96. - .globl .putchar -.putchar = -100. +.putchar = -92. .globl .quit -.quit = -104. +.quit = -96. .globl .read -.read = -108. +.read = -100. .globl .seek -.seek = -112. +.seek = -104. .globl .setuid -.setuid = -116. +.setuid = -108. .globl .sleep -.sleep = -120. +.sleep = -112. .globl .stat -.stat = -124. +.stat = -116. .globl .stty -.stty = -128. +.stty = -120. .globl .time -.time = -132. +.time = -124. .globl .unlink -.unlink = -136. +.unlink = -128. .globl .wait -.wait = -140. +.wait = -132. .globl .write -.write = -144. +.write = -136. / fall through from chain init of last B file .globl chain diff --git a/n.sh b/n.sh index 0529094..8c8c82a 100755 --- a/n.sh +++ b/n.sh @@ -7,7 +7,7 @@ apout bin/as bc.s brt.s apout bin/strip a.out mv a.out bc -apout bin/as ba.s brt.s +apout bin/as ba.s printf.s printn.s brt.s apout bin/strip a.out mv a.out ba diff --git a/printf.s b/printf.s new file mode 100644 index 0000000..d373028 --- /dev/null +++ b/printf.s @@ -0,0 +1,132 @@ + jmp 9f + +.globl .printf +.printf: + .+2 + s; 42 + va; 36 + c; 0 + b1 + iva; 30 + va; 6 + b1 +XL1: +XL2: + s; 42 + va; 34 + x; .char + n2 + a; 4 + va; 36 + u7 + n3 + b1 + c; 45 + b5 + f; XL3 + ia; 34 + c; 0 + b4 + f; XL4 + n11 +XL4: + ix; .putchar + n2 + a; 34 + n3 + t; XL2 +XL3: + iva; 32 + va; 30 + u7 + u3 + b1 + iva; 34 + x; .char + n2 + a; 4 + va; 36 + u7 + n3 + b1 + z; XL5 +XL6=144 +XL7: +XL10=157 +XL11: + ix; .printn + n2 + a; 32 + a; 34 + c; 157 + b4 + f; XL12 + ic; 10 + t; XL13 +XL12: + ic; 12 +XL13: + n3 + ix; 7f+0 + n6 +XL14=143 +XL15: + ix; .putchar + n2 + a; 32 + n3 + ix; 7f+0 + n6 +XL16=163 +XL17: + iva; 40 + c; 0 + b1 +XL20: + iva; 34 + x; .char + n2 + a; 32 + va; 40 + u7 + n3 + b1 + c; 0 + b5 + f; XL21 + ix; .putchar + n2 + a; 34 + n3 + t; XL20 +XL21: + ix; 7f+0 + n6 + t; .+24 +XL5: + 4 + XL6 + XL7 + XL10 + XL11 + XL14 + XL15 + XL16 + XL17 + ix; .putchar + n2 + c; 45 + n3 + iva; 36 + u10 + iva; 30 + u10 + ix; 7f+0 + n6 + n11 +7: + XL1 + +9: jsr r5,chain + 0 +8: diff --git a/printn.s b/printn.s new file mode 100644 index 0000000..0828e4b --- /dev/null +++ b/printn.s @@ -0,0 +1,62 @@ + jmp 9f + +.globl .printn +.printn: + .+2 + s; 14 + va; 12 + c; 0 + b1 + ia; 4 + c; 0 + b7 + f; YL1 + iva; 4 + a; 4 + u2 + b1 + ia; 4 + c; 0 + b7 + f; YL2 + iva; 4 + u10 + iva; 12 + c; 1 + b1 + t; YL3 +YL2: + ix; .putchar + n2 + c; 55 + n3 +YL3: +YL1: + iva; 10 + a; 4 + a; 6 + b20 + b1 + f; YL4 + ix; .printn + n2 + a; 10 + a; 6 + n3 +YL4: + ix; .putchar + n2 + a; 4 + a; 6 + b16 + c; 60 + b14 + a; 12 + b14 + n3 + n11 +7: + +9: jsr r5,chain + 0 +8: -- 2.34.1