aboutsummaryrefslogtreecommitdiff
path: root/src
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
parent978af5db1f2189793d02d1c5a210e460a94dd345 (diff)
downloadfujinet-chat-08bba9cd8f0dfd5269287331b2baae1c388d79dd.tar.gz
Rewrite nextarg() in asm. 6643 bytes free.
Diffstat (limited to 'src')
-rw-r--r--src/cmd.c25
-rw-r--r--src/irc.h4
-rw-r--r--src/nextarg.s78
3 files changed, 81 insertions, 26 deletions
diff --git a/src/cmd.c b/src/cmd.c
index f0a6d8a..8a59512 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -119,31 +119,6 @@ static void err_no_scr_target(void) {
scr_print_current("No channel/nick for screen\n");
}
-/* 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;
-}
-
static char have_commas(void) {
if(strchr(arg1, ',')) {
err_marker();
diff --git a/src/irc.h b/src/irc.h
index 3171033..bb1d695 100644
--- a/src/irc.h
+++ b/src/irc.h
@@ -66,7 +66,6 @@ void __fastcall__ bell(void); /* see src/bell.s */
void start_keystroke(char c);
/**** cmd.c */
-char *nextarg(char *arg);
void cmd_command(char *cmd);
void cmd_execute(void);
void cmd_rejoin_chans(void);
@@ -81,3 +80,6 @@ extern char __fastcall__ isnum(char c);
/* see a2uint.s */
extern unsigned int __fastcall__ a2uint(char *str);
+
+/* nextarg.s */
+extern char *nextarg(char *arg);
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