Install the full printf() and printn(), patched to avoid Lnnn label conflicts master
authorNick Downing <nick@ndcode.org>
Tue, 2 Jan 2024 00:50:12 +0000 (11:50 +1100)
committerNick Downing <nick@ndcode.org>
Tue, 2 Jan 2024 00:53:30 +0000 (11:53 +1100)
README.md
bi.c
brt.s
n.sh
printf.s [new file with mode: 0644]
printn.s [new file with mode: 0644]

index 9f4fe64..167fa0b 100644 (file)
--- 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 (file)
--- 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 (file)
--- 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 (executable)
--- 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 (file)
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 (file)
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: