aboutsummaryrefslogtreecommitdiff
path: root/src/nextarg.s
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2026-04-06 01:36:32 -0400
committerB. Watson <urchlay@slackware.uk>2026-04-06 01:36:40 -0400
commit08bba9cd8f0dfd5269287331b2baae1c388d79dd (patch)
treef980b44554286790a35ededbae19f9cb3e925412 /src/nextarg.s
parent978af5db1f2189793d02d1c5a210e460a94dd345 (diff)
downloadfujinet-chat-08bba9cd8f0dfd5269287331b2baae1c388d79dd.tar.gz
Rewrite nextarg() in asm. 6643 bytes free.
Diffstat (limited to 'src/nextarg.s')
-rw-r--r--src/nextarg.s78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/nextarg.s b/src/nextarg.s
new file mode 100644
index 0000000..f01cc04
--- /dev/null
+++ b/src/nextarg.s
@@ -0,0 +1,78 @@
+
+ ; in C:
+
+;; /* arg points to something like:
+;; "part #channel I'm outta here\0"
+;; after nextarg(), arg points to "part\0" only, and ret points
+;; to "#channel I'm outta here\0". */
+;; char *nextarg(char *arg) {
+;; /* iterate over the first word */
+;; while(*arg && *arg != ' ')
+;; arg++;
+;;
+;; /* if we found a space, replace it with a null terminator */
+;; if(*arg)
+;; *arg++ = 0;
+;; else
+;; return 0; /* found no space, there's no next arg! */
+;;
+;; /* skip space(s) */
+;; while(*arg && *arg == ' ')
+;; arg++;
+;;
+;; if(*arg)
+;; return arg;
+;;
+;; return 0;
+;; }
+
+; ...which compiles to ~175 bytes. we can do better in asm.
+
+ .export _nextarg
+ .importzp ptr1
+
+incptr1:
+ inc ptr1
+ bne @ret
+ inc ptr1+1
+@ret:
+ rts ; always returns with Z flag clear (unless we roll over $FFFF -> 0!)
+
+_nextarg:
+ sta ptr1
+ stx ptr1+1
+
+ ldy #0 ; actually this stays 0 the while time
+
+ ; skips over the first word (aka sequence of non-spaces)
+@skipword:
+ lda (ptr1),y
+ beq @ret0 ; found a null byte, return null (there is no next arg).
+ cmp #' '
+ beq @foundspc
+ jsr incptr1
+ bne @skipword ; branch always
+
+@foundspc:
+ ; ptr1 now points to a space.
+ tya ; 0
+ sta (ptr1),y ; null out the space
+
+ jsr incptr1
+@skipspc:
+ lda (ptr1),y
+ beq @ret0 ; found a null byte, return null (there is no next arg).
+ cmp #' '
+ bne @done
+ jsr incptr1
+ bne @skipspc
+
+@done:
+ lda ptr1
+ ldx ptr1+1
+ rts
+
+@ret0:
+ lda #0
+ tax
+ rts