summary refs log tree commit diff
path: root/quine.asm
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-05-03 18:43:37 -0700
committerIrene Knapp <ireneista@irenes.space>2026-05-03 18:43:37 -0700
commitcf4e6a88a19d8bbe42f0e41c1d9168009d3addab (patch)
tree551b1c74a8f867fd1e6630209b120e6e0d7880e2 /quine.asm
parentcb555fc1884824fc7c0e9de7cb3e04b61f623838 (diff)
the heavy lifting of refilling a circular buffer is implemented now
it's not hooked up to the read logic yet, and some of the finicky cases aren't fully tested yet because it will be necessary to alternate reads and refills a bit to exercise them.

Force-Push: yes
Change-Id: Ic7442787068ea4ae985832ae597531d7d7bdcea9
Diffstat (limited to 'quine.asm')
-rw-r--r--quine.asm126
1 files changed, 114 insertions, 12 deletions
diff --git a/quine.asm b/quine.asm
index 806616b..3abbfc9 100644
--- a/quine.asm
+++ b/quine.asm
@@ -6258,20 +6258,13 @@ cold_start:
   dq lit, 5*8, early_comma
   dq litstring, "+", early_find, entry_to_execution_token, early_comma
   ; (capacity in bytes, metadata pointer, metadata pointer, physical start)
-  dq litstring, "dup", early_find, entry_to_execution_token, early_comma
-  dq litstring, "3unroll", early_find, entry_to_execution_token, early_comma
   dq litstring, "swap", early_find, entry_to_execution_token, early_comma
   dq litstring, "buffer-physical-start", early_find, entry_to_execution_token
   dq early_comma
   dq litstring, "!", early_find, entry_to_execution_token, early_comma
-  ; (capacity in bytes, metadata pointer, physical start)
-  dq litstring, "swap", early_find, entry_to_execution_token, early_comma
+  ; (capacity in bytes, metadata pointer)
   dq litstring, "dup", early_find, entry_to_execution_token, early_comma
   dq litstring, "3unroll", early_find, entry_to_execution_token, early_comma
-  dq litstring, "buffer-logical-start", early_find, entry_to_execution_token
-  dq early_comma
-  dq litstring, "!", early_find, entry_to_execution_token, early_comma
-  ; (capacity in bytes, metadata pointer)
   dq litstring, "buffer-physical-length", early_find, entry_to_execution_token
   dq early_comma
   dq litstring, "!", early_find, entry_to_execution_token, early_comma
@@ -8628,6 +8621,9 @@ defword sys_write, 0
   next
 
 
+; In:
+;   length
+;   address
 defword sys_read, 0
   dq $ + 8
   pop.qreg rcx                   ; address from stack
@@ -11330,10 +11326,110 @@ defword boot_source, 0x40
   dq "  entry-to-name s"" docol"" stringcmp 0 = ;                       "
 
 
