srcNext asks its own questions instead of calling for the answers

Two calls per character of every pass: numCompare to ask whether the
buffer is used up, and numStep to move one further into it. Inlined, the
compare settles almost every time on the high bytes and settles them
FIRST - a full block is 256, so SrcCount's high byte is one and SrcAt's
is nought until the last sixteenth of the block. Six instructions where
the call was twenty.

And the newline test uses A, which still holds the character, where it
used to fetch it back out of the SrcChar it had just been put in.

              before        after
  hello      586,184      574,737
  Say      4,506,702    4,333,689
  Files    7,188,351    6,863,744
  Keys    15,069,880   14,399,801
  cosmos 789,982,899  772,826,841

Two to four and a half per cent, which is worth having and is much less
than expected - AND THAT IS THE INTERESTING PART. It says the per
character cost is not in the reading. Now that comments no longer come
through here at all, what is left is the tokenizer above it, and the
remaining time is there rather than in getting the bytes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-09-06 21:43:29 -04:00
co-authored by Claude Opus 5
parent 2e9cb9af7e
commit 09c72e4951
+40 -10
View File
@@ -249,11 +249,29 @@ srcNext:
LDA.0 LDA.0
BNA srcAtEnd BNA srcAtEnd
; Is the buffer used up? SrcAt counts how far into it we have read and SrcCount how many ; ---- Is the buffer used up? ----
; of its bytes are the file's, which is 256 for every block but a short last one. ;
; SrcAt counts how far into it we have read and SrcCount how many of its bytes are the
; file's, which is 256 for every block but a short last one.
;
; ASKED HERE RATHER THAN BY numCompare, because this is the hottest question in the
; assembler - every character of every pass asks it - and a call to answer it costs more
; than the answer. The high bytes settle it almost every time and settle it FIRST: a full
; block is 256, so SrcCount's high byte is one and SrcAt's is nought until the last
; sixteenth of the block. Six instructions, where the call was twenty.
SETD.0 SrcAt SETD.0 SrcAt
SETD.2 SrcCount SETD.2 SrcCount
CALL numCompare LDA.0
LDB.2
CCF
SUB
BNQ srcHaveByte
INCD.0
INCD.2
LDA.0
LDB.2
CCF
SUB
BNQ srcHaveByte BNQ srcHaveByte
CALL srcLoad CALL srcLoad
BNQ srcAtEnd BNQ srcAtEnd
@@ -266,19 +284,31 @@ srcHaveByte:
STD.0.1 STD.0.1
SETD.0 SrcChar SETD.0 SrcChar
STA.0 STA.0
SETD.0 SrcAt
CALL numStep
; A newline is what makes the next character part of the next line. Counting it here, ; ---- A newline is what makes the next character part of the next line ----
; as it is handed out, means the line number always describes the character just given. ;
SETD.0 SrcChar ; Counted here, as the character is handed out, so the line number always describes the
LDA.0 ; character just given. A still holds it - nothing since the load has wanted it - where
; this used to fetch it back out of SrcChar it had just been put in.
INIB 0x0A INIB 0x0A
XOR XOR
BNQ srcNextDone BNQ srcNextStep
SETD.0 SrcLine SETD.0 SrcLine
CALL numStep CALL numStep
srcNextStep:
; And one further into the buffer, counted the same way and for the same reason.
SETD.0 SrcAt
INCD.0
LDA.0
INCA
STA.0
BNC srcNextDone
DECD.0
LDA.0
INCA
STA.0
srcNextDone: srcNextDone:
RSTA RSTA
RSTB RSTB