-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathccirc.asm
1434 lines (1270 loc) · 23.6 KB
/
ccirc.asm
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;;;
;;; CCIRC - CoCo IRC Client for CoCo3
;;;
;;;
include yados.def ; YA-DOS definitions
;;; Colors
WHITE equ 0 ; white
RED equ 1 ; red
BLUE equ 2 ; blue
GREEN equ 3 ; green
CYAN equ 4 ; cyan
MAGENTA equ 5 ; magenta
YELLOW equ 6 ; yellow
GRAY equ 7 ; grey
;;; Screen buffer struct
org $0
SCRBEG rmb 2 ; beginning of memory buffer
SCRPOS rmb 2 ; screen buffer memory position
SCRX rmb 1 ; screen buffer X position
SCRY rmb 1 ; screen buffer Y position
SCRM rmb 1 ; max lines in buffer
SCRC rmb 1 ; if there's a cursor
SCRA rmb 1 ; current screen attributes
SCRZ equ * ; size of struct
org $1000 ; start of this program
DBUF0 equ $600
CR equ $d
BS equ $8
;;;
;;; Ram Variables
;;;
drvNo .db 0 ; device no (for YA-DOS)
DWRead .dw YDWRead ; DWRead vector
DWWrite .dw YDWWrite ; DWWrite vector
;;; This is the server input buffer
ibuff rmb 512 ; input buffer
ipos .dw ibuff ; input buffer position
;;; this is a transmit buffer to DW
dwbuf .db $64,$1 ; write to port 1
dwno rmb 1 ; number of bytes
xmitb rmb 256 ; transmit buffer
xpos .dw xmitb ; xmit buffer position
;;; this is the keyboard output buffer
obuff rmb 512 ; output buffer
opos .dw obuff ; output buffer position
mbuf rmb SCRZ ; main window buffer
kbuf rmb SCRZ ; keyboard window
sbuf rmb SCRZ ; status window
dwsq .db 0 ; DW poll sqelch
timer rmb 2 ; timer value
chan rmb 16 ; saved channel string
nick rmb 16 ; saved nickname
word rmb 512 ; command word buffer
ppos rmb 2 ; parse input pointer
cpl .db 80 ; Charactors per line
attr .db 0
start
;; clear global string
clr chan
clr nick
clr word
;; check for CoCo3
ldb $fffc ; get MSB of NMI Vector
cmpb #$fe ; is coco3?
lbne err@ ; no then error
;; check for YA-DOS
ldd $d930 ; get MSW of Magic
cmpd #$5941 ; is "YA" ?
bne a@ ; no then check for next flavor
ldd $d932 ; get LSW of Magic
cmpd #$4453 ; is "DS" ?
bne a@ ; no then check for next flavor
ldb #0 ; B = Drivewire device
SCALL SDWSETUP ; set it up
bcs err@
bra cont@ ; continue with setup
;; check for HDBDOS
a@ ldb $C101 ; check a patch
cmpb #$12 ; is it a NOP?
bne b@ ; no then check for next flavor
ldd $d93f ; get DWRead vector
std DWRead ; store as our vector
ldd $d941 ; get DWWrite vector
std DWWrite ; store as out vector
bra cont@
;; check for SDC-DOS
b@ ldd $dffe ; check rom for signature
cmpd #$0203
bne err@ ; first word doesn't match
ldd $dff0
std DWRead
ldd $dff2
std DWWrite
cont@ ;; setup keyboard
clr $11a ; lower case
;; setup main window screen
jsr scrInit
ldx #mbuf ; main window buffer
ldu #$6000 ; start of window
ldb #21 ; 23 lines
jsr bufIni ; initialize buffer
;; setup status screen
ldx #sbuf ; status buffer
lda #21
ldb cpl
lslb
mul
addd #$6000
tfr d,u
ldb #1
jsr bufIni
jsr drawStatus
;; setup keyboard screen
ldx #kbuf ; keyboard buffer
lda #22
ldb cpl
lslb
mul
addd #$6000
tfr d,u
ldb #2 ; 2 lines
jsr bufIni
clr SCRC,x
com SCRC,x
;; Setup DW device
jsr DWOpen ; open port
;; send a command
c@ jsr getKey ; get keys
;; get result
jsr DWReply ; get from dw
bra c@
;; return
err@ rts ; return to basic
;;; Set screen buffer forground attributes
;;; takes: X = screen struct ptr, B = color number
;;; returns: nothing
bufFcolor
pshs b
lslb ; shift arg to fg bits pos
lslb
lslb
pshs b ; save on stack
ldb SCRA,x ; b = attribute bytes
andb #$c7 ; mask off foreground bits
orb ,s+ ; set fg bits from stack
stb SCRA,x ; save in attribute bytes
puls b,pc ; return
;;; Print a space to screen buffer
;;; takes: X = screen struct ptr
;;; returns: nothing
bufSpace
pshs b
ldb #$20
jsr bufPrint
puls b,pc
;;; Print a CR to screen buffer
;;; takes: X = screen struct ptr
;;; returns: nothing
bufCR
pshs b
ldb #CR
jsr bufPrint
puls b,pc
;;; Print byte to a screen buffer
;;; takes: X = screen struct ptr, B = byte
;;; returns: nothing
bufPrint
pshs d,u
jsr bufScursor
cmpb #CR
beq cr@ ; go do cr
cmpb #BS
beq bs@
;; convert underscore
cmpb #$5f ; underscore?
bne c@ ; no then no translate
ldb #127
c@ ldu SCRPOS,x ; U = screen position
stb ,u+
ldb SCRA,x
stb ,u+
stu SCRPOS,x ; save new screen position
;; increment X position
ldb SCRX,x ; get position
incb ; increment
cmpb cpl ; past last column?
beq incy@ ; no past last column
stb SCRX,x ; save position
bra out@ ; return
;; increment Y position
incy@ clr SCRX,x ; reset column
ldb SCRY,x ; get line post
incb ; increment it
cmpb SCRM,x ; on max line?
beq scroll@ ; go scroll
stb SCRY,x ; save it
bra out@
;; Scroll
scroll@
ldu SCRBEG,x ; begining of screen
;; move M-1 lines
lda SCRM,x ; lines
deca ; lines - 1
ldb cpl
lslb
mul ; D = number of bytes to move
addd SCRBEG,x ; posititon to stop at
pshs d ; push onto stack
a@ ldb 160,u ; get byte from next line
stb ,u+ ; put here and increment
cmpu ,s ; at end?
bne a@ ; nope do again
puls d ; drop stop address
;; clear out last line
lda cpl
b@ ldb #$20
stb ,u+
ldb SCRA,x
stb ,u+
deca
bne b@
;; reset position
ldu SCRPOS,x ; X = old position
leau -160,u
stu SCRPOS,x ; new position
;; put cursor and leave
out@ jsr bufScursor
puls d,u,pc ; restore, return
;; do a CR
cr@ clra
ldb cpl ; D = 80
subb SCRX,x ; subtract to get remaining chars in line
lslb ; convert to position
addd SCRPOS,x ; add to position to get new position
std SCRPOS,x ; store it
bra incy@ ; and increment y
;; do a BS
bs@ ldu SCRPOS,x ; D = screen position
cmpu SCRBEG,x ; are we at beginning?
beq out@ ; yes then do nothing!
leau -2,u ; else adjust screen pos
stu SCRPOS,x ;
ldb #$20
stb ,u+
ldb SCRA,x
stb ,u
dec SCRX,x ; adjust X
bmi bsy@ ;
bra out@
bsy@ ldb cpl
decb
stb SCRX,x ; reset X
dec SCRY,x ; decrement y
bra out@
;;; Initializes a screen buffer
;;; Takes: X = screen struct ptr, B = lines, U=screen begining
;;; returns: nothing
bufIni
stu SCRBEG,x
clr SCRC,x
stb SCRM,x
bsr bufClear
rts
;;; Print a Zstring to buffer w/ word wrap
;;; takes: X = screen struct ptr, U = string to print
;;; returns: nothing
bufWWString
pshs d,x,u
stu ppos
a@ jsr getWord ; get a white-space string
ldx #word
jsr strlen ; B = string length
beq ret@ ; zero string length - return
ldx 2,s ; get buffer pointer
addb SCRX,x ; add string length to X position
bcs cr@ ; overflow then do a CR
subb cpl ; subtract charactors per line
bcc cr@ ; overflow then do a CR
;; no wrap so just print it
b@ ldu #word
jsr bufString ; print it
jsr bufSpace
bra a@
;; wrap so do a CR first
cr@ jsr bufCR
jsr bufSpace
jsr bufSpace
bra b@ ; and print string normally
ret@ puls d,x,u,pc
;;; Prints a Zstring to buffer
;;; Takes: X = screen struct ptr, U = string pointer
;;; returns: nothing
bufString
pshs b,u
a@ ldb ,u+
beq out@
jsr bufPrint
bra a@
out@ puls b,u,pc
;;; Clear buffer
;;; takes: X = screen struct ptr
;;; returns: nothing
bufClear
pshs d,u
jsr bufScursor
clr SCRA,x
lda cpl
lsla
ldb SCRM,x
mul
addd SCRBEG,x
pshs d
lda #$20
ldb SCRA,x
ldu SCRBEG,x
a@ std ,u++
cmpu ,s
bne a@
puls d
ldu SCRBEG,x
stu SCRPOS,x
clr SCRX,x
clr SCRY,x
jsr bufScursor
puls d,u,pc
bufScursor
pshs b,u
tst SCRC,x ; does window have a cursor?
beq out@
ldu SCRPOS,x
ldb 1,u
eorb #$3f
stb 1,u
out@ puls b,u,pc
;;; Possibly get key from keyboard
getKey
jsr $a1cb ; A = get a key?
beq out@ ; no key leave
cmpa #BS
beq bs@ ; is a BS?
cmpa #CR
beq cr@ ; is a CR?
cmpa #$15
beq wbs@ ; is a Shift-left
;; add to output buffer
ldu opos
sta ,u+
stu opos
echo@ tfr a,b
ldx #kbuf
jsr bufPrint
out@ rts
;; handle backspace
bs@ ldu opos ; backspace buffer
cmpu #obuff ; equal to output buff?
beq out@ ; yes - don't do anything
leau -1,u ; move back
stu opos
bra echo@
;; handle CR (send to DW)
cr@ ldu opos
clr ,u+
stu opos
jsr parse
ldd #obuff ; reset output buffer
std opos
ldx #kbuf ; point to keyboard window
jsr bufClear ; clear it
bra out@
;; handle a word erase (shift-left)
wbs@ ; remove "leading" spaces
ldu opos
cmpu #obuff
beq out@
ldb ,-u
cmpb #$20
bne a@
lda #BS
bsr bs@
bra wbs@
;; remove non spaces
a@ ldu opos
cmpu #obuff
beq out@
ldb ,-u
cmpb #$20
beq b@
lda #BS
bsr bs@
bra a@
;; remove trailing spaces
b@ ldu opos
cmpu #obuff
beq out@
ldb ,-u
cmpb #$20
bne out@
lda #BS
bsr bs@
bra b@
;;; Initialize Screen
scrInit
;; setup gimme
ldb #$4c ; coco 3 graphics (reset to $CC)
stb $ff90
ldb #$03 ; text-mode
stb $ff98
* ldb #$54 ; 80 column, no attrib
ldb #$15 ; 80 column, w/ attributes
stb $ff99
ldd #$ec00 ; $6000 ($76000)
std $ff9d
ldb #0
stb $ffb0
ldb #$ff
stb $ffb8
;; setup colors
ldu #rgbpal
setpal ldx #$ffb8
lda #8
a@ ldb ,u+
stb ,x+
deca
bne a@
rts
;; RGB color table
rgbpal .db 63 ; White
.db 32 ; Red
.db 8 ; Blue
.db 16 ; Green
.db 24 ; Cyan
.db 40 ; Magenta
.db 48 ; yellow
.db 7 ; Gray
;; Composite Table
cmppal .db 48 ; White
.db 23 ; Red
.db 28 ; Blue
.db 34 ; Green
.db 30 ; Cyan
.db 25 ; Magenta
.db 20 ; yellow
.db 16 ; Gray
;;;
;;;
;;; Drivewire routines
;;;
;;;
;;; Open Vport
DWOpen
ldx #0x0129
ldb #0xc4
pshs b,x
tfr s,x
ldy #3
* SCALL SDWWRITE
jsr [DWWrite]
leas 3,s
rts
;;; Close Vport
DWClose
ldx #0x012a
ldb #0xc4
pshs b,x
tfr s,x
ldy #3
* SCALL SDWWRITE
jsr [DWWrite]
leas 3,s
rts
;;; Send input buffer to DW
DWSend
;; calc buffer size
ldd opos ; D = end
subd #obuff ; subtract start = size
stb dwno ; save in packet
;; send buffer to DW
addd #3 ; add three byte packet
tfr d,y ; number of byte to send in Y
ldx #dwbuf ; buffer
* SCALL SDWWRITE ; send!
jsr [DWWrite]
;; reset output buffer
ldd #obuff ; D = start
std opos ; save to pos pointer
;; cls screen
rts ; return
;; Print reply from DW
DWReply
tst dwsq ; are we squelching?
beq cont@ ; no then read
ldd timer ; get timer
cmpd $112 ; are we bigger?
bcc ret@ ; not time just return
com dwsq ; turn off squalching and read
cont@ lda #0x43 ; Poll/Read op code
pshs d ; push onto stack
tfr s,x ; setup for DW write
ldy #1 ;
* SCALL SDWWRITE ; send to DW
jsr [DWWrite]
tfr s,x ; setup for read status
ldy #2
* SCALL SDWREAD ; get status bytes
jsr [DWRead]
bcs err2@ ; error on timeout
bne err2@ ; error on framing
lda ,s ; get byte1
bne e@ ; branch if not zero
;; return nothing to read
puls d ; drop stack buffer
com dwsq ; squelch dw poller
ldd $112 ; get time
addd #30 ; squelch for 30 ticks
bcc a@ ; if no carry then ok to set
;; timer overflowed, skip squelch
com dwsq ; turn squelching off
a@ std timer ; save squelch time
ret@ rts ; return
;; something to read
e@ clr dwsq ; turn off squelching
cmpa #16 ; compare to #16
blo sin@ ; is lower than a single byte read
bhi mul@ ; is higher than multi byte read
;; close port & return
;; closing the port is not specified by DW
;; but DW will hang if we don't
puls d ; is same so close port
jsr DWClose
jsr DWOpen
rts
;; receive a single byte
sin@ puls d
jsr ibufput
rts ; return
;; receive multiple bytes
mul@ clr ,s
inc ,s
lda #0x63
pshs a
tfr s,x
ldy #3
* SCALL SDWWRITE
jsr [DWWrite]
ldx #DBUF0
ldb 2,s
clra
tfr d,y
* SCALL SDWREAD
jsr [DWRead]
bcs err3@
bne err3@
puls cc,d
exg a,b
ldx #DBUF0
d@ ldb ,x+
jsr ibufput
deca
bne d@
rts ; return
err3@ leas 1,s
err2@ leas 2,s
rts
YDWRead
SCALL SDWREAD
rts
YDWWrite
SCALL SDWWRITE
rts
;;;
;;;
;;; IRC Command routines
;;;
;;;
;;; Command name vector table
tserver fcn "server"
tjoin fcn "join"
tuser fcn "user"
tme fcn "me"
tquit fcn "quit"
tnick fcn "nick"
tmsg fcn "msg"
tnames fcn "names"
tcmp fcn "cmp"
trgb fcn "rgb"
texit fcn "exit"
cmdtab .dw tserver
.dw cserver
.dw tjoin
.dw cjoin
.dw tuser
.dw cuser
.dw tme
.dw cme
.dw tquit
.dw cquit
.dw tnick
.dw cnick
.dw tmsg
.dw cmsg
.dw tnames
.dw cnames
.dw tcmp
.dw ccmp
.dw trgb
.dw crgb
.dw texit
.dw cexit
.dw 0
;;; Get a command word from input buffer
;;; takes: ppos=start of input buffer
;;; returns: word=parsed command
getWord pshs d,x,u
ldx ppos ; X = start of output buffer
ldu #word ; start of word buffer
;; remove spaces
b@ ldb ,x ; get byte
beq out@ ; is zero copy byte
cmpb #$20 ; is space or less?
bhi a@ ; no then copy bytes
leax 1,x ; yes then get next byte
bra b@
;; copy byte to word buffer
a@ ldb ,x ; get a byte
cmpb #$20 ; is space (or less?)
bls out@ ; done!
stb ,u+
leax 1,x
bra a@
out@ clr ,u ; put a zero in word buffer
stx ppos ; save parse position
puls d,x,u,pc ; restore return
;;; Compares two strings
;;; takes: X=string, U=string
;;; returns: Z set on string equality
strcmp pshs d,x,u
a@ ldb ,x+
cmpb ,u+
bne out@
tstb
beq out@
bra a@
out@ puls d,x,u,pc
;;; Find length of string
;;; takes: X=string
;;; returns: B = size of string
strlen pshs x
clrb
a@ tst ,x+
beq out@
incb
bra a@
out@ tstb
puls x,pc
;;; Append string xmit buffer
;;; takes: X = ptr to string
appString
pshs b,x,u
;; copy to xmit buffer
ldu xpos ; transmit buffer
a@ ldb ,x+
beq out@
stb ,u+
bra a@
out@ stu xpos ; save buffer pos
puls b,x,u,pc ; return
;;; Append a byte to xmit buffer
appByte
pshs u
ldu xpos
stb ,u+
stu xpos
puls u,pc
;;; Append a space to xmit buffer
appSpace
pshs b
ldb #$20
bsr appByte
puls b,pc
;;; Append crlf to xmit buffer
appCRLF
pshs b
ldb #CR
bsr appByte
ldb #$a
bsr appByte
puls b,pc
;;; send xmit buffer to DW
send
pshs d,x,y
ldd xpos ; end address
subd #xmitb ; sub start address; D = length
stb dwno ; save length in xmit prefix
addd #3 ; add 3 to length = total DW length
tfr d,y ; put in Y
ldx #dwbuf ; X = DW packet buffer
* SCALL SDWWRITE ; send to DW
jsr [DWWrite]
;; reset xmit buffer
ldd #xmitb
std xpos
puls d,x,y,pc
parse
ldb obuff ; get first char
beq empty@ ; empty string do not process
cmpb #'/ ; is a command?
beq command ; go parse command
;; echo to main window
ldx #mbuf
ldb #GREEN
jsr bufFcolor
ldu #nick
jsr bufString
jsr bufSpace
ldb #WHITE
jsr bufFcolor
ldu #obuff
jsr bufWWString
jsr bufCR
;; send privmsg
ldx #privmsg@
jsr appString
jsr appSpace
ldx #chan
jsr appString
jsr appSpace
ldb #':
jsr appByte
ldx #obuff
jsr appString
jsr appCRLF
jmp send
empty@ rts
privmsg@ fcn "PRIVMSG "
;;; find command in table
command
ldd #obuff+1 ; set parse pos to after "/"
std ppos
jsr getWord ; parse word into buffer
ldu #word ; U = word buffer
ldy #cmdtab ; first command
a@ ldx ,y ; X is string pointer
beq err@ ; end of table
jsr strcmp ; match?
beq match@ ; yup
leay 4,y ; goto next command
bra a@
match@ ldy 2,y ; get vector
jmp ,y ; jmp to it!
;; else just pass through!
err@ ldx #obuff+1
jsr appString
ldb #CR
jsr appByte
jmp send
;; /server command
cserver
ldx #p@
jsr appString
jsr getWord ; parse hostname
ldx #word
jsr appString
jsr appSpace
jsr getWord ; parse tcp port
tst ,x ; is null?
bne a@
ldx #p1@ ; get default port
a@ jsr appString ; append port number
ldb #CR
jsr appByte
jmp send
p@ fcn "tcp connect "
p1@ fcn "6667"
;; /join command
cjoin
ldx #obuff+1
jsr appString
jsr appCRLF
jsr send
;; get channel name
jsr getWord
ldx #word ; source is parse position
ldu #chan ; dest is chan name buffer
a@ ldb ,x+
stb ,u+
bne a@
jsr drawStatus
rts
;; /user command (/user name nick)
cuser ; send user command
ldx #p1@
jsr appString
jsr getWord
ldx #word
jsr appString
ldx #p2@
jsr appString
ldx #word
jsr appString
jsr appCRLF
jsr send
;; send nick command
ldx #p3@
jsr appString
jsr getWord
ldx #word
jsr appString
;; copy nick to saved buffer
ldu #nick
a@ ldb ,x+
stb ,u+
bne a@
;; continue building nick command
jsr appCRLF
jsr send
jmp drawStatus
p1@ fcn "USER "
p2@ fcn " 0 * "
p3@ fcn "NICK "
;; /me action
cme ldx #privmsg@
jsr appString
jsr appSpace
ldx #chan
jsr appString
jsr appSpace
ldb #':
jsr appByte
ldx #p2@
jsr appString
ldx ppos
jsr appString
ldb #1
jsr appByte
jsr appCRLF
jmp send
privmsg@ fcn "PRIVMSG "
p2@ .db $1
fcn "ACTION"
;; /msg action
cmsg ldx #p1@
jsr appString
jsr getWord
ldx #word
jsr appString
jsr appSpace
ldb #':
jsr appByte
ldx ppos
jsr appString
jsr appCRLF
jsr send
;; print to output
ldx #mbuf
ldb #RED
jsr bufFcolor
ldu #p2@
jsr bufString
ldu #obuff
stu ppos
jsr getWord ; parse off "/msg"
jsr getWord ; parse off "nick"
ldu #word ; print nick
jsr bufString
jsr bufSpace
ldb #WHITE
jsr bufFcolor
ldu ppos ; point to message after nick
jsr bufWWString ; print
jmp bufCR ;
p1@ fcn "PRIVMSG "
p2@ fcn "!!!->"
;; /quit action
cquit ; send quit message
ldx #p@
jsr appString
ldb #':
jsr appByte
ldx ppos
leax 1,x ; skip space
jsr appString
jsr appCRLF
jsr send
;; and close connect to server
jsr DWClose ; close DW vport
jsr DWOpen ; reopen DW vport
;; reset status line
clr nick
clr chan
jsr drawStatus
rts ; return to BASIC
p@ fcn "QUIT "
;; /nick action
cnick ; send whole string minus / to server
ldx #obuff
leax 1,x
jsr appString ; append whole string
jsr appCRLF
jsr send
;; rip nickname from string
jsr getWord ; get nickname
ldx #word
ldu #nick
a@ ldb ,x+
stb ,u+
bne a@