
ô > iprom/asmFô IP for the Beeb. Lovingly coded in hand-crafted assembler. Hmph.$ô (c) 1995-1996 Philip Blundell.(ô2<ô 19-Jul-04  - JGH: Source converted to BBC BASIC syntax<ôF/ô 12-Sep-95  - send_packet cheating removedPRô            - arp added. Doesn't seem to work - not sure if this is Freenet'sZ ô              fault or mined ô            - routing addedn-ô            - BASIC loader program addedxGô            - made ip_checksum more general, removed icmp_checksum‚$ô            - clock now 32 bitsŒ+ô            - started implementing TCP–1ô            - fixed block_copy of >256 bytes ôª3ô 15-Dec-95  - fixed read_rx control-byte check´7ô            - implemented response to incoming ARP¾.ô            - fixed outgoing ARP requestsÈ?ô            - implemented handling of incoming ARP repliesÒ7ô            - improved ARP/route table search codeÜôæ"ô 17-Dec-95  - implemented TCPðôú<ô 27-Dec-95  - started to implement sideways ROM versionôPô 30-Dec-95  - add tcpack_buffer to fix overwrite problems in reject and ack-ô            - more tx retries (10 not 2)",ô            - randomise our port number,>ô            - try to fix the zero-window deadlock problem6,ô            - start implementing TELAPI@ôJô 03-Jan-96  - add initflagT;ô            - implement vector claim & passon properly^ôhMô 11-Apr-96  - fix resets being sent with wrong port numbers (was killingrEô              active connection when a spurious segment arrived)|8ô            - fix CNP code to return correct values†ôLô 16-Apr-96  - queue up another frame to go out if we have buffered dataš-ô              when an ACK arrives <doh!>¤3ô            - don't re-open rxcb on soft break®Kô            - do initialisation stuff after claiming workspace, not on¸!ô              auto-boot callÂ1ô          - print numbers in decimal not hexÌ?ô          - preserve more zero-page stuff more of the timeÖ.ô          - print our IP address on *HELPàôê>ô 17-Apr-96  - part implemented UDP and bootp transmissionô>ô          - can't really do broadcasts though, so we loseþôHô 01-Nov-96  - removed initflag, replaced with DEROUTE (to allow the/ô              ROM to be put into hardware):&__DEBUG__     =   00::OSASCI        =   &FFE3DOSNEWL        =   &FFE7NOSWRCH        =   &FFEEXOSWORD        =   &FFF1bOSBYTE        =   &FFF4l:vEVENTV        =   &30€temp          =   &A8Štemp2         =   &AA”base          =   &ACždata          =   &AE¨params        =   &70²tcp_frame     =   &72¼temp3         =   &74Æpltemp        =   &74Ðbccount       =   &76Útrcount       =   &77ä:î!ô Econet MTU=1280 bytes=&500.ø@scratch       =   &A040         :ô &40 bytes more temp spacepblk          =   &A080trx_buf       =   &A0C0 Btcprx_buffer  =   &A200         :ô 256 bytes TCP receive space*6tcptx_buffer  =   &A100         :ô ditto, transmit4>varbase       =   &B200H+oldvector     =   varbase       :ô &980R+rxhandle      =   varbase+2     :ô &982\+ihl           =   varbase+3     :ô &983f+clock         =   varbase+4     :ô &984p+rstation      =   varbase+8     :ô &988z+rlength       =   varbase+&A    :ô &98A„+cpsrc         =   varbase+&C    :ô &98CŽ+cpdst         =   varbase+&E    :ô &98E˜+cplen         =   varbase+&10   :ô &990¢+his_ip        =   varbase+&12   :ô &992¬+proto         =   varbase+&16   :ô &996¶+retry         =   varbase+&17   :ô &997À+seg_seq       =   varbase+&18   :ô &998Ê+seg_ack       =   varbase+&1C   :ô &99CÔ+tcp_state     =   varbase+&20   :ô &9A0Þ+tcp_flags     =   varbase+&21   :ô &9A1è+locport       =   varbase+&22   :ô &9A2ò+remport       =   varbase+&24   :ô &9A4ü+tcp_peer      =   varbase+&26   :ô &9A6+snd_nxt       =   varbase+&2A   :ô &9AA+hisport       =   varbase+&2E   :ô &9AE+ourport       =   varbase+&30   :ô &9B0$+tcp_retransmit=   varbase+&32   :ô &9B2.+tcp_timer     =   varbase+&34   :ô &9B48+rcv_nxt       =   varbase+&35   :ô &9B5B+snd_una       =   varbase+&39   :ô &9B9L+tcprx_in      =   varbase+&3D   :ô &9BDV+tcprx_out     =   varbase+&3E   :ô &9BE`+tcptx_in      =   varbase+&3F   :ô &9BFj+tcptx_out     =   varbase+&40   :ô &9C0t+tx_size       =   varbase+&41   :ô &9C1~!my_ip         =   varbase+&42ˆ!rxbuffer_ptr  =   varbase+&46’!txbuffer_ptr  =   varbase+&47œ)rxbuffer_end_ptr      =   varbase+&48¦)txbuffer_end_ptr      =   varbase+&49°!blk_ptr       =   varbase+&4Aº!zwindow       =   varbase+&4BÄ!old_insv      =   varbase+&4CÎ!old_remv      =   varbase+&4FØ!old_cnpv      =   varbase+&52â!old_eventv    =   varbase+&55ì!zpstore       =   varbase+&80ö!tx_flag       =   varbase+&8A!ack_timer     =   varbase+&8B
!iac_flag      =   varbase+&8C!iac_cmd       =   varbase+&8D!lockflag      =   varbase+&8E(!iac_x         =   varbase+&8F2!data_size     =   varbase+&90<!our_fin_flag  =   varbase+&92FPSTATE_CLOSED          =   0ZSTATE_SYN_SENT        =   1dSTATE_ESTABLISHED     =   2nSTATE_FIN             =   3x‚URG           =   32ŒACK           =   16–PSH           =   8 RST           =   4ªSYN           =   2´FIN           =   1¾ÈFarp           =   varbase+&100  :ô space for 40x6-byte arp entriesÒAroute         =   varbase+&1F0  :ô space for 10x8-byte routesÜCtcp_buffer    =   varbase+&240  :ô space for 512 bytes TCP dataæ8tcpack_buffer =   varbase+&440  :ô space for TCP ackðúload%=&8000mcode%=¸P+&3FFE:Ó=mcode%O%=mcode%:P%=load%	[OPT0"C.header        : BRK                    :\ we aren't a language,                EQUW    06#                JMP     service@F                EQUB    &82            :\ Service ROM in 6502 codeJ+                EQUB    copyright-&8000T                EQUB    14^&.ROMName       :  EQUS    "TCP/IP"h:]:namelen=P%-ROMName:[OPT0r                BRK|.                EQUS    "v0.14 1996-04-16"†.copyright     :  BRK1                EQUS    "(C) Philip Blundell"š                BRK¤                EQUW     0®                EQUW     0¸Â .service       :  CMP     #0Ì'                BEQ     AAnoserviceÖ                PHAà                TYAê                PHAô                 LDA     tempþ                PHA"                LDA     temp+1                PHA!                LDA     temp2&                PHA0#                LDA     temp2+1:                PHAD                TSXN"                LDA     &106,XX                CMP     #2b,                BEQ     AAclaimworkspacel                CMP     #9v"                BEQ     AAhelp€                CMP     #3Š&                BNE     AAnotbreak”!                JMP     breakž!.AAnotbreak    :   CMP     #4¨(                BNE     AAnotstarcmd²#                JMP     starcmd¼.AAnotstarcmdÆ.service_exitÐ                PLAÚ#                STA     temp2+1ä                PLAî!                STA     temp2ø                PLA"                STA     temp+1                PLA                 STA     temp                 PLA*                TAY4                PLA>                LDX     &F4H.AAnoservice   :   RTSR.AAclaimworkspace\                LDX     &F4f                TYAp"                STA     &DF0,Xz(                STY     rxbuffer_ptr„                INYŽ                INY˜(                STY     txbuffer_ptr¢                INY¬                INY¶#                STY     blk_ptrÀ                INYÊ                TSXÔ                TYAÞ"                STA     &105,Xè(                JMP     service_exitòü&.AAhelp        :   LDA     (&F2),Y	                CMP     #&D	'                BEQ     AAshorthelp	                LDX     #0	$,                JSR     cmd_decode_setup	.&                JSR     cmd_decode	8(                JMP     service_exit	B	L'.AAshorthelp   :   JSR     prinline	V                EQUB    13	`1                EQUS    "Econet TCP/IP 0.14 "	j                BRK	t$.AAinit_ok     :   LDA     my_ip	~\               CMP     #0	ˆ+                BEQ     AAno_addr_known	’                PHA	œ!                LDA     #—"("	¦"                JSR     OSWRCH	°                PLA	º(                JSR     PrintDecimal	Ä!                LDA     #—"."	Î"                JSR     OSWRCH	Ø#                LDA     my_ip+1	â(                JSR     PrintDecimal	ì!                LDA     #—"."	ö"                JSR     OSWRCH
#                LDA     my_ip+2

(                JSR     PrintDecimal
!                LDA     #—"."
"                JSR     OSWRCH
(#                LDA     my_ip+3
2(                JSR     PrintDecimal
<!                LDA     #—")"
F"                JSR     OSWRCH
P.AAno_addr_known
Z$                JSR     prinline
d                EQUB    13
n%                EQUS    "  TCPIP"
x                EQUB    13
‚                BRK
Œ(                JMP     service_exit
–
                \ BLOCK
ª
´.cmd_decode_setup
¾                TYA
È                CLC
Ò                ADC     &F2
Ü!                STA     temp2
æ                LDA     &F3
ð                ADC     #0
ú#                STA     temp2+1                RTS.cmd_decode"'                LDA     cmd_table,X,                 STA     temp6)                LDA     cmd_table+1,X@"                STA     temp+1J                LDY     #0T'.AAloop        :   LDA     (temp),Y^\               CMP     #0h                 BEQ     AAokr%                LDA     (temp2),Y|                CMP     #46†                 BEQ     AAok                €     #&5Fš$                CMP     (temp),Y¤!                BNE     AAbad®                INY¸"                JMP     AAloopÂ.AAbad         :   INXÌ                INXÖ                INXà                INXê                LDA     #0ô                RTSþ,.AAok          :   LDA     cmd_table+2,X                 STA     temp)                LDA     cmd_table+3,X&"                STA     temp+10"                JMP     (temp):D(.cmd_table     :  EQUW     tcpip_strN'                EQUW     tcpip_helpX$                EQUW     arp_strb#                EQUW     arpcmdl'                EQUW     ipaddr_strv&                EQUW     ipaddrcmd€'                EQUW     telnet_strŠ&                EQUW     telnetcmd”&                EQUW     route_strž%                EQUW     routecmd¨(                EQUW     deroute_str²'                EQUW     deroutecmd¼'                EQUW     telapi_strÆ&                EQUW     telapicmdÐÚ%.tcpip_str     :  EQUS    "TCPIP"ä                BRKî#.arp_str       :  EQUS    "ARP"ø                BRK&.ipaddr_str    :  EQUS    "IPADDR"                BRK&.telnet_str    :  EQUS    "TELNET"                 BRK*$.route_str       EQUS    "ROUTE"4                BRK>'.deroute_str   :  EQUS    "DEROUTE"H                BRKR&.telapi_str    :  EQUS    "TELAPI"\                BRKfp&.tcpip_help    :  JSR     prinlinez                EQUB    13„1                EQUS    "TCP/IP 0.14":EQUB 13Ž>                EQUS    "(C) 1996 Philip Blundell":EQUB 13˜3                EQUS    "  IPADDR <ip>":EQUB 13¢/                EQUS    "  DEROUTE":EQUB 13¬F                EQUS    "  ROUTE <target ip> <gateway ip>":EQUB 13¶<                EQUS    "  TELNET <ip> (<port>)":EQUB 13À<                EQUS    "  TELAPI <ip> (<port>)":EQUB 13Ê+                EQUS    "  ARP":EQUB 13Ô                BRKÞ                 LDA     #&FFè                RTSòü&.break        :   JSR     prinline1                EQUS    "TCP/IP 0.14":EQUB 13                BRK                 LDA     #253$                LDX     #0.                 LDY     #2558"                JSR     OSBYTEB                CPX     #0L'                BEQ     AAsoftbreakV#                JSR     open_rx`                LDA     #0j!                STA     my_ipt#                STA     my_ip+1~#                STA     my_ip+2ˆ#                STA     my_ip+3’                 LDX     #239œ$.AAzlp        :    STA     arp,X¦                DEX°                 CPX     #&FFº!                BNE     AAzlpÄ,.AAsoftbreak    :  LDA     #STATE_CLOSEDÎ%                STA     tcp_stateØ.init1        :  LDA     #0â#                STA     zwindowì!                STA     clockö#                STA     clock+1#                STA     clock+2
#                STA     clock+3*                STA     tcp_retransmit,                STA     tcp_retransmit+1($                STA     tcprx_in2%                STA     tcprx_out<$                STA     tcptx_inF%                STA     tcptx_outP#                STA     tx_flagZ%                STA     ack_timerd$                STA     iac_flagn#                STA     iac_cmdx$                STA     lockflag‚!                STA     iac_xŒ%                STA     data_size–'                STA     data_size+1 (                STA     our_fin_flagª´                LDA     #10¾%                STA     tcp_timerÈÒ                 LDA     #&A8Ü                LDX     #0æ                 LDY     #&FFð"                JSR     OSBYTEú                 STX     temp                 LDA     #&A9                LDX     #0                 LDY     #&FF""                JSR     OSBYTE,"                STX     temp+16@                 LDA     &22AJ$                STA     old_insvT                 LDA     &22B^&                STA     old_insv+1h                 LDA     &22Cr$                STA     old_remv|                 LDA     &22D†&                STA     old_remv+1                 LDA     &22Eš$                STA     old_cnpv¤                 LDA     &22F®&                STA     old_cnpv+1¸Â                 LDA     &220Ì                 CMP     #&30Ö0                BNE     AAeventv_notextendedà                 LDA     &221ê                 CMP     #&FFô0                BNE     AAeventv_notextendedþ                 LDY     #&30$                LDA     (temp),Y&                STA     old_eventv                INY&$                LDA     (temp),Y0(                STA     old_eventv+1:                INYD$                LDA     (temp),YN(                STA     old_eventv+2X0                JMP     AAeventv_wasextendedb.AAeventv_notextendedl                 LDA     &220v&                STA     old_eventv€                 LDA     &221Š(                STA     old_eventv+1”                 LDA     #&FFž(                STA     old_eventv+2¨.AAeventv_wasextended²¼                PHPÆ                SEIÐÚ(                LDA     #vsync € 255ä                 LDY     #&30î$                STA     (temp),Yø                INY(                LDA     #vsync  256$                STA     (temp),Y                INY                 LDA     &F4*$                STA     (temp),Y4                 LDA     #&FF>                 STA     &221H                 LDA     #&30R                 STA     &220\f                 LDY     #&3Fp)                LDA     #insert € 255z$                STA     (temp),Y„                INYŽ)                LDA     #insert  256˜$                STA     (temp),Y¢                INY¬                LDA     &F4¶$                STA     (temp),YÀ                 LDA     #&FFÊ                 STA     &22BÔ                 LDA     #&3FÞ                 STA     &22Aèò                 LDY     #&42ü                 STY     &22C                 LDA     #&FF                 STA     &22D)                LDA     #remove € 255$$                STA     (temp),Y.                INY8)                LDA     #remove  256B$                STA     (temp),YL                INYV                LDA     &F4`$                STA     (temp),Yjt-                INY            \ LDY #&45~                 STY     &22Eˆ                 LDA     #&FF’                 STA     &22Fœ-                LDA     #countpurge € 255¦$                STA     (temp),Y°                INYº-                LDA     #countpurge  256Ä$                STA     (temp),YÎ                INYØ                LDA     &F4â$                STA     (temp),Yìö                PLP                LDA     #14
                LDX     #4"                JSR     OSBYTE"                JSR     OSNEWL((                JMP     service_exit2<%.open_rx      :   LDA     blk_ptrF"                STA     temp+1P                LDA     #0Z                 STA     tempd                LDY     #0n                TYAx$                STA     (temp),Y‚                LDY     #3Œ$                STA     (temp),Y–$                STA     (temp),Y                 LDY     #1ª                 LDA     #&7F´$                STA     (temp),Y¾                INYÈ                 LDA     #&D2Ò$                STA     (temp),YÜ(                LDA     rxbuffer_ptræ                LDY     #6ð$                STA     (temp),Yú                DEY                LDA     #0$                STA     (temp),Y                 LDA     #&FF"                LDY     #7,$                STA     (temp),Y6                INY@$                STA     (temp),YJ                LDY     #11T$                STA     (temp),Y^                INYh$                STA     (temp),Yr(                LDA     rxbuffer_ptr|                LDY     #10†                CLC                ADC     #1š$                STA     (temp),Y¤                 LDA     #&FF®                DEY¸$                STA     (temp),YÂ                 LDA     #&11Ì                LDX     #0Ö#                LDY     blk_ptrà"                JSR     OSWORDê                LDY     #0ô$                LDA     (temp),Yþ\               CMP     #0                 BEQ     rxcb$                STA     rxhandle                RTS&0.rxcb         :   BRK:                BRKD#                EQUS    "Rxcb?"N                BRKXb$.evexit_j     :   JMP     evexitlv .eventcode    :   CMP     #4€!                BEQ     vsyncŠ                RTS”.vsync        :   PHPž                PHA¨                TXA²                PHA¼                TYAÆ                PHAÐ!                INC     clockÚ!                LDA     clockä\               CMP     #0î       \ BLOCKø"                BNE     BBskip#                INC     clock+1#                LDA     clock+1\               CMP     #0 "                BNE     BBskip*#                INC     clock+24#                LDA     clock+2>\               CMP     #0H"                BNE     BBskipR#                INC     clock+3\.BBskipf$                LDA     lockflagp\               CMP     #0z$                BNE     evexit_j„$                INC     lockflagŽ                CLI˜                 LDA     temp¢                PHA¬"                LDA     temp+1¶                PHAÀ!                LDA     temp2Ê                PHAÔ#                LDA     temp2+1Þ                PHAè%                LDA     tcp_frameò#                STA     zpstoreü'                LDA     tcp_frame+1%                STA     zpstore+1                 LDA     base%                STA     zpstore+2$"                LDA     base+1.%                STA     zpstore+38                 LDA     dataB%                STA     zpstore+4L"                LDA     data+1V%                STA     zpstore+5`"                LDA     paramsj%                STA     zpstore+6t$                LDA     params+1~%                STA     zpstore+7ˆ!                LDA     temp3’%                STA     zpstore+8œ#                LDA     temp3+1¦%                STA     zpstore+9°8               \ Every second, or if we get prodded:º               \ÄG               \  + Check if there is a segment to be retransmittedÎ$               \    if not, thenØG               \    + check if there is data in the transmit bufferâ%               \      if so, thenìM               \      + call tcp_transmit to build a segment and queue itöP               \  + Check the Econet for received packets.  ACK any incoming'               \    data if we can.
S               \  + Check if there is a segment to be retransmitted - includingB               \    one we just generated. If so, transmit it.%                DEC     tcp_timer(%                LDA     tcp_timer2                 CMP     #&FF<(                BNE     BBgo_read_rxF                 LDA     #100P%                STA     tcp_timerZ#                STA     tx_flagd!\               LDA     my_ipn"\               BNE     BBokipx&\               JSR     send_bootp‚-.BBokip       :    LDA     tcp_retransmitŒ\               CMP     #0–(                BNE     BBgo_read_rx ,                LDA     tcp_retransmit+1ª\               CMP     #0´-                BEQ     BBno_frame_queued¾(                JMP     BBgo_read_rxÈ.BBno_frame_queuedÒ$                LDA     tcptx_inÜ%                CMP     tcptx_outæ(                BEQ     BBgo_read_rxð(                JSR     tcp_transmitú.BBgo_read_rx$                LDX     rxhandle       \ BLOCK                 LDA     #&33""                JSR     OSBYTE,                TXA6(                BPL     BBdo_tcp_ack@#                JSR     read_rxJT(.BBdo_tcp_ack :    LDA     ack_timer^C\               CMP     #0                     \ no ack waitingh'                BEQ     BBdo_tcp_txr%                DEC     ack_timer|F                CMP     #1                     \ ack still waiting†'                BNE     BBdo_tcp_tx6               \ Fixme.  This shouldn't be needed.š$                LDA     tcp_peer¤"                STA     his_ip®&                LDA     tcp_peer+1¸$                STA     his_ip+1Â&                LDA     tcp_peer+2Ì$                STA     his_ip+2Ö&                LDA     tcp_peer+3à$                STA     his_ip+3ê(                JSR     tcp_ack_sendô&.BBdo_tcp_tx  :    LDA     tx_flagþ\               CMP     #0%                BEQ     BBevexit1                LDA     #0#                STA     tx_flag&,                LDA     tcp_retransmit+10\               CMP     #0:(                BNE     BBtx_goaheadD*                LDA     tcp_retransmitN\               CMP     #0X%                BEQ     BBevexit1b/.BBtx_goahead :    LDA     tcp_retransmit+1l'                STA     tcp_frame+1v*                LDA     tcp_retransmit€%                STA     tcp_frameŠ$                LDA     tcp_peer”"                STA     his_ipž&                LDA     tcp_peer+1¨$                STA     his_ip+1²&                LDA     tcp_peer+2¼$                STA     his_ip+2Æ&                LDA     tcp_peer+3Ð$                STA     his_ip+3Ú$                JSR     tcp_sendä.BBevexit1î%                LDA     zpstore+9ø#                STA     temp3+1%                LDA     zpstore+8!                STA     temp3%                LDA     zpstore+7 $                STA     params+1*%                LDA     zpstore+64"                STA     params>%                LDA     zpstore+5H"                STA     data+1R%                LDA     zpstore+4\                 STA     dataf%                LDA     zpstore+3p"                STA     base+1z%                LDA     zpstore+2„                 STA     baseŽ%                LDA     zpstore+1˜'                STA     tcp_frame+1¢#                LDA     zpstore¬%                STA     tcp_frame¶                PLAÀ#                STA     temp2+1Ê                PLAÔ!                STA     temp2Þ                PLAè"                STA     temp+1ò                PLAü                 STA     temp$                DEC     lockflag.evexit       :   PLA                TAY$                PLA.                TAX8                PLAB                PLPL                RTSV`.read_rxj#                LDA     blk_ptrt"                STA     temp+1~                LDA     #0ˆ                 STA     temp’$                LDA     rxhandleœ                LDY     #0¦$                STA     (temp),Y°                 LDA     #&11º                LDX     #0Ä#                LDY     blk_ptrÎ"                JSR     OSWORDØ                LDY     #4â$                LDA     (temp),Yì&                STA     rstation+1ö                DEY$                LDA     (temp),Y
$                STA     rstation                LDY     #9$                LDA     (temp),Y(A                STA     rlength        \ rbuf is page-aligned2                LDY     #10<$                LDA     (temp),YF                SECP                LDY     #6Z$                SBC     (temp),Yd%                STA     rlength+1n                LDY     #1x$                LDA     (temp),Y‚                 CMP     #&81Œ'                BNE     BBnot_dgram–!                JMP     dgram #.BBnot_dgram  :    CMP     #&A2ª+                BNE     BBnot_arp_reply´%                JMP     arp_reply¾.BBnot_arp_replyÈ                 CMP     #&A1Ò-                BNE     BBnot_arp_requestÜ'                JMP     arp_requestæ.BBnot_arp_requestð.Z%ú\        ç __DEBUG__$                JSR     prinline,                EQUS    "Rcvd weird cb "                BRK"                LDY     #1,$                LDA     (temp),Y6%                JSR     PrintHex1@\        FIJ,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%T#                JMP     open_rx^h.arp_replyr.Z%|\        ç __DEBUG__†$                JSR     prinline'                EQUS    "ARP reply"š                BRK¤\        FI®,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%¸                LDA     #0Â%                STA     tcp_timerÌ.BBfind_emptyÖ                TAXà!                LDA     arp,Xê\               CMP     #0ô'                BNE     BBnot_emptyþ#                LDA     arp+1,X \               CMP     #0 '                BNE     BBnot_empty #                LDA     arp+2,X &\               CMP     #0 0'                BNE     BBnot_empty :#                LDA     arp+3,X D\               CMP     #0 N&                BEQ     BBis_empty X.BBnot_empty  :    TXA b                CLC l                ADC     #6 v                CMP     #60 €(                BNE     BBfind_empty Š$                JSR     prinline ”.                EQUS    " (no slots free)" ž                EQUB    13 ¨                BRK ²#                JMP     open_rx ¼!.BBis_empty   :    LDY     #5 Æ$                LDA     (temp),Y Ð                 STA     data Ú                INY ä$                LDA     (temp),Y î"                STA     data+1 ø                LDY     #0!$                LDA     (data),Y!!                STA     arp,X!                INY! $                LDA     (data),Y!*#                STA     arp+1,X!4                INY!>$                LDA     (data),Y!H#                STA     arp+2,X!R                INY!\$                LDA     (data),Y!f#                STA     arp+3,X!p$                LDA     rstation!z#                STA     arp+4,X!„&                LDA     rstation+1!Ž#                STA     arp+5,X!˜#                JMP     open_rx!¢!¬
.dgram!¶.Z%!À\        ç __DEBUG__!Ê$                JSR     prinline!Ô#                EQUS    "rcvd "!Þ                BRK!è#                LDX     rlength!ò%                LDY     rlength+1!ü%                JSR     PrintHex2"$                JSR     prinline"*                EQUS    " bytes from ""                BRK"$&                LDA     rstation+1".%                JSR     PrintHex1"8                LDA     #46"B"                JSR     OSWRCH"L$                LDA     rstation"V%                JSR     PrintHex1"`\        FI"j,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%"t                LDY     #5"~$                LDA     (temp),Y"ˆ                 STA     data"’                INY"œ$                LDA     (temp),Y"¦"                STA     data+1"°)                JSR     IPDecapsulate"º#                JMP     open_rx"Ä"Î.IPDecapsulate"Ø       \ BLOCK"â                LDY     #12"ì$                LDA     (data),Y"ö"                STA     his_ip#                INY#
$                LDA     (data),Y#$                STA     his_ip+1#                INY#($                LDA     (data),Y#2$                STA     his_ip+2#<                INY#F$                LDA     (data),Y#P$                STA     his_ip+3#Z.Z%#d\        ç __DEBUG__#n"                LDA     his_ip#x%                JSR     PrintHex1#‚                LDA     #46#Œ!                JSR     &FFEE#–$                LDA     his_ip+1# %                JSR     PrintHex1#ª                LDA     #46#´!                JSR     &FFEE#¾$                LDA     his_ip+2#È%                JSR     PrintHex1#Ò                LDA     #46#Ü!                JSR     &FFEE#æ$                LDA     his_ip+3#ð%                JSR     PrintHex1#ú$                JSR     prinline$"                EQUS    " -> "$                BRK$                LDY     #16$"$                LDA     (data),Y$,%                JSR     PrintHex1$6                LDA     #46$@!                JSR     &FFEE$J                INY$T$                LDA     (data),Y$^%                JSR     PrintHex1$h                LDA     #46$r!                JSR     &FFEE$|                INY$†$                LDA     (data),Y$%                JSR     PrintHex1$š                LDA     #46$¤!                JSR     &FFEE$®                INY$¸$                LDA     (data),Y$Â%                JSR     PrintHex1$Ì$                JSR     prinline$Ö#                EQUS    " IHL="$à                BRK$ê\        FI$ô,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%$þ                LDY     #9%$                LDA     (data),Y%!                STA     proto%                LDY     #0%&$                LDA     (data),Y%0                €     #&F%:                ASL     A%D                ASL     A%N                STA     ihl%X.Z%%b\        ç __DEBUG__%l%                JSR     PrintHex1%v$                JSR     prinline%€%                EQUS    " proto="%Š                BRK%”!                LDA     proto%ž%                JSR     PrintHex1%¨\        FI%²,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%%¼#                LDA     rlength%Æ                SEC%Ð                SBC     ihl%Ú#                STA     rlength%ä%                LDA     rlength+1%î                SBC     #0%ø%                STA     rlength+1&                 LDA     data&                CLC&                ADC     ihl&                  STA     data&*"                LDA     data+1&4                ADC     #0&>"                STA     data+1&H.Z%&R\        ç __DEBUG__&\"                JSR     OSNEWL&f\        FI&p,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%&z!                LDA     proto&„                CMP     #1&Ž%                BNE     BCnoticmp&˜                 JMP     icmp&¢.BCnoticmp&¬                CMP     #6&¶$                BNE     BCnottcp&À                JMP     tcp&Ê.BCnottcp&Ô                RTS&Þ&è.tcp&ò.Z%&ü\        ç __DEBUG__'$                JSR     prinline'"                EQUS    "TCP "'                BRK'$\        FI'.,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%'8                LDY     #0'B$                LDA     (data),Y'L%                STA     remport+1'V                INY'`$                LDA     (data),Y'j#                STA     remport't                INY'~$                LDA     (data),Y'ˆ%                STA     locport+1'’                INY'œ$                LDA     (data),Y'¦#                STA     locport'°                INY'º$                LDA     (data),Y'Ä%                STA     seg_seq+3'Î                INY'Ø$                LDA     (data),Y'â%                STA     seg_seq+2'ì                INY'ö$                LDA     (data),Y(%                STA     seg_seq+1(
                INY($                LDA     (data),Y(#                STA     seg_seq((                INY(2$                LDA     (data),Y(<%                STA     seg_ack+3(F                INY(P$                LDA     (data),Y(Z%                STA     seg_ack+2(d                INY(n$                LDA     (data),Y(x%                STA     seg_ack+1(‚                INY(Œ$                LDA     (data),Y(–%                STA     seg_ack+0(                 INY(ª$                LDA     (data),Y(´                LSR     A(¾                LSR     A(È<                STA     scratch        \ TCP header size(Ò                INY(Ü$                LDA     (data),Y(æ%                STA     tcp_flags(ð                 LDA     data(ú                CLC)#                ADC     scratch)                 STA     data)"                LDA     data+1)"                ADC     #0),"                STA     data+1)6#                LDA     rlength)@                SEC)J#                SBC     scratch)T#                STA     rlength)^%                LDA     rlength+1)h                SBC     #0)r%                STA     rlength+1)|.Z%)†\        ç __DEBUG__)#                LDX     remport)š%                LDY     remport+1)¤%                JSR     PrintHex2)®$                JSR     prinline)¸"                EQUS    " -> ")Â                BRK)Ì#                LDX     locport)Ö%                LDY     locport+1)à%                JSR     PrintHex2)ê                LDA     #32)ô"                JSR     OSWRCH)þ%                LDX     seg_seq+2*%                LDY     seg_seq+3*%                JSR     PrintHex2*#                LDX     seg_seq*&%                LDY     seg_seq+1*0%                JSR     PrintHex2*:                LDA     #32*D"                JSR     OSWRCH*N%                LDX     seg_ack+2*X%                LDY     seg_ack+3*b%                JSR     PrintHex2*l#                LDX     seg_ack*v%                LDY     seg_ack+1*€%                JSR     PrintHex2*Š                LDA     #32*”"                JSR     OSWRCH*ž%                LDA     tcp_flags*¨%                JSR     PrintHex1*²"                JSR     OSNEWL*¼\        FI*Æ,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%*Ð%                LDA     tcp_state*Ú)                CMP     #STATE_CLOSED*ä"                BEQ     reject*î#                LDA     locport*ø#                CMP     ourport+"                BNE     reject+#                LDA     remport+#                CMP     hisport+ "                BNE     reject+*&                JMP     BCnoreject+4+>.reject+H.Z%+R\        ç __DEBUG__+\$                JSR     prinline+f1                EQUS    "[rejecting segment]"+p                EQUB    13+z                BRK+„\        FI+Ž,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%+˜%                LDA     tcp_flags+¢                 BIT     #RST+¬$                BNE     BCnotrst+¶                RTS+À.BCnotrst+Ê+               \ use tcpack_buffer here+Ô0                LDX     #tcpack_buffer € 255+Þ0                LDY     #tcpack_buffer  256+è%                STX     tcp_frame+ò'                STY     tcp_frame+1+ü                LDY     #24,                 LDA     #&50,)                STA     (tcp_frame),Y,                LDY     #10,$                LDA     #0,.)                STA     (tcp_frame),Y,8                INY,B                LDA     #20,L)                STA     (tcp_frame),Y,V               \ BIT   #ACK,`"               \ BNE somewhere,j                LDY     #23,t                LDA     #0,~)                STA     (tcp_frame),Y,ˆ                DEY,’)                STA     (tcp_frame),Y,œ                DEY,¦)                STA     (tcp_frame),Y,°                DEY,º)                STA     (tcp_frame),Y,Ä                 LDA     #RST,Î                LDY     #25,Ø)                STA     (tcp_frame),Y,â                LDA     #0,ì                INY,ö)                STA     (tcp_frame),Y-                INY-
)                STA     (tcp_frame),Y-                LDY     #12-%                LDA     locport+1-()                STA     (tcp_frame),Y-2                INY-<#                LDA     locport-F)                STA     (tcp_frame),Y-P                INY-Z%                LDA     remport+1-d)                STA     (tcp_frame),Y-n                INY-x#                LDA     remport-‚)                STA     (tcp_frame),Y-Œ)                JMP     tcp_send_port-–- .BCnoreject-ª%                LDA     tcp_state-´+                CMP     #STATE_SYN_SENT-¾$                BEQ     syn_sent-È.                CMP     #STATE_ESTABLISHED-Ò"                BNE     BCskip-Ü'                JMP     established-æ).BCskip     :      CMP     #STATE_FIN-ð#                BNE     BCskip1-ú'                JMP     established..BCskip1    :      RTS...syn_sent."       \ BLOCK.,.Z%.6\        ç __DEBUG__.@$                JSR     prinline.J2                EQUS    "Processing SYN reply".T                EQUB    13.^                BRK.h\        FI.r,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%.|%                LDA     tcp_flags.†                €     #RST.\               CMP     #0.š,                BEQ     CCconn_not_reset.¤)                LDA     #STATE_CLOSED.®%                STA     tcp_state.¸                RTS.Â(.CCconn_not_reset: LDA     tcp_flags.Ì                 BIT     #SYN.Ö                 BNE     CCok.à"                JMP     reject.ê&.CCok        :     LDA     seg_ack.ô#                STA     snd_una.þ%                LDA     seg_ack+1/%                STA     snd_una+1/%                LDA     seg_ack+2/%                STA     snd_una+2/&%                LDA     seg_ack+3/0%                STA     snd_una+3/:.                LDA     #STATE_ESTABLISHED/D%                STA     tcp_state/N                LDA     #0/X*                STA     tcp_retransmit/b,                STA     tcp_retransmit+1/l                CLC/v#                LDA     seg_seq/€                ADC     #1/Š#                STA     rcv_nxt/”%                LDA     seg_seq+1/ž                ADC     #0/¨%                STA     rcv_nxt+1/²%                LDA     seg_seq+2/¼                ADC     #0/Æ%                STA     rcv_nxt+2/Ð%                LDA     seg_seq+3/Ú                ADC     #0/ä%                STA     rcv_nxt+3/î#                JMP     tcp_ack/ø0       \ BLOCK0.established0.Z%0 \        ç __DEBUG__0*$                JSR     prinline041                EQUS    "Got TCP data len = "0>                BRK0H#                LDX     rlength0R%                LDY     rlength+10\%                JSR     PrintHex20f"                JSR     OSNEWL0p\        FI0z,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%0„%                LDA     tcp_flags0Ž                €     #ACK0˜\               CMP     #00¢%                BEQ     DDnot_ack0¬'                JSR     ack_process0¶(.DDnot_ack   :     LDA     tcp_flags0À                €     #FIN0Ê\               CMP     #00Ô%                BEQ     DDnot_fin0Þ'                JSR     fin_process0è(.DDnot_fin   :     LDA     tcp_flags0ò                €     #RST0ü%                BEQ     DDnot_rst1)                LDA     #STATE_CLOSED1%                STA     tcp_state1&.DDnot_rst   :     LDA     rlength1$\               CMP     #01.                 BNE     DDnz18%                LDA     rlength+11B\               CMP     #01L                 BNE     DDnz1VG                RTS                    \ Quietly drop zero segments1`1jC.DDnz        :    \ Accept the segment if seq.seq <= rcv.nxt &&1t5               \    (seg.seq + length) > rcv.next1~%                LDA     seg_seq+31ˆ%                CMP     rcv_nxt+31’'                BNE     DDgds_check1œ%                LDA     seg_seq+21¦%                CMP     rcv_nxt+21°'                BNE     DDgds_check1º%                LDA     seg_seq+11Ä%                CMP     rcv_nxt+11Î'                BNE     DDgds_check1Ø#                LDA     seg_seq1â#                CMP     rcv_nxt1ì'                BNE     DDgds_check1ö3               \ It's the segment we asked for.2%                JMP     DDyessame2
.DDgds_check2"                BCC     DDokds2.Z%2(\        ç __DEBUG__22$                JSR     prinline2<)                EQUS    "Bad segment"2F                BRK2P\        FI2Z,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%2dO                JMP     tcp_ack                \ Oh dear.  Ack the last one2n;                                               \ again.2x2‚Q               \ OK so far -- this segment is earlier than the one we wanted.2ŒN               \ Calculate the difference between rcv.nxt and seg.seq.  If2–?               \ it's less than rlength, we're in business.2 .DDokds      :     SEC2ª#                LDA     rcv_nxt2´#                SBC     seg_seq2¾#                STA     scratch2È%                LDA     rcv_nxt+12Ò%                SBC     seg_seq+12Ü%                STA     scratch+12æ%                LDA     rcv_nxt+22ð%                SBC     seg_seq+22ú%                STA     scratch+23%                LDA     rcv_nxt+33%                SBC     seg_seq+33%                STA     scratch+33"%                LDX     scratch+23,%                LDY     scratch+336.Z%3@\        ç __DEBUG__3J$                JSR     prinline3T!                EQUS    "DS "3^                BRK3h%                JSR     PrintHex23r#                LDX     scratch3|%                LDY     scratch+13†%                JSR     PrintHex23\        FI3š,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%3¤%                LDA     scratch+33®\               CMP     #03¸$                BNE     DDnogood3Â%                LDA     scratch+23Ì\               CMP     #03Ö$                BNE     DDnogood3à%                LDA     scratch+13ê\               CMP     #03ô$                BNE     DDnogood3þ                CLC4%                LDA     tcprx_out4$                SBC     tcprx_in4#                CMP     scratch4&$                BEQ     DDnogood40#                BCS     DDokds24:.DDnogood4D.Z%4N\        ç __DEBUG__4X$                JSR     prinline4b%                EQUS    "Bad seg"4l                EQUB    134v                BRK4€\        FI4Š,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%4”#                JMP     tcp_ack4ž4¨&.DDokds2     :     LDA     rlength4²                SEC4¼#                SBC     scratch4Æ#                STA     rlength4Ð%                LDA     rlength+14Ú                SBC     #04ä%                STA     rlength+14î                 LDA     data4ø                CLC5#                ADC     scratch5                 STA     data5"                LDA     data+15                 ADC     #05*"                STA     data+154.DDyessame5>.Z%5H\        ç __DEBUG__5R$                JSR     prinline5\%                EQUS    "out,in="5f                BRK5p%                LDA     tcprx_out5z%                JSR     PrintHex15„                LDA     #325Ž"                JSR     OSWRCH5˜$                LDA     tcprx_in5¢%                JSR     PrintHex15¬"                JSR     OSNEWL5¶\        FI5À,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%5Ê%                LDA     rlength+15Ô\               CMP     #05Þ%                BNE     DDtoomuch5è                CLC5ò%                LDA     tcprx_out5ü$                SBC     tcprx_in6#                CMP     rlength6(                BCS     DDnottoomuch6(                BEQ     DDnottoomuch6$N               \ At the moment we don't over-advertise the window, so this6.N               \ should never happen.  This will change if Martyn gets his68P               \ evil way, though.  Even then we hope it would never happen,6BN               \ but we have to do the best we can in the face of badness.6L.DDtoomuch6V.Z%6`\        ç __DEBUG__6j$                JSR     prinline6t)                EQUS    "[Too much!]"6~                BRK6ˆ\        FI6’,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%6œ#                JMP     tcp_ack6¦.DDnottoomuch6°                 LDY     #&FF6º$                LDX     tcprx_in6Ä.DDcopy      :     INY6Î#                CPY     rlength6Ø"                BEQ     DDdone6â$                LDA     (data),Y6ì*                STA     tcprx_buffer,X6ö                INX7"                JMP     DDcopy7
'.DDdone      :     STX     tcprx_in7                CLC7#                LDA     rcv_nxt7(#                ADC     rlength72#                STA     rcv_nxt7<%                LDA     rcv_nxt+17F%                ADC     rlength+17P%                STA     rcv_nxt+17Z%                LDA     rcv_nxt+27d                ADC     #07n%                STA     rcv_nxt+27x#                BCC     DDskip37‚%                INC     rcv_nxt+37Œ+.DDskip3     :     LDA     our_fin_flag7–\               CMP     #07 #                BEQ     tcp_ack7ª#                LDA     rcv_nxt7´                SEC7¾                ADC     #07È#                STA     rcv_nxt7Ò%                LDA     rcv_nxt+17Ü                ADC     #07æ%                STA     rcv_nxt+17ð%                LDA     rcv_nxt+27ú                ADC     #08%                STA     rcv_nxt+28#                BCC     tcp_ack8%                INC     rcv_nxt+38"#                JMP     tcp_ack8,86.tcp_ack8@O               \ We hold back ACK frames by 1/10 second, in hopes that they8J9               \ can be merged with some other frame.8T8^G               \ If we've already delayed an ACK, send this one now8h%                LDA     ack_timer8r\               CMP     #08|(                BNE     tcp_ack_send8†8K               \ If there is a frame about to go out, add the ACK to it8š#                LDA     tx_flag8¤\               CMP     #08®                 BNE     DDfq8¸8Â>               \ Set the timer and forget about it for now8Ì                LDA     #68Ö%                STA     ack_timer8à                RTS8ê8ô.tcp_ack_send8þO               \ If a segment is about to go out, piggyback the ACK onto it9#                LDA     tx_flag9\               CMP     #09!                BEQ     DDnfq9&90	.DDfq9:*                LDA     tcp_retransmit9D%                STA     tcp_frame9N,                LDA     tcp_retransmit+19X'                STA     tcp_frame+19b%                JMP     DDset_ack9l9vM               \ We can't use tcp_buffer to generate ACK frames, as there9€K               \ may be a data segment there waiting to be transmitted.9Š3.DDnfq       :     LDX     #tcpack_buffer € 2559”0                LDY     #tcpack_buffer  2569ž%                STX     tcp_frame9¨'                STY     tcp_frame+19²                LDY     #249¼                 LDA     #&509Æ)                STA     (tcp_frame),Y9Ð                LDY     #109Ú                LDA     #09ä)                STA     (tcp_frame),Y9î                INY9ø                LDA     #20:)                STA     (tcp_frame),Y:                LDA     #0:                PHA: (                LDA     our_fin_flag:*                CMP     #1:4$                BNE     DDno_fin:>                PLA:H                „A     #FIN:R                PHA:\                LDA     #2:f(                STA     our_fin_flag:p.DDno_fin    :     PLA:z                LDY     #25:„)                STA     (tcp_frame),Y:Ž                INY:˜                LDA     #0:¢)                STA     (tcp_frame),Y:¬                INY:¶)                STA     (tcp_frame),Y:À%                LDA     snd_nxt+3:Ê                LDY     #16:Ô)                STA     (tcp_frame),Y:Þ                INY:è%                LDA     snd_nxt+2:ò)                STA     (tcp_frame),Y:ü                INY;%                LDA     snd_nxt+1;)                STA     (tcp_frame),Y;                INY;$#                LDA     snd_nxt;.)                STA     (tcp_frame),Y;8".DDset_ack   :     LDY     #25;B)                LDA     (tcp_frame),Y;L                „A     #ACK;V)                STA     (tcp_frame),Y;`                LDY     #20;j%                LDA     rcv_nxt+3;t)                STA     (tcp_frame),Y;~                INY;ˆ%                LDA     rcv_nxt+2;’)                STA     (tcp_frame),Y;œ                INY;¦%                LDA     rcv_nxt+1;°)                STA     (tcp_frame),Y;º                INY;Ä#                LDA     rcv_nxt;Î)                STA     (tcp_frame),Y;Ø                CLC;â%                LDA     tcprx_out;ì$                SBC     tcprx_in;ö                LDY     #27<;                STA     (tcp_frame),Y      \ set window<
                CMP     #0<+                BNE     DDnotzerowindow<                LDA     #1<(#                STA     zwindow<2.DDnotzerowindow<<                LDA     #0<F%                STA     ack_timer<PD               \ If we created this frame, send it and delete it<Z#                LDA     tx_flag<d\               CMP     #0<n!                BNE     DDrts<x$                JMP     tcp_send<‚.DDrts       :     RTS<Œ<–.tcp_send<        \ BLOCK<ª.Z%<´\        ç __DEBUG__<¾$                JSR     prinline<È(                EQUS    "tcp_send: "<Ò                BRK<Ü\        FI<æ,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%<ð                LDY     #12<ú%                LDA     ourport+1=)                STA     (tcp_frame),Y=                INY=#                LDA     ourport=")                STA     (tcp_frame),Y=,                INY=6%                LDA     hisport+1=@)                STA     (tcp_frame),Y=J                INY=T#                LDA     hisport=^)                STA     (tcp_frame),Y=h.tcp_send_port=r                LDY     #0=|!                LDA     my_ip=†)                STA     (tcp_frame),Y=                INY=š#                LDA     my_ip+1=¤)                STA     (tcp_frame),Y=®                INY=¸#                LDA     my_ip+2=Â)                STA     (tcp_frame),Y=Ì                INY=Ö#                LDA     my_ip+3=à)                STA     (tcp_frame),Y=ê                INY=ô"                LDA     his_ip=þ"                STA     pblk+6>)                STA     (tcp_frame),Y>                INY>$                LDA     his_ip+1>&"                STA     pblk+7>0)                STA     (tcp_frame),Y>:                INY>D$                LDA     his_ip+2>N"                STA     pblk+8>X)                STA     (tcp_frame),Y>b                INY>l$                LDA     his_ip+3>v"                STA     pblk+9>€)                STA     (tcp_frame),Y>Š                INY>”                LDA     #0>ž)                STA     (tcp_frame),Y>¨                INY>²2                LDA     #6             \ proto>¼)                STA     (tcp_frame),Y>Æ                 STA     pblk>Ð1                LDA     #0             \ xsum>Ú                LDY     #28>ä)                STA     (tcp_frame),Y>î                INY>ø)                STA     (tcp_frame),Y?                LDY     #11?)                LDA     (tcp_frame),Y?                CLC?                 ADC     #12?*%                LDX     tcp_frame?4'                LDY     tcp_frame+1?>'                JSR     ip_checksum?H                TYA?R                LDY     #28?\)                STA     (tcp_frame),Y?f                TXA?p                INY?z)                STA     (tcp_frame),Y?„%                LDA     tcp_frame?Ž                CLC?˜@                ADC     #12            \ strip pseudo header?¢"                STA     pblk+2?¬'                LDA     tcp_frame+1?¶                ADC     #0?À"                STA     pblk+3?Ê                LDY     #10?Ô)                LDA     (tcp_frame),Y?Þ"                STA     pblk+5?è                INY?ò)                LDA     (tcp_frame),Y?ü"                STA     pblk+4@'                LDX     #pblk € 255@'                LDY     #pblk  256@'                JMP     send_packet@$@..send_bootp@80                LDA     #tcpack_buffer € 255@B%                STA     tcp_frame@L0                LDA     #tcpack_buffer  256@V'                STA     tcp_frame+1@`                LDY     #12@j                LDA     #0@t)                STA     (tcp_frame),Y@~                INY@ˆ                INY@’)                STA     (tcp_frame),Y@œ                DEY@¦                LDA     #68@°)                STA     (tcp_frame),Y@º                INY@Ä                INY@Î                LDA     #67@Ø)                STA     (tcp_frame),Y@â                 LDA     #&34@ì                LDY     #11@ö)                STA     (tcp_frame),YA                LDY     #17A
)                STA     (tcp_frame),YA                LDA     #1A                LDY     #10A()                STA     (tcp_frame),YA2                LDA     #0A<                LDY     #16AF)                STA     (tcp_frame),YAP                 LDA     #255AZ"                STA     his_ipAd$                STA     his_ip+1An$                STA     his_ip+2Ax$                STA     his_ip+3A‚                LDY     #20AŒ9                LDA     #1             \ boot requestA–)                STA     (tcp_frame),YA                 LDA     #80Aª                INYA´)                STA     (tcp_frame),YA¾                INYAÈ                LDA     #2AÒ)                STA     (tcp_frame),YAÜ                INYAæ1                LDA     #0             \ hopsAð)                STA     (tcp_frame),YAú                INYB0                STA     (tcp_frame),Y  \ xidB                INYB)                STA     (tcp_frame),YB"                INYB,)                STA     (tcp_frame),YB6                INYB@)                STA     (tcp_frame),YBJ                INYBT1                STA     (tcp_frame),Y  \ secsB^                INYBh                LDA     #1Br)                STA     (tcp_frame),YB|B†B?               \ must have already initialised port numbersBš.udp_sendB¤                LDY     #0B®!                LDA     my_ipB¸)                STA     (tcp_frame),YBÂ                INYBÌ#                LDA     my_ip+1BÖ)                STA     (tcp_frame),YBà                INYBê#                LDA     my_ip+2Bô)                STA     (tcp_frame),YBþ                INYC#                LDA     my_ip+3C)                STA     (tcp_frame),YC                INYC&"                LDA     his_ipC0"                STA     pblk+6C:)                STA     (tcp_frame),YCD                INYCN$                LDA     his_ip+1CX"                STA     pblk+7Cb)                STA     (tcp_frame),YCl                INYCv$                LDA     his_ip+2C€"                STA     pblk+8CŠ)                STA     (tcp_frame),YC”                INYCž$                LDA     his_ip+3C¨"                STA     pblk+9C²)                STA     (tcp_frame),YC¼                INYCÆ                LDA     #0CÐ)                STA     (tcp_frame),YCÚ                INYCä2                LDA     #17            \ protoCî)                STA     (tcp_frame),YCø                 STA     pblkD1                LDA     #0             \ xsumD                LDY     #18D)                STA     (tcp_frame),YD                 INYD*)                STA     (tcp_frame),YD4                LDY     #11D>)                LDA     (tcp_frame),YDH                CLCDR                ADC     #12D\%                LDX     tcp_frameDf'                LDY     tcp_frame+1Dp'                JSR     ip_checksumDz                TYAD„                LDY     #18DŽ)                STA     (tcp_frame),YD˜                TXAD¢                INYD¬)                STA     (tcp_frame),YD¶%                LDA     tcp_frameDÀ                CLCDÊ@                ADC     #12            \ strip pseudo headerDÔ"                STA     pblk+2DÞ'                LDA     tcp_frame+1Dè                ADC     #0Dò"                STA     pblk+3Dü                LDY     #10E)                LDA     (tcp_frame),YE"                STA     pblk+5E                INYE$)                LDA     (tcp_frame),YE."                STA     pblk+4E8'                LDX     #pblk € 255EB'                LDY     #pblk  256EL'                JMP     send_packetEVE`	.icmpEj.Z%Et\        ç __DEBUG__E~$                JSR     prinlineEˆ#                EQUS    "ICMP "E’                BRKEœ\        FIE¦,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%E°                LDY     #0Eº$                LDA     (data),YEÄ.Z%EÎ\        ç __DEBUG__EØ%                JSR     PrintHex1Eâ\        FIEì,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%Eö                CMP     #8F(                BNE     EEnotechoreqF
(                JMP     icmp_echoreqF.EEnotechoreqF.Z%F(\        ç __DEBUG__F2"                JSR     OSNEWLF<\        FIFF,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%FP                RTSFZFd.icmp_echoreqFn.Z%Fx\        ç __DEBUG__F‚$                JSR     prinlineFŒ+                EQUS    " Echo Request"F–                BRKF "                JSR     OSNEWLFª\        FIF´,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%F¾                LDY     #0FÈ                TYAFÒ?                STA     (data),Y       \ mark as Echo ReplyFÜ:                LDY     #2             \ zero checksumFæ$                STA     (data),YFð                INYFú$                STA     (data),YG                 LDX     dataG"                LDY     data+1G#                LDA     rlengthG"'                JSR     ip_checksumG,                TYAG6                LDY     #2G@$                STA     (data),YGJ                TXAGT                INYG^$                STA     (data),YGh                 LDA     dataGr"                STA     pblk+2G|"                LDA     data+1G†"                STA     pblk+3G#                LDA     rlengthGš"                STA     pblk+4G¤%                LDA     rlength+1G®"                STA     pblk+5G¸1                LDA     #1             \ ICMPGÂ                 STA     pblkGÌ"                LDA     his_ipGÖ"                STA     pblk+6Gà$                LDA     his_ip+1Gê"                STA     pblk+7Gô$                LDA     his_ip+2Gþ"                STA     pblk+8H$                LDA     his_ip+3H"                STA     pblk+9H'                LDX     #pblk € 255H&'                LDY     #pblk  256H0'                JMP     send_packetH:HD.send_packetHN"                STX     paramsHX$                STY     params+1Hb.Z%Hl\        ç __DEBUG__Hv$                JSR     prinlineH€*                EQUS    "send_packet "HŠ                BRKH”\        FIHž,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%H¨E                LDY     #4             \ calc size of data+headerH²&                LDA     (params),YH¼                CLCHÆ                 ADC     #&14HÐ                TAXHÚ                PHAHä                INYHî&                LDA     (params),YHø                ADC     #0I                TAYI                PHAI.Z%I \        ç __DEBUG__I*%                JSR     PrintHex2I4\        FII>,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%IH(                LDA     txbuffer_ptrIR#                STA     temp2+1I\                LDA     #0If!                STA     temp2Ip.Z%Iz\        ç __DEBUG__I„                LDA     #32IŽ!                JSR     &FFEEI˜%                JSR     PrintHex2I¢\        FII¬,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%I¶                 LDA     #&45IÀ                LDY     #0IÊ=                STA     (temp2),Y              \ Vers IHLIÔ                TYAIÞ                INYIè7                STA     (temp2),Y              \ ¸SIò                INYIü                PLAJ?                STA     (temp2),Y              \ Total sizeJ                INYJ                PLAJ$%                STA     (temp2),YJ.                INYJ8!                LDA     clockJB7                STA     (temp2),Y              \ IDJL                INYJV#                LDA     clock+1J`%                STA     (temp2),YJj                INYJt                LDA     #0J~:                STA     (temp2),Y              \ FlagsJˆ                INYJ’<                STA     (temp2),Y              \ FragOffJœ                INYJ¦                LDA     #64J°8                STA     (temp2),Y              \ TTLJº                LDY     #0JÄ&                LDA     (params),YJÎ                LDY     #9JØ:                STA     (temp2),Y              \ protoJâ                LDA     #0Jì                INYJö=                STA     (temp2),Y              \ checksumK                INYK
%                STA     (temp2),YK                LDY     #6K&                LDA     (params),YK(                PHAK2                INYK<&                LDA     (params),YKF                PHAKP                INYKZ&                LDA     (params),YKd                PHAKn                INYKx&                LDA     (params),YK‚                LDY     #19KŒ%                STA     (temp2),YK–                DEYK                 PLAKª%                STA     (temp2),YK´                DEYK¾                PLAKÈ%                STA     (temp2),YKÒ                DEYKÜ                PLAKæ%                STA     (temp2),YKð                LDY     #12Kú!                LDA     my_ipL%                STA     (temp2),YL#                LDA     my_ip+1L                INYL"%                STA     (temp2),YL,#                LDA     my_ip+2L6                INYL@%                STA     (temp2),YLJ#                LDA     my_ip+3LT                INYL^%                STA     (temp2),YLh                LDY     #20Lr                LDA     #0L|                INYL†%                STA     (temp2),YL                INYLš%                STA     (temp2),YL¤                INYL®%                STA     (temp2),YL¸                INYLÂ%                STA     (temp2),YLÌ!                LDX     temp2LÖ#                LDY     temp2+1Là                 LDA     #&14Lê'                JSR     ip_checksumLô                TYALþ?                LDY     #10            \ store the checksumM%                STA     (temp2),YM                INYM                TXAM&%                STA     (temp2),YM0                LDY     #2M:&                LDA     (params),YMD!                STA     cpsrcMN                INYMX&                LDA     (params),YMb#                STA     cpsrc+1Ml                INYMv&                LDA     (params),YM€!                STA     cplenMŠ                INYM”&                LDA     (params),YMž#                STA     cplen+1M¨!                LDA     temp2M²                CLCM¼                 ADC     #&14MÆ!                STA     cpdstMÐ#                LDA     temp2+1MÚ                ADC     #0Mä#                STA     cpdst+1Mî&                JSR     block_copyMø"                LDA     his_ipN                 CMP     #&FFN$                BNE     EEnot_bcN$                LDA     his_ip+1N                  CMP     #&FFN*$                BNE     EEnot_bcN4$                LDA     his_ip+2N>                 CMP     #&FFNH$                BNE     EEnot_bcNR$                LDA     his_ip+3N\                 CMP     #&FFNf*                BEQ     EEis_broadcastNpP.EEnot_bc    :     JSR     do_route               \ check for specific routeNzK                LDA     his_ip                 \ is destination on thisN„<                CMP     my_ip                  \ subnet?NŽ'                BNE     EEnot_localN˜$                LDA     his_ip+1N¢#                CMP     my_ip+1N¬'                BNE     EEnot_localN¶$                LDA     his_ip+2NÀ#                CMP     my_ip+2NÊ&                BEQ     EEis_localNÔM.EEnot_local :     LDA     #0                     \ use the default routeNÞ"                STA     his_ipNè$                STA     his_ip+1Nò$                STA     his_ip+2Nü$                STA     his_ip+3O$                JSR     do_routeO'.EEis_local  :     LDA     his_ip+3O                 CMP     #&FFO$*                BEQ     EEis_broadcastO.H                JSR     do_arp                 \ look up his addressO8$                LDA     rstationOBE\               CMP     #0                     \ valid arp entry?OL"                BNE     EEsendOV'                JMP     EEdont_sendO`".EEsend      :     LDA     #50Oj!                STA     retryOt$                JMP     EEtry_txO~#.EEis_broadcast :  LDA     #240Oˆ$                STA     rstationO’                LDA     #0Oœ&                STA     rstation+1O¦                 LDA     #&FEO°#                STA     bccountOº.EEtry_txOÄ#                LDA     blk_ptrOÎ"                STA     temp+1OØ                LDA     #0Oâ                 STA     tempOì                 LDA     #&81Oö                LDY     #0P$                STA     (temp),YP
                 LDA     #&D2P                INYP$                STA     (temp),YP($                LDA     rstationP2                INYP<$                STA     (temp),YPF&                LDA     rstation+1PP                INYPZ$                STA     (temp),YPd!                LDA     temp2Pn                INYPx$                STA     (temp),YP‚#                LDA     temp2+1PŒ                INYP–$                STA     (temp),YP                  LDA     #&FFPª                INYP´$                STA     (temp),YP¾                INYPÈ$                STA     (temp),YPÒ                LDY     #10PÜ$                STA     (temp),YPæ                INYPð$                STA     (temp),YPú                LDY     #3QA                LDA     (temp2),Y      \ get total length LSBQ                CLCQ                LDY     #4Q"$                ADC     (temp),YQ,                LDY     #8Q6$                STA     (temp),YQ@                LDY     #2QJ0                LDA     (temp2),Y      \ MSBQT                LDY     #5Q^$                ADC     (temp),YQh                LDY     #9Qr$                STA     (temp),YQ|                 LDA     #&10Q†                LDX     #0Q#                LDY     blk_ptrQš"                JSR     OSWORDQ¤$                LDA     his_ip+3Q®                 CMP     #&FFQ¸(                BEQ     EEnext_bcastQÂ#.EEpoll_tx   :     LDA     #&32QÌ"                JSR     OSBYTEQÖ                TXAQà%                BMI     EEpoll_txQê                €     #64Qô\               CMP     #0Qþ;                BEQ     EEdont_send             \ tx OKR!                DEC     retryR!                LDA     retryR\               CMP     #0R&$                BNE     EEtry_txR0!                LDA     #—"?"R:"                JSR     OSWRCHRD.EEdont_sendRN.Z%RX\        ç __DEBUG__Rb"                JSR     OSNEWLRl\        FIRv,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%R€.EErts       :     RTSRŠR”&.EEnext_bcast:     INC     bccountRž#                LDA     bccountR¨'                BNE     EEgo_try_txR²                 LDA     #&FER¼#                STA     bccountRÆ$                INC     rstationRÐ$                LDA     rstationRÚ                 CMP     #&FFRä!                BEQ     EErtsRî'.EEgo_try_tx :     JMP     EEtry_txRøS.do_routeS       \ BLOCKS                LDA     #0S .FFloopS*                TAXS4#                LDA     route,XS>"                CMP     his_ipSH                 BNE     FFnoSR%                LDA     route+1,XS\$                CMP     his_ip+1Sf                 BNE     FFnoSp%                LDA     route+2,XSz$                CMP     his_ip+2S„                 BNE     FFnoSŽ%                LDA     route+3,XS˜$                CMP     his_ip+3S¢                 BNE     FFnoS¬       \ Got a matchS¶%                LDA     route+4,XSÀ"                STA     his_ipSÊ%                LDA     route+5,XSÔ$                STA     his_ip+1SÞ%                LDA     route+6,XSè$                STA     his_ip+2Sò%                LDA     route+7,XSü$                STA     his_ip+3T                RTST#.FFno        :    \ terminator?T#                LDA     route,XT$                 CMP     #&FFT.*                BNE     FFnot_targetedT8%                LDA     route+1,XTB                 CMP     #&FFTL*                BNE     FFnot_targetedTV%                LDA     route+2,XT`                 CMP     #&FFTj*                BNE     FFnot_targetedTt%                LDA     route+3,XT~                 CMP     #&FFTˆ*                BNE     FFnot_targetedT’                RTSTœ.FFnot_targeted:   TXAT¦                CLCT°E                ADC     #8             \ go round for another tryTº"                JMP     FFloopTÄTÎ.do_arpTØ       \ BLOCKTâ                LDA     #0Tì.GGloop      :     TAXTö!                LDA     arp,XU"                CMP     his_ipU
                 BNE     GGnoU#                LDA     arp+1,XU$                CMP     his_ip+1U(                 BNE     GGnoU2#                LDA     arp+2,XU<$                CMP     his_ip+2UF                 BNE     GGnoUP#                LDA     arp+3,XUZ$                CMP     his_ip+3Ud                 BNE     GGnoUn#                LDA     arp+4,XUx$                STA     rstationU‚#                LDA     arp+5,XUŒ&                STA     rstation+1U–                RTSU .GGno        :     TXAUª                CLCU´                ADC     #6U¾:                CMP     #60            \ Finished yet?UÈ"                BNE     GGloopUÒ<                LDA     #0             \ He's not there.UÜ$                STA     rstationUæ&                STA     rstation+1Uð#                LDA     blk_ptrUú"                STA     temp+1V                LDA     #0V                 STA     tempV"                LDA     his_ipV"                LDY     #8V,$                STA     (temp),YV6$                LDA     his_ip+1V@                INYVJ$                STA     (temp),YVT$                LDA     his_ip+2V^                INYVh$                STA     (temp),YVr$                LDA     his_ip+3V|                INYV†$                STA     (temp),YV!                LDA     my_ipVš                LDY     #4V¤$                STA     (temp),YV®#                LDA     my_ip+1V¸                INYVÂ$                STA     (temp),YVÌ#                LDA     my_ip+2VÖ                INYVà$                STA     (temp),YVê#                LDA     my_ip+3Vô                INYVþ$                STA     (temp),YW                LDY     #0W                 LDA     #&A1W$                STA     (temp),YW&                 LDA     #&D2W0                INYW:$                STA     (temp),YWD                 LDA     #&FFWN                INYWX$                STA     (temp),YWb                INYWl$                STA     (temp),YWv                 LDA     #&10W€                LDX     #0WŠ#                LDY     blk_ptrW”"                JMP     OSWORDWžW¨.ip_checksumW²       \ BLOCKW¼.       \ entry YX point to\ BLOCK. A=countWÆ%       \ exit YX contain checksumWÐ%                STA     scratch+3WÚ!                LDA     temp2Wä                PHAWî#                LDA     temp2+1Wø                PHAX!                STX     temp2X#                STY     temp2+1X                LDY     #0X #                STY     scratchX*%                STY     scratch+1X4%                STY     scratch+2X>.HHloopXH%                LDA     (temp2),YXR                PHAX\                INYXf%                CPY     scratch+3Xp                CLCXz!                BEQ     HHendX„%                LDA     (temp2),YXŽ#                ADC     scratchX˜#                STA     scratchX¢.HHend       :     PLAX¬%                ADC     scratch+1X¶%                STA     scratch+1XÀ%                LDA     scratch+2XÊ                ADC     #0XÔ%                STA     scratch+2XÞ%                CPY     scratch+3Xè#                BEQ     HHloop2Xò                INYXü%                CPY     scratch+3Y"                BNE     HHloopY(.HHloop2     :     LDA     scratch+2Y\               CMP     #0Y$"                BEQ     HHskipY.                CLCY8#                ADC     scratchYB#                STA     scratchYL%                LDA     scratch+1YV                ADC     #0Y`%                STA     scratch+1Yj                LDA     #0Yt                ADC     #0Y~%                STA     scratch+2Yˆ#                JMP     HHloop2Y’.HHskipYœ#                LDA     scratchY¦                ‚     #&FFY°                TAXYº%                LDA     scratch+1YÄ                ‚     #&FFYÎ                TAYYØ                PLAYâ#                STA     temp2+1Yì                PLAYö!                STA     temp2Z                RTSZ
Z.PrintHex2Z                PHAZ(                TYAZ2%                JSR     PrintHex1Z<                TXAZF%                JSR     PrintHex1ZP                PLAZZ                RTSZdZn.PrintHex1Zx       \ BLOCKZ‚                PHAZŒ                €     #240Z–                LSR     AZ                 LSR     AZª                LSR     AZ´                LSR     AZ¾'                JSR     HHHexNibbleZÈ                PLAZÒ                PHAZÜ                €     #15Zæ'                JSR     HHHexNibbleZð                PLAZú                RTS[.HHHexNibble[               \ BLOCK[                PHA["                CMP     #10[,(                BCC     HHnibble_dec[6                CLC[@$                ADC     #—"A"-10[J"                JSR     OSWRCH[T                PLA[^                RTS[h[r.HHnibble_dec[|!                ADC     #—"0"[†"                JSR     OSWRCH[                PLA[š                RTS[¤[®.prinline[¸       \ BLOCK[Â                PLA[Ì                CLC[Ö                ADC     #1[à"                STA     pltemp[ê                PLA[ô                ADC     #0[þ$                STA     pltemp+1\                TYA\                PHA\                LDY     #0\&.IIloop\0&                LDA     (pltemp),Y\:"                BEQ     IIdone\D"                JSR     OSASCI\N"                INC     pltemp\X"                BNE     IIloop\b$                INC     pltemp+1\l"                BNE     IIloop\v.IIdone\€                PLA\Š                TAY\”"                INC     pltemp\ž"                BNE     IIskip\¨$                INC     pltemp+1\²'.IIskip      :     JMP     (pltemp)\¼\Æ
.error\Ð       \ BLOCK\Ú                PLA\ä                CLC\î                ADC     #1\ø"                STA     pltemp]                PLA]                ADC     #0]$                STA     pltemp+1]                 TYA]*                PHA]4                LDY     #0]>                 STY     &100]H&                LDA     (pltemp),Y]R                 STA     &101]\                INY]f                LDX     #2]p.JJloop]z&                LDA     (pltemp),Y]„"                STA     &100,X]Ž\               CMP     #0]˜"                BEQ     JJdone]¢                INX]¬"                INC     pltemp]¶"                BNE     JJloop]À$                INC     pltemp+1]Ê"                BNE     JJloop]Ô.JJdone]Þ                PLA]è                TAY]ò"                INC     pltemp]ü"                BNE     JJskip^$                INC     pltemp+1^#.JJskip      :     JMP     &100^^$^..block_copy^8       \ BLOCK^B                 LDA     temp^L                PHA^V"                LDA     temp+1^`                PHA^j!                LDA     temp2^t                PHA^~#                LDA     temp2+1^ˆ                PHA^’!                LDA     cpsrc^œ                 STA     temp^¦#                LDA     cpsrc+1^°"                STA     temp+1^º!                LDA     cpdst^Ä!                STA     temp2^Î#                LDA     cpdst+1^Ø#                STA     temp2+1^â                LDY     #0^ì$.KKloop      :     DEC     cplen^ö!                LDA     cplen_                 CMP     #&FF_
"                BNE     KKskip_#                DEC     cplen+1_#                LDA     cplen+1_(                 CMP     #&FF_2"                BEQ     KKdone_<'.KKskip      :     LDA     (temp),Y_F%                STA     (temp2),Y_P                INY_Z                CPY     #0_d"                BNE     KKloop_n"                INC     temp+1_x#                INC     temp2+1_‚"                JMP     KKloop_Œ.KKdone      :     PLA_–#                STA     temp2+1_                 PLA_ª!                STA     temp2_´                PLA_¾"                STA     temp+1_È                PLA_Ò                 STA     temp_Ü                RTS_æ_ð.arp_request_ú       \ BLOCK`.Z%`\        ç __DEBUG__`$                JSR     prinline`"*                EQUS    "ARP request "`,                BRK`6\        FI`@,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%`J#                LDA     blk_ptr`T"                STA     temp+1`^                LDA     #0`h                 STA     temp`r                LDY     #5`|$                LDA     (temp),Y`†                 STA     data`                INY`š$                LDA     (temp),Y`¤"                STA     data+1`®                LDY     #0`¸$                LDA     (data),Y`Â"                STA     his_ip`Ì                INY`Ö$                LDA     (data),Y`à$                STA     his_ip+1`ê                INY`ô$                LDA     (data),Y`þ$                STA     his_ip+2a                INYa$                LDA     (data),Ya$                STA     his_ip+3a&                LDY     #4a0$                LDA     (data),Ya:!                CMP     my_ipaD$                BNE     LLnot_meaN                INYaX$                LDA     (data),Yab#                CMP     my_ip+1al$                BNE     LLnot_meav                INYa€$                LDA     (data),YaŠ#                CMP     my_ip+2a”$                BNE     LLnot_meaž                INYa¨$                LDA     (data),Ya²#                CMP     my_ip+3a¼#                BEQ     LLis_meaÆ.LLnot_meaÐ.Z%aÚ\        ç __DEBUG__aä$                JSR     prinlineaî(                EQUS    " (ignored)"aø                EQUB    13b                BRKb\        FIb,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%b #                JMP     open_rxb*b4.LLis_meb>.Z%bH\        ç __DEBUG__bR$                JSR     prinlineb\%                EQUS    " (erk!)"bf                EQUB    13bp                BRKbz\        FIb„,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%bŽ#                LDA     blk_ptrb˜"                STA     temp+1b¢                LDA     #0b¬                 STA     tempb¶                 LDY     #&20bÀ!                LDA     my_ipbÊ$                STA     (temp),YbÔ#                LDA     my_ip+1bÞ                INYbè$                STA     (temp),Ybò#                LDA     my_ip+2bü                INYc$                STA     (temp),Yc#                LDA     my_ip+3c                INYc$$                STA     (temp),Yc."                LDA     his_ipc8                INYcB$                STA     (temp),YcL$                LDA     his_ip+1cV                INYc`$                STA     (temp),Ycj$                LDA     his_ip+2ct                INYc~$                STA     (temp),Ycˆ$                LDA     his_ip+3c’                INYcœ$                STA     (temp),Yc¦                 LDA     #&A2c°                LDY     #0cº$                STA     (temp),YcÄ                 LDA     #&D2cÎ                INYcØ$                STA     (temp),Ycâ$                LDA     rstationcì                INYcö$                STA     (temp),Yd&                LDA     rstation+1d
                INYd$                STA     (temp),Yd                 LDA     #&20d(                INYd2$                STA     (temp),Yd<                CLCdF                ADC     #8dP                LDY     #8dZ$                STA     (temp),Ydd#                LDA     blk_ptrdn                LDY     #5dx$                STA     (temp),Yd‚                LDY     #9dŒ$                STA     (temp),Yd–                 LDA     #&FFd                 LDY     #6dª$                STA     (temp),Yd´                INYd¾$                STA     (temp),YdÈ                LDY     #10dÒ$                STA     (temp),YdÜ                INYdæ$                STA     (temp),Ydð                 LDA     #&10dú                LDX     #0e#                LDY     blk_ptre"                JSR     OSWORDe#                JMP     open_rxe"e,       \ BLOCKe6$.MMsyntax    :     JSR     errore@                BRKeJC                EQUS    "Syntax: *TELNET <ip address> (<port>)"eT                BRKe^eh.telapicmder6       \ Open a TCP connection to some remote hoste|%                LDA     tcp_framee†                PHAe'                LDA     tcp_frame+1eš                PHAe¤(.MMloop      :     LDA     (temp2),Ye®                CMP     #&De¸$                BEQ     MMsyntaxeÂ                CMP     #32eÌ!                BNE     MMgo1eÖ                INYeà"                JMP     MMloopeê(.MMgo1       :     JSR     getNumbereô$                STA     tcp_peereþ%                LDA     (temp2),Yf!                CMP     #—"."f$                BNE     MMsyntaxf                INYf&%                JSR     getNumberf0&                STA     tcp_peer+1f:%                LDA     (temp2),YfD!                CMP     #—"."fN$                BNE     MMsyntaxfX                INYfb%                JSR     getNumberfl&                STA     tcp_peer+2fv%                LDA     (temp2),Yf€!                CMP     #—"."fŠ$                BNE     MMsyntaxf”                INYfž%                JSR     getNumberf¨&                STA     tcp_peer+3f²                LDA     #23f¼#                STA     hisportfÆ%                LDA     (temp2),YfÐ                CMP     #&DfÚ                 BEQ     MMcrfä!                CMP     #—" "fî&                BEQ     MMoksyntaxfø$                JMP     MMsyntaxg.MMoksyntaxg                INYg%                JSR     getNumberg #                STA     hisportg*(.MMcr        :     LDA     tcp_stateg4)                CMP     #STATE_CLOSEDg>%                BEQ     MMokstategH!                JSR     errorgR                BRKg\5                EQUS    "Connection already open"gf                BRKgp!.MMokstate   :     LDA     #0gz(                STA     our_fin_flagg„                LDA     #0gŽ%                STA     hisport+1g˜%                LDA     tcp_timerg¢#                STA     ourportg¬.Z%g¶\        ç __DEBUG__gÀ$                JSR     prinlinegÊ5                EQUS    "TCP open connection to "gÔ                BRKgÞ$                LDA     tcp_peergè%                JSR     PrintHex1gò                LDA     #46gü"                JSR     OSWRCHh&                LDA     tcp_peer+1h%                JSR     PrintHex1h                LDA     #46h$"                JSR     OSWRCHh.&                LDA     tcp_peer+2h8%                JSR     PrintHex1hB                LDA     #46hL"                JSR     OSWRCHhV&                LDA     tcp_peer+3h`%                JSR     PrintHex1hj!                LDA     #—"/"ht"                JSR     OSWRCHh~%                LDA     hisport+1hˆ%                JSR     PrintHex1h’#                LDA     hisporthœ%                JSR     PrintHex1h¦"                JSR     OSNEWLh°\        FIhº,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%hÄ                LDA     #0hÎ$                STA     iac_flaghØ                LDA     #31hâ%                STA     ourport+1hì#                JSR     lock_rxhö-                LDX     #tcp_buffer € 255i-                LDY     #tcp_buffer  256i
%                STX     tcp_framei'                STY     tcp_frame+1i                LDY     #24i(                 LDA     #&50i2)                STA     (tcp_frame),Yi<                LDY     #10iF                LDA     #0iP)                STA     (tcp_frame),YiZ                INYid                LDA     #20in)                STA     (tcp_frame),Yix                 LDA     #SYNi‚                LDY     #25iŒ)                STA     (tcp_frame),Yi–                INYi                 LDA     #0iª)                STA     (tcp_frame),Yi´                INYi¾)                STA     (tcp_frame),YiÈ%                LDA     snd_nxt+3iÒ                LDY     #16iÜ)                STA     (tcp_frame),Yiæ                INYið%                LDA     snd_nxt+2iú)                STA     (tcp_frame),Yj                INYj%                LDA     snd_nxt+1j)                STA     (tcp_frame),Yj"                INYj,#                LDA     snd_nxtj6)                STA     (tcp_frame),Yj@%                JSR     tcp_queuejJ+                LDA     #STATE_SYN_SENTjT%                STA     tcp_statej^%                JSR     unlock_rxjh$                JSR     prinlinejr'                EQUS    "Trying..."j|                BRKj†.MMpollj%                LDA     tcp_statejš.                CMP     #STATE_ESTABLISHEDj¤                 BEQ     MMgoj®)                CMP     #STATE_CLOSEDj¸"                BEQ     MMfailjÂ                 LDA     #126jÌ"                JSR     OSBYTEjÖ                 CPX     #255jà"                BNE     MMpolljê)                LDA     #STATE_CLOSEDjô%                STA     tcp_statejþ                LDA     #0k*                STA     tcp_retransmitk,                STA     tcp_retransmit+1k                PLAk&'                STA     tcp_frame+1k0                PLAk:%                STA     tcp_framekD                 LDA     #&FFkN                RTSkX$.MMfail      :     JSR     errorkb                BRKkl/                EQUS    "Connection failed"kv                BRKk€'.MMgo        :     JSR     prinlinekŠ                EQUB    13k”(                EQUS    "Connected."kž                EQUB    13k¨                BRKk²                PLAk¼'                STA     tcp_frame+1kÆ                PLAkÐ%                STA     tcp_framekÚ                 LDA     #&FFkä                RTSkîkø       \ BLOCKl .insert      :    CPX     #2l'                BEQ     NNinsseriall&                JMP     (old_insv)l l*(.NNinsserial :     JMP     tcp_writel4l>       \ BLOCKlH .remove      :    CPX     #1lR'                BEQ     OOremseriall\&                JMP     (old_remv)lflp(.OOremserial :     LDX     tcprx_outlz$                CPX     tcprx_inl„#                BEQ     OOemptylŽ*                LDA     tcprx_buffer,Xl˜                INXl¢%                STX     tcprx_outl¬$                CPX     tcprx_inl¶'                BNE     OOnozwchecklÀ%                JSR     OOzwchecklÊ'.OOnozwcheck :     LDY     iac_flaglÔ                CPY     #1lÞ"                BEQ     OOiac1lè                CPY     #2lò"                BEQ     OOiac2lü                 CMP     #255m"                BNE     OOiac0m                LDA     #1m$                STA     iac_flagm$?                JMP     OOremserial             \ try againm..OOiac0      :     TAYm8mB                CLCmL                RTSmVm`&.OOiac1      :     STA     iac_cmdmj$                INC     iac_flagmt'                JMP     OOremserialm~mˆ.OOiac2      :     PHAm’                LDA     #0mœ$                STA     iac_flagm¦#                LDA     iac_cmdm°                 CMP     #253mº$                BEQ     OOiac_domÄ                PLAmÎ'                JMP     OOremserialmØmâ#.OOiac_do    :     LDA     #255mì%                JSR     tcp_writemö                 LDA     #252n%                JSR     tcp_writen
                PLAn%                JSR     tcp_writen'                JMP     OOremserialn(n2.OOzwcheck   :     PHAn<#                LDA     zwindownF\               CMP     #0nP!                BEQ     OOrtsnZ                LDA     #2nd%                STA     ack_timernn6                DEC     zwindow        \ zwindow=0nx.OOrts       :     PLAn‚                RTSnŒn–(.OOempty     :     JSR     OOzwcheckn                 SECnª                RTSn´n¾       \ BLOCKnÈ .countpurge  :    CPX     #1nÒ)                BEQ     PPcountserialnÜ                CPX     #2næ,                BEQ     PPcountserialoutnð&                JMP     (old_cnpv)núo&.PPcountserial:    BVS     PPflusho                PHPo                PHPo"                CLCo,%                LDA     tcprx_outo6$                SBC     tcprx_ino@                PLPoJ%                BCS     PPcountedoT.PPcountminuso^                ‚     #255oh.PPcounted   :     TAXor                LDY     #0o|                PLPo†.PPflush     :     RTSooš.PPcountserialouto¤#                BVS     PPflusho®                PHPo¸                PHPoÂ                CLCoÌ%                LDA     tcptx_outoÖ$                SBC     tcptx_inoà                PLPoê%                BCS     PPcountedoô(                JMP     PPcountminusoþp.telnetcmdp       \ BLOCKp%                JSR     telapicmdp&-.QQmainloop  :     LDX     #trx_buf € 255p0*                LDY     #trx_buf  256p:                LDA     #32pD$                JSR     tcp_readpN                TAYpX                LDX     #0pb".QQloop      :     CPY     #32pl"                BEQ     QQdonepv$                LDA     iac_flagp€                CMP     #1pŠ#                BEQ     QQiac1jp”                CMP     #2pž#                BEQ     QQiac2jp¨%                LDA     trx_buf,Xp²                 CMP     #&FFp¼%                BNE     QQnot_iacpÆ                LDA     #1pÐ$                STA     iac_flagpÚ"                JMP     QQnextpä%.QQiac1j     :     JMP     QQiac1pî%.QQiac2j     :     JMP     QQiac2pø.QQnot_iacq"                JSR     OSWRCHq.QQnext      :     INXq                INYq "                JMP     QQloopq*#.QQdone      :     LDA     #145q4                LDX     #0q>                LDY     #0qH"                JSR     OSBYTEqR#                BCS     QQnokeyq\                TYAqf(.QQnormalkey :     JSR     tcp_writeqp(.QQnokey     :     LDA     tcp_stateqz.                CMP     #STATE_ESTABLISHEDq„&                BEQ     QQmainloopqŽ&                JMP     QQfinishedq˜q¢(.QQiac1      :     LDA     trx_buf,Xq¬#                STA     iac_cmdq¶                LDA     #2qÀ$                STA     iac_flagqÊ"                JMP     QQnextqÔqÞ.QQiac2qè%                LDA     trx_buf,Xqò                PHAqü                LDA     #0r$                STA     iac_flagr#                LDA     iac_cmdr                 CMP     #253r$$                BEQ     QQiac_dor.                PLAr8"                JMP     QQnextrBrL$.QQiac_do    :     STX     iac_xrV                 LDA     #&FFr`%                JSR     tcp_writerj                 LDA     #252rt%                JSR     tcp_writer~                PLArˆ%                JSR     tcp_writer’!                LDX     iac_xrœ"                JMP     QQnextr¦r°'.QQfinished  :     JSR     prinlinerº>                EQUS    "Connection closed by remote host"rÄ                EQUB    13rÎ                BRKrØ#                JSR     lock_rxrâ)                LDA     #STATE_CLOSEDrì%                STA     tcp_staterö                LDA     #0s%                STA     tcp_frames
'                STA     tcp_frame+1s*                STA     tcp_retransmits,                STA     tcp_retransmit+1s(%                JSR     unlock_rxs2                 LDA     #&FFs<                RTSsFsP.tcp_queuesZ       \ BLOCKsd                LDY     #11sn)                LDA     (tcp_frame),Ysx                SECs‚E                SBC     #20            \ minus sizeof(tcp_header)sŒ%                STA     data_sizes–                DEYs )                LDA     (tcp_frame),Ysª                SBC     #0s´'                STA     data_size+1s¾                LDY     #25sÈ)                LDA     (tcp_frame),YsÒ$                €     #(SYN+FIN)sÜ\               CMP     #0sæ"                BEQ     RRskipsð                CLCsú%                LDA     data_sizet                ADC     #1t%                STA     data_sizet"                BCC     RRskipt"'                INC     data_size+1t,.RRskipt6                CLCt@#                LDA     snd_nxttJ%                ADC     data_sizetT#                STA     snd_nxtt^%                LDA     snd_nxt+1th'                ADC     data_size+1tr%                STA     snd_nxt+1t|%                LDA     snd_nxt+2t†                ADC     #0t%                STA     snd_nxt+2tš#                BCC     RRskip1t¤%                INC     snd_nxt+3t®.RRskip1t¸N               \ if we're in the established state, we can transmit an acktÂ               \ here.tÌ                LDY     #20tÖ%                LDA     rcv_nxt+3tà)                STA     (tcp_frame),Ytê                INYtô%                LDA     rcv_nxt+2tþ)                STA     (tcp_frame),Yu                INYu%                LDA     rcv_nxt+1u)                STA     (tcp_frame),Yu&                INYu0#                LDA     rcv_nxtu:)                STA     (tcp_frame),YuD                INYuN%                LDA     tcp_stateuX.                CMP     #STATE_ESTABLISHEDub-                BNE     RRnot_establishedul                INYuv)                LDA     (tcp_frame),Yu€                „A     #ACKuŠ)                STA     (tcp_frame),Yu”B                LDA     #0                     \ it's gone nowuž%                STA     ack_timeru¨.RRnot_establishedu²%                LDA     tcp_frameu¼*                STA     tcp_retransmituÆ'                LDA     tcp_frame+1uÐ,                STA     tcp_retransmit+1uÚ\               LDA     #0uä%\               STA     tcp_timeruî                LDA     #1uø#                STA     tx_flagv                RTSvv.tcp_close   :    RTSv v*\ A= character to writev4.tcp_writev>       \ BLOCKvH$                LDX     tcptx_invR                INXv\%                CPX     tcptx_outvf$                BEQ     RRnoroomvp                DEXvz*                STA     tcptx_buffer,Xv„                INXvŽ$                STX     tcptx_inv˜#                JSR     lock_rxv¢H               \ See if we already have a data frame queued up to gov¬*                LDA     tcp_retransmitv¶\               CMP     #0vÀ!                BNE     RRrtsvÊ,                LDA     tcp_retransmit+1vÔ\               CMP     #0vÞ!                BNE     RRrtsvè-               \ No, so kick the TCP codevò                LDA     #0vü%                STA     tcp_timerw(.RRrts       :     JSR     unlock_rxw                CLCw                RTSw$w..RRnoroom    :     SECw8                RTSwBwL$\ A max# of characters to returnwV\ X,Y point to bufferw`.tcp_readwj#                STA     trcountwt!                STX     temp3w~#                STY     temp3+1wˆ                LDY     #0w’(.RRread_data :     LDX     tcprx_outwœ$                CPX     tcprx_inw¦'                BEQ     RRread_donew°*                LDA     tcprx_buffer,Xwº%                STA     (temp3),YwÄ                INYwÎ%                INC     tcprx_outwØ#                DEC     trcountwâ#                LDA     trcountwì\               CMP     #0wö'                BNE     RRread_datax,               \ read all requested datax
                RTSx+.RRread_done :    \ buffer is empty nowx                PHAx(#                LDA     zwindowx2\               CMP     #0x<+                BEQ     RRnotzerowindowxF                LDA     #2xP%                STA     ack_timerxZ6                DEC     zwindow        \ zwindow=0xd.RRnotzerowindowxn                PLAxx                RTSx‚xŒ.lock_rxx–.Z%x \        ç __DEBUG__xª$                JSR     prinlinex´$                EQUS    "[lock]"x¾                BRKxÈ\        FIxÒ,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%xÜ                LDA     #1xæ$                STA     lockflagxð                RTSxúy.unlock_rxy.Z%y\        ç __DEBUG__y"$                JSR     prinliney,&                EQUS    "[unlock]"y6                BRKy@\        FIyJ,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%yT                LDA     #0y^$                STA     lockflagyh                RTSyry|.tcp_transmity†       \ BLOCKy                SECyš$                LDA     tcptx_iny¤%                SBC     tcptx_outy®;                CMP     #80            \ max tx at oncey¸"                BCC     RSskipyÂ                LDA     #80yÌ&.RSskip      :     STA     tx_sizeyÖ                CLCyàD                ADC     #32                    \ plus TCP headeryê#                STA     scratchyô-                LDY     #tcp_buffer  256yþ-                LDX     #tcp_buffer € 255z%                STX     tcp_framez'                STY     tcp_frame+1z                LDY     #32z&%                LDX     tcptx_outz0-.RScopy      :     LDA     tcptx_buffer,Xz:)                STA     (tcp_frame),YzD                INXzN                INYzX#                CPY     scratchzb"                BNE     RScopyzl%                STX     tcptx_outzv                LDY     #24z€                 LDA     #&50zŠ)                STA     (tcp_frame),Yz”                LDY     #10zž                LDA     #0z¨)                STA     (tcp_frame),Yz²                INYz¼#                LDA     scratchzÆ                SECzÐ                SBC     #12zÚ)                STA     (tcp_frame),Yzä                LDA     #0zî                LDY     #25zø)                STA     (tcp_frame),Y{                INY{                LDA     #0{)                STA     (tcp_frame),Y{                 CLC{*%                LDA     tcprx_out{4$                SBC     tcprx_in{>                LDY     #27{H;                STA     (tcp_frame),Y      \ set window{R                CMP     #0{\+                BNE     RSnotzerowindow{f                LDA     #1{p#                STA     zwindow{z.RSnotzerowindow{„%                LDA     snd_nxt+3{Ž                LDY     #16{˜)                STA     (tcp_frame),Y{¢                INY{¬%                LDA     snd_nxt+2{¶)                STA     (tcp_frame),Y{À                INY{Ê%                LDA     snd_nxt+1{Ô)                STA     (tcp_frame),Y{Þ                INY{è#                LDA     snd_nxt{ò)                STA     (tcp_frame),Y{ü%                JMP     tcp_queue||       \ BLOCK|.ack_process|$#                LDA     seg_ack|.#                STA     snd_una|8%                LDA     seg_ack+1|B%                STA     snd_una+1|L%                LDA     seg_ack+2|V%                STA     snd_una+2|`%                LDA     seg_ack+3|j%                STA     snd_una+3|t*                LDA     tcp_retransmit|~%                STA     tcp_frame|ˆ\               CMP     #0|’"                BNE     SSskip|œ,                LDA     tcp_retransmit+1|¦\               CMP     #0|°-                BEQ     SSno_frame_queued|º/.SSskip      :     LDA     tcp_retransmit+1|Ä'                STA     tcp_frame+1|Î                LDY     #19|Ø)                LDA     (tcp_frame),Y|â                CLC|ì#                ADC     tx_size|ö#                STA     scratch}                DEY}
)                LDA     (tcp_frame),Y}                ADC     #0}%                STA     scratch+1}(                DEY}2)                LDA     (tcp_frame),Y}<                ADC     #0}F%                STA     scratch+2}P                DEY}Z)                LDA     (tcp_frame),Y}d                ADC     #0}n%                STA     scratch+3}x%                CMP     snd_una+3}‚"                BNE     SSdiff}Œ%                LDA     scratch+2}–%                CMP     snd_una+2} "                BNE     SSdiff}ª%                LDA     scratch+1}´%                CMP     snd_una+1}¾"                BNE     SSdiff}È#                LDA     scratch}Ò#                CMP     snd_una}Ü"                BNE     SSdiff}æ!.SSok        :     LDA     #0}ð*                STA     tcp_retransmit}ú,                STA     tcp_retransmit+1~#                STA     tx_size~%                STA     tcp_frame~'                STA     tcp_frame+1~".Z%~,\        ç __DEBUG__~6$                JSR     prinline~@1                EQUS    "ACK: dequeued frame"~J                EQUB    13~T                BRK~^\        FI~h,:]ç¬__DEBUG__:Z%=P%-Z%:P%=P%-Z%:O%=O%-Z%~r.SSno_frame_queued~|O               \ We may be able to queue some more data up for transmission~†$                LDA     tcptx_in~%                CMP     tcptx_out~š&                BEQ     SStx_empty~¤(                JMP     tcp_transmit~®.SStx_empty  :     RTS~¸~Â0.SSdiff      :     BCS     SSno_frame_queued~Ì"                JMP     reject~Ö~à .fin_process :    LDA     #1~ê(                STA     our_fin_flag~ô&                LDA     #STATE_FIN~þ%                STA     tcp_state                RTS       \ BLOCK&.arpcmd0                LDX     #0:.TTarploop   :     TXAD                PHAN#                LDA     arp+4,XX\               CMP     #0b%                BEQ     TTarpskipl!                LDA     arp,Xv(                JSR     PrintDecimal€!                LDA     #—"."Š"                JSR     OSWRCH”                PLAž                PHA¨                TAX²#                LDA     arp+1,X¼(                JSR     PrintDecimalÆ!                LDA     #—"."Ð"                JSR     OSWRCHÚ                PLAä                PHAî                TAXø#                LDA     arp+2,X€(                JSR     PrintDecimal€!                LDA     #—"."€"                JSR     OSWRCH€                 PLA€*                PHA€4                TAX€>#                LDA     arp+3,X€H(                JSR     PrintDecimal€R$                JSR     prinline€\"                EQUS    " at "€f                BRK€p                PLA€z                PHA€„                TAX€Ž#                LDA     arp+5,X€˜(                JSR     PrintDecimal€¢!                LDA     #—"."€¬"                JSR     OSWRCH€¶                PLA€À                PHA€Ê                TAX€Ô#                LDA     arp+4,X€Þ(                JSR     PrintDecimal€è"                JSR     OSNEWL€ò.TTarpskip   :     PLA€ü                CLC                ADC     #6                TAX                 CMP     #240$%                BNE     TTarploop.                 LDA     #&FF8                RTSBL.starcmdV       \ BLOCK`,                JSR     cmd_decode_setupj                LDX     #4t).UUcmdlp     :     JSR     cmd_decode~                 CMP     #&FFˆ                 BEQ     UUok’                CPX     #28œ#                BNE     UUcmdlp¦(                JMP     service_exit°.UUok        :     TSXº                LDA     #0Ä"                STA     &106,XÎ(                JMP     service_exitØâ.ipaddrcmdì       \ BLOCKö(.VVloop      :     LDA     (temp2),Y‚                CMP     #&D‚
$                BEQ     VVsyntax‚                CMP     #32‚                 BNE     VVgo‚(                INY‚2"                JMP     VVloop‚<$.VVsyntax    :     JSR     error‚F                BRK‚P:                EQUS    "Syntax: *IPADDR <ip address>"‚Z                BRK‚d(.VVgo        :     JSR     getNumber‚n!                STA     my_ip‚x%                LDA     (temp2),Y‚‚!                CMP     #—"."‚Œ$                BNE     VVsyntax‚–                INY‚ %                JSR     getNumber‚ª#                STA     my_ip+1‚´%                LDA     (temp2),Y‚¾!                CMP     #—"."‚È$                BNE     VVsyntax‚Ò                INY‚Ü%                JSR     getNumber‚æ#                STA     my_ip+2‚ð%                LDA     (temp2),Y‚ú!                CMP     #—"."ƒ$                BNE     VVsyntaxƒ                INYƒ%                JSR     getNumberƒ"#                STA     my_ip+3ƒ,                 LDA     #&FFƒ6                RTSƒ@ƒJ<               \ read a number in decimal from (temp2),YƒTP               \ return=> result in A, Y points to next character, X corruptƒ^.getNumberƒh       \ BLOCKƒr#                LDA     scratchƒ|                PHAƒ†                LDA     #0ƒ#                STA     scratchƒš(.WWnext      :     LDA     (temp2),Yƒ¤!                CMP     #—"0"ƒ®&                BCC     WWnotdigitƒ¸2                CMP     #58            \ '9'+1ƒÂ&                BCS     WWnotdigitƒÌ                SECƒÖ;                SBC     #—"0"           \ get the digitƒà                PHAƒê                LDX     #0ƒô#                LDA     scratchƒþ.WWmultloop  :     CLC„#                ADC     scratch„                INX„                CPX     #9„&&                BNE     WWmultloop„0#                STA     scratch„:                PLA„D                CLC„N#                ADC     scratch„X#                STA     scratch„b                INY„l"                JMP     WWnext„v&.WWnotdigit  :     LDA     scratch„€                TAX„Š                PLA„”#                STA     scratch„ž                TXA„¨                RTS„²„¼.deroutecmd„Æ       \ BLOCK„Ð                 LDA     #&FF„Ú                TAX„ä.XXloop      :     INX„î#                STA     route,X„ø                CPX     #3…"                BNE     XXloop…                RTS…… .routecmd…*       \ BLOCK…4                LDA     #0…>@                STA     scratch+1              \ route entry…H(.YYloop      :     LDA     (temp2),Y…R                CMP     #&D…\$                BEQ     YYsyntax…f                CMP     #32…p                 BNE     YYgo…z                INY…„"                JMP     YYloop…Ž$.YYsyntax    :     JSR     error…˜                BRK…¢=                EQUS    "Syntax: *ROUTE <dest> <gw addr>"…¬                BRK…¶(.YYgo        :     LDA     (temp2),Y…À                CMP     #42…Ê(                BNE     YYnotDefault…Ô'                JMP     YYisDefault…Þ(.YYnotDefault:     JSR     getNumber…è%                LDX     scratch+1…ò#                STA     route,X…ü%                LDA     (temp2),Y†!                CMP     #—"."†$                BNE     YYsyntax†                INY†$%                JSR     getNumber†.%                LDX     scratch+1†8%                STA     route+1,X†B%                LDA     (temp2),Y†L!                CMP     #—"."†V$                BNE     YYsyntax†`                INY†j%                JSR     getNumber†t%                LDX     scratch+1†~%                STA     route+2,X†ˆ%                LDA     (temp2),Y†’!                CMP     #—"."†œ$                BNE     YYsyntax†¦                INY†°%                JSR     getNumber†º%                LDX     scratch+1†Ä%                STA     route+3,X†Î(.YYpart2     :     LDA     (temp2),Y†Ø!                CMP     #—" "†â$                BNE     YYsyntax†ì                INY†ö%                JSR     getNumber‡%                LDX     scratch+1‡
%                STA     route+4,X‡%                LDA     (temp2),Y‡!                CMP     #—"."‡(%                BNE     YYsyntax1‡2                INY‡<%                JSR     getNumber‡F%                LDX     scratch+1‡P%                STA     route+5,X‡Z%                LDA     (temp2),Y‡d!                CMP     #—"."‡n%                BNE     YYsyntax1‡x                INY‡‚%                JSR     getNumber‡Œ%                LDX     scratch+1‡–%                STA     route+6,X‡ %                LDA     (temp2),Y‡ª!                CMP     #—"."‡´%                BNE     YYsyntax1‡¾                INY‡È%                JSR     getNumber‡Ò%                LDX     scratch+1‡Ü%                STA     route+7,X‡æ                 LDA     #&FF‡ð%                STA     route+8,X‡ú%                STA     route+9,Xˆ&                STA     route+10,Xˆ&                STA     route+11,Xˆ                RTSˆ"ˆ,'.YYsyntax1   :     JMP     YYsyntaxˆ6ˆ@.YYisDefaultˆJ%                LDX     scratch+1ˆT                LDA     #0ˆ^#                STA     route,Xˆh%                STA     route+1,Xˆr%                STA     route+2,Xˆ|%                STA     route+3,Xˆ†                INYˆ#                JMP     YYpart2ˆšˆ¤.PrintDecimalˆ®                LDX     #0ˆ¸5       \ BLOCK                          \ do 100sˆÂ#.ZZloop      :     CMP     #&64ˆÌ"                BCC     ZZpingˆÖ                 SBC     #&64ˆà                INXˆê"                JMP     ZZloopˆô.ZZping      :     PHAˆþ                TXA‰#             \   BEQ     ZZskip‰!                ADC     #—"0"‰"                JSR     OSWRCH‰&.ZZskip      :     PLA‰0                LDX     #0‰:4       \ BLOCK                          \ do 10s‰D".ZAloop      :     CMP     #&A‰N"                BCC     ZAping‰X                SBC     #&A‰b                INX‰l"                JMP     ZAloop‰v.ZAping      :     PHA‰€                TXA‰Š#             \   BEQ     ZAskip‰”!                ADC     #—"0"‰ž"                JSR     OSWRCH‰¨.ZAskip      :     PLA‰²!                ADC     #—"0"‰¼"                JMP     OSWRCH‰Æ‰Ð]‰Ú#çO%>&7C00:ñ"Overwriting screen"‰ä=ñ"SAVE iprom/rom "+Ã~mcode%+" "+Ã~O%+" FFFF0000 FFFBBC00"‰î=ÿ"SAVE iprom/rom "+Ã~mcode%+" "+Ã~O%+" FFFF0000 FFFBBC00"ÿ