NEW AUTO 3,1 .LIST OFF .OP 65C02 .OR $2000 .TF bin/irc *-------------------------------------- .INB inc/macros.i .INB inc/a2osx.i .INB inc/mli.i .INB inc/eth.i .INB inc/libtcpip.i *-------------------------------------- TIMEOUT.MAX .EQ 200 20 sec. MSGSIZE .EQ 1024 TEXTMAX .EQ 240 *-------------------------------------- * https://tools.ietf.org/html/rfc2812#section-3.3 *-------------------------------------- .DUMMY .OR ZPBIN ZS.START ZPPtr1 .BS 2 hSocket .BS 1 hFile .BS 1 hLineBuf .BS 1 ZPLineBufPtr .BS 2 TextPtr .BS 1 TextLen .BS 1 hText .BS 1 ZPTextPtr .BS 2 bEscMode .BS 1 TimeOut .BS 1 bJoin .BS 1 hMsgBuf .BS 1 ZPMsgPtr .BS 2 ZPMsgPfxPtr .BS 2 ZPMsgCmdPtr .BS 2 ZPMsgArgPtr .BS 2 ZPMsgExtPtr .BS 2 ZS.END .ED *-------------------------------------- * File Header (16 Bytes) *-------------------------------------- CS.START cld jmp (.1,x) .DA #$61 6502,Level 1 (65c02) .DA #1 BIN Layout Version 1 .DA #S.PS.F.EVENT S.PS.F .DA #0 .DA CS.END-CS.START Code Size (without Constants) .DA DS.END-DS.START Data Segment Size .DA #64 Stack Size .DA #ZS.END-ZS.START Zero Page Size .DA 0 *-------------------------------------- .1 .DA CS.INIT .DA CS.RUN .DA CS.DOEVENT .DA CS.QUIT L.LIBTCPIP .DA LIBTCPIP L.SA.LOCAL .DA SA.LOCAL L.SA.REMOTE .DA SA.REMOTE L.SA.REMOTE.AD .DA SA.REMOTE+S.SOCKADDR.ADDR L.NOD.Template .DA NOD.Template L.MSG.IPKO .DA MSG.IPKO L.MSG.USAGE .DA MSG.USAGE L.MSG.UNKNOWN .DA MSG.UNKNOWN L.MSG.HOSTOK .DA MSG.HOSTOK L.MSG.SKTKO .DA MSG.SKTKO L.MSG.SKTOK .DA MSG.SKTOK L.MSG.SKTERR .DA MSG.SKTERR L.MSG.NICK .DA MSG.NICK L.MSG.USER .DA MSG.USER L.MSG.JOIN .DA MSG.JOIN L.MSG.TOPBAR .DA MSG.TOPBAR L.MSG.STATUSBAR .DA MSG.STATUSBAR L.MSG.STATUSBARMSG .DA MSG.STATUSBARMSG L.IRC.NICK .DA IRC.NICK L.IRC.USER .DA IRC.USER L.IRC.JOIN .DA IRC.JOIN L.IRC.JOINKEY .DA IRC.JOINKEY L.IRC.PONG .DA IRC.PONG L.IRC.PART .DA IRC.PART L.IRC.NAMES .DA IRC.NAMES L.IRC.PRIVMSG .DA IRC.PRIVMSG L.SEQ.INIT .DA SEQ.INIT L.SEQ.BAR .DA SEQ.BAR L.SEQ.TXTCLR .DA SEQ.TXTCLR L.SEQ.PRIVMSG .DA SEQ.PRIVMSG L.SEQ.INFOMSG .DA SEQ.INFOMSG L.SEQ.DUMPMSG .DA SEQ.DUMPMSG L.SEQ.RESET .DA SEQ.RESET L.IRC.CMDS .DA IRC.CMDS J.IRC.CMDS .DA CS.RUN.CMD.JOIN .DA CS.RUN.CMD.PART .DA CS.RUN.CMD.PING .DA CS.RUN.CMD.PRIVMSG .DA CS.RUN.CMD.MODE .DA CS.RUN.CMD.353 .DA CS.RUN.CMD.375 .DA CS.RUN.CMD.372 .DA CS.RUN.CMD.376 J.ESC .DA CS.RUN.CHARIN.LEFT .DA CS.RUN.CHARIN.DOWN .DA CS.RUN.CHARIN.UP .DA CS.RUN.CHARIN.RIGHT .DA 0 *-------------------------------------- CS.INIT >LDYA L.LIBTCPIP >SYSCALL LoadLib bcs .9 sta hLIBTCPIP .9 rts *-------------------------------------- CS.RUN >LIBCALL hLIBTCPIP,LIBTCPIP.GETCFG is TCPIP loaded ? >STYA ZPPtr1 lda (ZPPtr1) Configured ? bmi CS.RUN.IPOK >LDYA L.MSG.IPKO >SYSCALL PutS lda #E.SYN sec .99 rts CS.RUN.IPOK ldy #S.PS.ARGC lda (pPS),y cmp #3 bcc .9 ldy #S.IPCFG.IP+3 ldx #3 .1 lda (ZPPtr1),y sta SA.LOCAL+S.SOCKADDR.ADDR,x dey dex bpl .1 lda #TIMEOUT.MAX sta TimeOut .2 >SLEEP >PUSHW L.SA.REMOTE.AD lda #1 >SYSCALL ArgV >PUSHYA >LIBCALL hLIBTCPIP,LIBTCPIP.HST.GetByName bcc CS.RUN.HOSTOK lda TimeOut bne .2 >PUSHW L.MSG.UNKNOWN lda #1 >SYSCALL ArgV >PUSHYA >PUSHBI 2 >SYSCALL PrintF bra .99 .9 >LDYA L.MSG.USAGE >SYSCALL PutS .99 lda #E.SYN sec rts CS.RUN.HOSTOK lda #2 >SYSCALL ArgV >SYSCALL AToI >STYA SA.REMOTE+S.SOCKADDR.PORT >PUSHW L.MSG.HOSTOK ldx #0 .1 >PUSHB SA.REMOTE+S.SOCKADDR.ADDR,x inx cpx #4 bne .1 >PUSHW SA.REMOTE+S.SOCKADDR.PORT lda #1 >SYSCALL ArgV >PUSHYA >PUSHBI 8 >SYSCALL PrintF CS.RUN.OPENSKT >PUSHBI 0 no protocol lda #S.SOCKET.T.STREAM >LIBCALL hLIBTCPIP,LIBTCPIP.Socket bcs .9 sta hSocket >PUSHW L.SA.LOCAL lda hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Bind bcc .2 .9 pha >LDYA L.MSG.SKTKO >SYSCALL PutS pla sec .99 rts .2 lda #TIMEOUT.MAX sta TimeOut .3 >SLEEP >PUSHW L.SA.REMOTE lda hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Connect bcc .4 cmp #ERR.SKT.NOCONN bne .9 lda TimeOut bne .3 lda #ERR.SKT.NOCONN bra .9 .4 >PUSHW L.MSG.SKTOK >PUSHBI 0 >SYSCALL PrintF jsr CS.RUN.MkNod bcs .99 jsr CS.RUN.GETBUF bcs .99 jsr CS.RUN.SCRSETUP bcs .99 jsr CS.RUN.NICK bcs .99 >SLEEP jsr CS.RUN.USER bcs .99 >SLEEP jsr CS.RUN.JOIN bcs .99 >LDYA pData NULLSTRING jsr CS.RUN.STATUSPDATE bcs .99 CS.RUN.LOOP >SLEEP lda hFile >SYSCALL FEOF bcs .9 tay bne .2 jsr CS.RUN.GetMsg bcs .9 beq .2 jsr CS.RUN.REQ bcs .9 >SLEEP .2 ldy #S.PS.hStdIn lda (pPS),y >SYSCALL FEOF bcs .9 tay bne CS.RUN.LOOP EOF = true, no char from STDIN >SYSCALL GetChar bcs .9 jsr CS.RUN.CHARIN bcc CS.RUN.LOOP .9 php pha >PUSHW L.SEQ.RESET >PUSHBI 0 >SYSCALL PrintF pla plp rts *-------------------------------------- CS.RUN.MkNod >PUSHEA.G NodBuf >PUSHW L.NOD.Template >PUSHB hSocket >PUSHBI 1 >SYSCALL SPrintF bcs .9 >PUSHEA.G NodBuf+5 >PUSHW 0 >PUSHB hSocket >SYSCALL MKNod bcs .9 >PUSHEA.G NodBuf >PUSHBI O.RDWR+O.TEXT >PUSHBI S.FI.T.TXT >PUSHWZ Aux type >SYSCALL FOpen bcs .9 sta hFile .9 rts *-------------------------------------- CS.RUN.GETBUF >LDYAI MSGSIZE >SYSCALL GetMem bcs .9 stx hMsgBuf >STYA ZPMsgPtr >LDYAI 256 >SYSCALL GetMem bcs .9 stx hText >STYA ZPTextPtr >LDYAI 256 >SYSCALL GetMem bcs .9 stx hLineBuf >STYA ZPLineBufPtr .9 rts *-------------------------------------- CS.RUN.SCRSETUP >PUSHW L.SEQ.INIT >PUSHBI 0 >SYSCALL PrintF bcs .9 jsr CS.RUN.TOPUPDATE bcs .9 jsr CS.RUN.TXTCLR .9 rts *-------------------------------------- CS.RUN.TOPUPDATE >PUSHW ZPLineBufPtr >PUSHW L.MSG.TOPBAR >PUSHB #K.VER >PUSHB /K.VER lda #1 >SYSCALL ArgV >PUSHYA lda #2 >SYSCALL ArgV >PUSHYA lda #3 >SYSCALL ArgV >PUSHYA >PUSHBI 8 >SYSCALL SPrintF >PUSHW L.SEQ.BAR >PUSHBI 1 >PUSHW ZPLineBufPtr >PUSHBI 3 >SYSCALL PrintF rts *-------------------------------------- CS.RUN.STATUSPDATE pha phy >PUSHW ZPLineBufPtr >PUSHW L.MSG.STATUSBAR lda #4 >SYSCALL ArgV >PUSHYA ply pla >PUSHYA >PUSHBI 4 bra CS.RUN.STATUS *-------------------------------------- CS.RUN.STATUSMSG pha >PUSHW ZPLineBufPtr >PUSHW L.MSG.STATUSBARMSG pla >PUSHYA >PUSHBI 2 CS.RUN.STATUS >SYSCALL SPrintF >PUSHW L.SEQ.BAR >PUSHBI 21 >PUSHW ZPLineBufPtr >PUSHBI 3 >SYSCALL PrintF rts *-------------------------------------- CS.RUN.TXTCLR lda #0 sta (ZPTextPtr) stz TextPtr stz TextLen stz bEscMode >PUSHW L.SEQ.TXTCLR >PUSHBI 0 >SYSCALL PrintF rts *-------------------------------------- CS.RUN.NICK >LDYA L.MSG.NICK jsr CS.RUN.STATUSMSG >PUSHB hFile >PUSHW L.IRC.NICK lda #3 nickname >SYSCALL ArgV >PUSHYA >PUSHBI 2 >SYSCALL FPrintF bcs .9 .1 >SLEEP jsr CS.RUN.GetMsg bcs .9 beq .1 jsr CS.RUN.SplitMsg jsr CS.RUN.DUMPMSG ldy #$ff .3 iny lda IRC.REP.NOIDENT,y beq .8 cmp (ZPMsgExtPtr),y beq .3 bra .1 .8 clc .9 rts *-------------------------------------- CS.RUN.USER >LDYA L.MSG.USER jsr CS.RUN.STATUSMSG >PUSHB hFile >PUSHW L.IRC.USER lda #3 nickname >SYSCALL ArgV >PUSHYA lda #3 nickname >SYSCALL ArgV >PUSHYA >PUSHBI 4 >SYSCALL FPrintF bcs .9 .1 >SLEEP jsr CS.RUN.GetMsg bcs .9 beq .1 .2 jsr CS.RUN.SplitMsg jsr CS.RUN.DUMPMSG ldy #$ff .3 iny lda IRC.REP.001,y beq .8 cmp (ZPMsgCmdPtr),y beq .3 bra .1 .8 clc .9 rts *-------------------------------------- CS.RUN.JOIN >LDYA L.MSG.JOIN jsr CS.RUN.STATUSMSG >PUSHB hFile lda #5 key >SYSCALL ArgV bcs .1 >PUSHW L.IRC.JOINKEY lda #4 channel >SYSCALL ArgV >PUSHYA lda #5 key >SYSCALL ArgV >PUSHYA >PUSHBI 4 bra .2 .1 >PUSHW L.IRC.JOIN lda #4 channel >SYSCALL ArgV >PUSHYA >PUSHBI 2 .2 >SYSCALL FPrintF .9 rts *-------------------------------------- CS.RUN.REQ jsr CS.RUN.SplitMsg bcs .8 * jsr CS.RUN.DUMPMSG >LDYA L.IRC.CMDS >STYA ZPPtr1 ldx #0 .1 lda (ZPPtr1) beq .8 ldy #$ff .2 iny lda (ZPPtr1),y cmp (ZPMsgCmdPtr),y bne .3 ora #0 bne .2 jmp (J.IRC.CMDS,x) .3 ora #0 beq .5 .4 iny lda (ZPPtr1),y bne .4 .5 inx inx tya sec adc ZPPtr1 sta ZPPtr1 bcc .1 inc ZPPtr1+1 bra .1 .8 clc .9 rts *-------------------------------------- CS.RUN.CMD.JOIN lda bJoin bmi .1 sec ror bJoin clc rts .1 *-------------------------------------- CS.RUN.CMD.PART >PUSHB hFile >PUSHW L.IRC.NAMES lda #4 channel >SYSCALL ArgV >PUSHYA >PUSHBI 2 >SYSCALL FPrintF rts *-------------------------------------- CS.RUN.CMD.PING >PUSHB hFile >PUSHW L.IRC.PONG >PUSHW ZPMsgExtPtr >PUSHBI 2 >SYSCALL FPrintF rts *-------------------------------------- CS.RUN.CMD.PRIVMSG ldy #0 .1 iny lda (ZPMsgPfxPtr),y beq .2 eor #'!' bne .1 sta (ZPMsgPfxPtr),y .2 >PUSHW L.SEQ.PRIVMSG >PUSHW ZPMsgPfxPtr >PUSHW ZPMsgExtPtr >PUSHBI 4 >SYSCALL PrintF rts *-------------------------------------- CS.RUN.CMD.MODE clc rts *-------------------------------------- CS.RUN.CMD.353 >LDYA ZPMsgExtPtr RPL_NAMREPLY jmp CS.RUN.STATUSPDATE CS.RUN.CMD.375 CS.RUN.CMD.372 CS.RUN.CMD.376 >PUSHW L.SEQ.INFOMSG >PUSHW ZPMsgExtPtr >PUSHBI 2 >SYSCALL PrintF rts *-------------------------------------- CS.RUN.GetMsg >PUSHB hFile >PUSHW ZPMsgPtr >PUSHWI MSGSIZE >SYSCALL FGetS bcs .9 lda (ZPMsgPtr) * clc .9 rts *-------------------------------------- CS.RUN.SplitMsg >LDYA pData >STYA ZPMsgPfxPtr >STYA ZPMsgCmdPtr >STYA ZPMsgArgPtr >STYA ZPMsgExtPtr ldy #0 ldx #0 lda (ZPMsgPtr) cmp #':' do we have a prefix ? bne .2 lda ZPMsgPtr clc adc #1 sta ZPMsgPfxPtr lda ZPMsgPtr+1 adc #0 sta ZPMsgPfxPtr+1 .1 iny lda (ZPMsgPtr),y beq .9 cmp #C.SPACE bne .1 lda #0 sta (ZPMsgPtr),y End Of prefix iny Skip blank tya tax Save CMD start pos .2 iny lda (ZPMsgPtr),y beq .4 .3 cmp #C.SPACE scan until end of CMD bne .2 lda #0 sta (ZPMsgPtr),y End of CMD iny Skip blank .4 php txa clc adc ZPMsgPtr sta ZPMsgCmdPtr lda #0 adc ZPMsgPtr+1 sta ZPMsgCmdPtr+1 plp beq .80 tya tax Save Arg start pos lda (ZPMsgPtr),y cmp #':' beq .71 no arg....ext .6 iny lda (ZPMsgPtr),y beq .7 cmp #':' ARGS could be "ARG1 ARG2 ARG3" bne .6 lda #0 sta (ZPMsgPtr),y iny Skip : .7 php txa clc adc ZPMsgPtr sta ZPMsgArgPtr lda #0 adc ZPMsgPtr+1 sta ZPMsgArgPtr+1 plp beq .80 lda (ZPMsgPtr),y cmp #':' bne .8 .71 iny Skip blank .8 tya clc adc ZPMsgPtr sta ZPMsgExtPtr lda #0 adc ZPMsgPtr+1 sta ZPMsgExtPtr+1 .80 clc rts .9 sec rts *-------------------------------------- CS.RUN.DUMPMSG >PUSHW L.SEQ.DUMPMSG >PUSHW ZPMsgPfxPtr >PUSHW ZPMsgCmdPtr >PUSHW ZPMsgArgPtr >PUSHW ZPMsgExtPtr >PUSHBI 8 >SYSCALL PrintF rts *-------------------------------------- CS.RUN.CHARIN bit bEscMode bpl .4 cmp #'[' beq .8 stz bEscMode ldx #EscChars.Cnt-1 .1 cmp EscChars,x beq .2 dex bpl .1 clc rts .2 txa asl tax jmp (J.ESC,x) .4 cmp #C.ESC bne .5 sec ror bEscMode .8 clc rts .5 cmp #C.SPACE bcc CS.RUN.CHARIN.CTRL cmp #C.DEL bne CS.RUN.CHARIN.INS lda TextLen beq .8 lda TextPtr beq .8 lda #C.BS >SYSCALL PutChar jmp CS.RUN.CHARIN.DEL *-------------------------------------- CS.RUN.CHARIN.INS ldy TextLen cpy #TEXTMAX beq .8 inc TextLen ldy TextPtr sta (ZPTextPtr),y iny sty TextPtr pha lda #0 sta (ZPTextPtr),y pla >SYSCALL PutChar rts .8 CS.RUN.CHARIN.INS.8 clc rts *-------------------------------------- CS.RUN.CHARIN.CTRL cmp #C.CR bne .1 bit bJoin bpl CS.RUN.CHARIN.INS.8 lda TextLen beq CS.RUN.CHARIN.INS.8 >PUSHB hFile >PUSHW L.IRC.PRIVMSG lda #4 channel >SYSCALL ArgV >PUSHYA >PUSHW ZPTextPtr >PUSHBI 4 >SYSCALL FPrintF bcs .9 >PUSHW L.SEQ.PRIVMSG lda #3 nickname >SYSCALL ArgV >PUSHYA >PUSHW ZPTextPtr >PUSHBI 4 >SYSCALL PrintF bcs .9 jmp CS.RUN.TXTCLR .1 cmp #$14 Ctrl-T bne .8 >PUSHB hFile >PUSHW L.IRC.PART lda #4 channel >SYSCALL ArgV >PUSHYA >PUSHBI 2 >SYSCALL FPrintF >SLEEP lda #3 sec rts .8 clc .9 rts *-------------------------------------- CS.RUN.CHARIN.LEFT clc lda TextPtr beq .9 dec TextPtr lda #C.BS >SYSCALL PutChar .9 rts CS.RUN.CHARIN.DOWN CS.RUN.CHARIN.UP clc rts CS.RUN.CHARIN.RIGHT lda TextPtr cmp TextLen clc beq .9 inc sta TextPtr lda #C.FS >SYSCALL PutChar .9 rts *-------------------------------------- CS.RUN.CHARIN.DEL clc rts *-------------------------------------- CS.DOEVENT lda (pEvent) bpl .9 is it a TIMER event? lda TimeOut beq .9 dec TimeOut .9 sec do not discard TIMER event rts *-------------------------------------- CS.QUIT lda hFile beq .1 >SYSCALL FClose .1 lda hSocket beq .2 >LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown .2 lda hText beq .3 >SYSCALL FreeMem .3 lda hLIBTCPIP beq .8 >SYSCALL UnloadLib .8 clc rts *-------------------------------------- CS.END LIBTCPIP .AZ "libtcpip" hLIBTCPIP .BS 1 MSG.IPKO .AZ "TCP/IP Not Loaded/Configured." MSG.USAGE .AZ "Usage : IRC <#channel> [key]" MSG.UNKNOWN .AZ "%s: Unknown host\r\n" MSG.HOSTOK .AZ "Connecting to %d.%d.%d.%d:%D (%s)..." MSG.SKTKO .AZ "Failed to Open Socket." MSG.SKTOK .AZ "Connected\r\n(Exit key is Ctrl-T)\r\n" MSG.SKTERR .AZ "Socket Error : $%h\r\n" MSG.NICK .AZ "Registering User..." MSG.USER .AZ "Connecting User..." MSG.JOIN .AZ "Joining Channel..." MSG.TOPBAR .AZ "A2osX IRC %d.%d Server:%s:%s Nick:%s" MSG.STATUSBAR .AZ "%s:%s" MSG.STATUSBARMSG .AZ "STATUS:%s" *-------------------------------------- EscChars .AS 'DBAC' EscChars.Cnt .EQ *-EscChars EscChars.Remap .DA #C.BS,#C.VT,#C.LF,#C.FS *-------------------------------------- IRC.REP.NOIDENT .AZ "*** No Ident response" IRC.REP.001 .AZ "001" IRC.REP.JOIN .AZ "JOIN" *-------------------------------------- IRC.CMDS .AZ "JOIN" .AZ "PART" .AZ "PING" .AZ "PRIVMSG" .AZ "MODE" .AZ "353" .AZ "375" .AZ "372" .AZ "376" .DA #0 *-------------------------------------- IRC.NICK .AZ "NICK %s\r\n" IRC.USER .AZ "USER %s 0 * :%s\r\n" IRC.JOIN .AZ "JOIN %s\r\n" IRC.JOINKEY .AZ "JOIN %s %s\r\n" IRC.PONG .AZ "PONG %s\r\n" IRC.PART .AS "PART %s\r\n" .AZ "QUIT :Pfff\r\n" IRC.NAMES .AZ "NAMES %s\r\n" IRC.PRIVMSG .AZ "PRIVMSG %s :%s\r\n" *-------------------------------------- SEQ.INIT .AZ "\ec\e(B\e)0\e[?7l\e[2;20r\e[22;1H\e[?7h" SEQ.BAR .AZ "\e7\e[%d;1H\e[7m\e[37;40m%80s\e[0m\e8" SEQ.TXTCLR .AZ "\e[22;1H\e[K\r\n\e[K\r\n\e[K\e[22;1H" SEQ.PRIVMSG .AZ "\e7\e[20;1H\r\n\e[7m%s:\e[0m%s\e8" SEQ.DUMPMSG .AZ "\e7\e[20;1H\r\n\e[7m%s \e[0m%s %s %s\e8" SEQ.INFOMSG .AZ "\e7\e[20;1H%s\r\n\e8" SEQ.RESET .AZ "\ec" *-------------------------------------- SA.LOCAL .DA #AF.INET S.SOCKADDR.AF .BS 1 .BS 4 S.SOCKADDR.ADDR .BS 2 S.SOCKADDR.PORT *-------------------------------------- SA.REMOTE .DA #AF.INET S.SOCKADDR.AF .BS 1 .BS 4 S.SOCKADDR.ADDR .BS 2 *-------------------------------------- NOD.Template .AZ "/dev/irc%h" *-------------------------------------- .DUMMY .OR 0 DS.START NULLSTRING .BS 1 NodBuf .BS 11 DS.END .ED *-------------------------------------- MAN SAVE usr/src/bin/irc.s ASM