aboutsummaryrefslogtreecommitdiff
path: root/src/nextarg.s
diff options
context:
space:
mode:
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