+  ;   If the buffer is empty, make sure its logical position is at the
+  ; physical start. Otherwise, leave it alone.
+  ;
+  ; In:
+  ;   pointer to buffer metadata
+  dq ": normalize-buffer                                              "
+  dq "  dup buffer-logical-length @ 0 =                               "
+  dq "  { dup buffer-physical-start @ swap                            "
+  dq "    buffer-logical-start ! } { drop } if-else                   "
+  dq "  ;                                                             "
+
+
+  ;   Find the next contiguous area of a buffer to write incoming data to.
+  ; This will begin at the logical end. Depending on the order things are in,
+  ; the available space might run from there to the physical end, or to the
+  ; logical start. Those are the only two possibilities.
+  ;
+  ;   If the buffer is full, this will return as normal but the length will
+  ; be zero. The caller should make sure to respect that.
+  ;
+  ; In:
+  ;   pointer to buffer metadata
+  ; Out:
+  ;   destination start
+  ;   destination length
+  dq ": compute-next-buffer-free-block                                "
+  dq "  dup buffer-physical-start @ swap dup buffer-physical-length @ "
+  dq "  swap 3unroll + swap                                           "
+  ; (physical end, metadata pointer)
+  dq "  dup buffer-logical-start @ swap dup buffer-logical-length @   "
+  dq "  swap 3unroll + swap 3unroll                                   "
+  ; (metadata pointer, physical end, logical end not yet wrapped)
+
+  dq "  2dup >=                                                       "
+  dq "  {                                                             "
+  ;   If the logical end is greater than or equal to the physical end, find
+  ; where it wraps to and start from there.
+  dq "    - swap dup buffer-physical-start @ swap 3unroll +           "
+  ; (metadata pointer, destination start)
+  ;   In this scenario, the logical start is the end of the free space, so
+  ; compute how far away it is.
+  dq "    dup 3roll                                                   "
+  ; (destination start, destination start, metadata pointer)
+  dq "    dup buffer-logical-start @ swap drop swap - }               "
+
+  dq "  {                                                             "
+  dq "    dup 3roll swap -                                            "
+  ;   If the logical end is less than the physical end, it is the destination;
+  ; the physical end is also the end of the free space, so compute how far
+  ; away it is.
+  dq "    } if-else                                                   "
+  ; (metadata pointer, destination start, destination length)
+  dq "  ;                                                             "
+
+
+
+  ; In:
+  ;   pointer to buffer metadata
+  dq ": refill-input-buffer-from-stdin                                "
+  dq "  dup normalize-buffer                                          "
+  dq "  compute-next-buffer-free-block                                "
+  ;   Check whether the buffer is full. If not, do a read. If so, that's not
+  ; an error, just clean up and take no action.
+  dq "  dup { swap sys-read                                           "
+  dq "        dup -2 =                                                "
+  dq "        { drop drop s"" Read error."" emitstring 0 sys-exit }     "
+  dq "        { swap dup buffer-logical-length @ 3roll +              "
+  dq "          swap buffer-logical-length ! } if-else }              "
+  dq "      { drop drop } if-else ;                                   "
+
+
+; TODO this is the step for after refilling works
+;  dq ": relink-main-input-buffer-to-stdin                             "
+;  dq "  1024 allocate-input-buffer main-input-buffer !                "
+;  dq "  ' refill-input-buffer-from-stdin entry-to-execution-token     "
+;  dq "  main-input-buffer @ input-buffer-refill !                     "
+;  dq "  main-input-buffer @ hexdump bye                               "
+;  dq "  ;                                                             "
+;  ; In:
+;  ;   pointer to buffer metadata
+;  dq ": attach-stdin-to-input-buffer                                  "
+;  dq "  dup buffer-physical-start here swap !                         "
+;  ; (metadata pointer)
+;  dq "  dup buffer-physical-end here 1024 + dup here ! swap !         "
+;  ; (metadata pointer)
+;  dq "  dup buffer-physical-start @ swap dup 3unroll                  "
+;  dq "  buffer-logical-start !                                        "
+;  dq "  dup buffer-physical-end @ swap dup 3unroll                    "
+;  dq "  buffer-logical-end !                                          "
+;  dq "  hexdump ;                                                     "
+;
+;  dq "main-input-buffer @ attach-stdin-to-input-buffer bye            "
+;  dq "relink-main-input-buffer-to-stdin                               "
+;  dq ": hmm 16 here sys-read stack here hexdump ; hmm                 "
+
+
   ;   The word named "docol" has the job of returning the value that gets used
-  ; as the actual codeword. We make the assumption that, if so, the codeword
-  ; will point somewhere near the entry header; we allow for the possibility
-  ; that it might be before or after.
+  ; as the actual codeword. We make the assumption that the codeword will
+  ; point somewhere near the entry header; we allow for the possibility that
+  ; it might be before or after.
+  ;
+  ;   Generally, it's possible for there to be several copies of docol due to
+  ; alternate heaps and things like that, so the goal is to recognize any of
+  ; them.
   dq ": is-docol-codeword                                             "
   dq "  dup is-in-heap { drop 0 exit } unless                         "
   dq "  containing-entry dup                                          "
@@ -11432,8 +11528,14 @@ defword boot_source, 0x40
   ;dq "68719587456     containing-entry stackhex                       "
   ;dq "587456     containing-entry stackhex                            "
   ;dq "68719607808 containing-entry stackhex                           "
-  dq "list-dictionary                                                 "
+  ;dq "list-dictionary                                                 "
   ;dq "describe-all                                                    "
+  dq ": doittoit 16   allocate-input-buffer                           "
+  dq "  dup stackhex refill-input-buffer-from-stdin                   "
+  dq "  stackhex dup 256 hexdump-from                                 "
+  dq "  dup refill-input-buffer-from-stdin                            "
+  dq "  stackhex dup 256 hexdump-from                                 "
+  dq "  bye ; doittoit                                                "
   dq "                                                                "
 
   ; TODO define ( ... ) comments