aboutsummaryrefslogtreecommitdiff
path: root/src/nextarg.s
blob: f01cc04b974dd5d1d1571d894c5a0a30a6901d96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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