/****************************************************************************
   
    OS/A65 Version 1.4.0
    Multitasking Operating System for 6502 Computers

    Copyright (C) 1989-1997 Andre Fachat 

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

****************************************************************************/


/******************** input loop ************************/

	.(
	.data
islot	.byt 0
ist	.byt 0		; 0=send data, $80= escaped
ilen	.word 0
ihl	.byt 0

	.zero
ip	.word 0

	.data
iend	.word 0

	.text

&iinit	.(
	lda #<-1
	sta islot
	clc
	rts
	.)

startin .(
/*DB("startin")*/
	lda #<MTU
	ldy #>MTU
	jsr balloc
	bcs oops

&iresp	stx islot
	sta ip			/* reset packet */
	sty ip+1

	jsr getblen
	clc
	adc ip
	sta iend
	tya
	adc ip+1
	sta iend+1
#if 0
DB("iresp: ip=")
lda ip+1:jsr EHexout: lda ip:jsr EHexout
lda #":":jsr ECout:lda slotladr:jsr EHexout
jsr ECrlfout
#endif
	lda #0
	sta ist
	clc
#ifdef DEBUGMEM
	rts
oops	
DB("startin Oops!^m^j")
/*jsr printmem*/
#else
oops	rts
#endif	
	.)

&loopin	.(
	bit islot
	bpl running
	jsr startin
	bcs ende
running

ldx islot
jsr getbadr
bcc adrok2
DB("illegal slot# at loopin^m^j")
adrok2
	ldx #STDIN
	jsr GETC
	bcc gotbyt
ende 	rts
gotbyt
	cmp #SL_END
	bne nogotpacket
	jmp gotpacket
nogotpacket
	cmp #SL_ESC
	bne noesc
	sta ist
	beq loopin
noesc
	bit ist
	bpl noescape
	cmp #SL_ESC_ESC
	beq isesc
	cmp #SL_ESC_END
	bne noescape
	lda #SL_END
	.byt $2c
isesc	lda #SL_ESC
noescape
	ldy #0
	sty ist
	sta (ip),y
	inc ip
	bne l1
	inc ip+1
l1
	lda ip+1
	cmp iend+1
	bcc loopin
	bne discard
	lda ip
	cmp iend
	bcc loopin
DB("input buffer overflow!^m^j")
discard
	ldx islot
	bpl discok
DB("discard with invalid islot!^m^j")
	rts
discok
	jsr getbadr
	bcs boom
	jmp iresp	; no inloop, because if only SL_ENDs are sent, this
			; would become an almost infinite loop
boom	DB("illegal slot# in discok^m^j")
boom1	lda #<-1
	sta islot
	rts

gotpacket
	ldx islot
	lda ip
	sta iend
	ldy ip+1
	sty iend+1
	and #1
	beq even	; fill up with nullbyte if length is odd
	lda #0
	tay
	sta (ip),y
even
	jsr getbadr
	bcc adrok
	DB("illegal slot# in gotpacket^m^j")
	jmp boom1
adrok
	sta ip
	sty ip+1
#if 0
pha:tya:pha
DB("slot=")
lda islot:jsr EHexout
DB("ip=")
lda ip+1:jsr EHexout: lda ip:jsr EHexout
lda #":":jsr ECout:lda slotladr:jsr EHexout
jsr ECrlfout
pla:tay:pla
#endif
	cmp iend
	bne ok
	cpy iend+1
	bne ok
	jmp discard	; zero length packet received
ok

#if 0 /*def DEBUGPKT*/
	/* so what now? */
DB("Received Packet: ip=")
lda ip+1:jsr EHexout:lda ip:jsr EHexout: jsr ECrlfout
#if 1
	jsr printpacket

DB("^m^jip=")
lda ip+1:jsr EHexout:lda ip:jsr EHexout
DB("^m^jiend=")
lda iend+1:jsr EHexout:lda iend:jsr EHexout
#endif
#endif

	/* sanity checks */
	/* header length */
	ldy #IPH_LEN	; length in hi/lo format in IP header
	lda (ip),y
	sta ilen+1
	iny
	lda (ip),y
	sta ilen

#if 0 /*def DEBUGPKT*/
DB("^m^jiph->len=")
lda ilen+1
jsr EHexout
lda ilen
jsr EHexout
jsr ECrlfout
#endif
	clc
	lda ilen
	adc ip
	php
	cmp iend
	bne discp
	plp
	lda ilen+1
	adc ip+1
	cmp iend+1
	beq lenok
	php
discp	
#if 0
DB("discp: ip=")
lda ip+1:jsr EHexout:lda ip:jsr EHexout
DB(" ilen=")
lda ilen+1:jsr EHexout:lda ilen:jsr EHexout
DB(" iend=")
lda iend+1:jsr EHexout:lda iend:jsr EHexout
jsr ECrlfout
#endif
	plp
	jmp discardlen
lenok
	/* header checksum */
	lda #0
	;sta ipl+1
	ldy #IPH_VER
	lda (ip),y
	and #$0f
	asl
	asl
	sta ihl
	;sta ipl
	;clc
	;adc ip
	;sta id		; start of datagram data
	;lda ip+1
	;adc #0
	;sta id+1

	;lda ilen
	;sec
	;sbc ihl
	;sta idlen
	;lda ilen+1
	;sbc #0
	;sta idlen+1

	;lda ipl
	;ldy ipl+1
	lda ihl
	ldy #0
	ldx #ip
	jsr checksum3

#if 0 /*def DEBUGPKT*/
php
pha
txa
pha
DB("Header Checksum=")
pla
tay
jsr EHexout
pla
pha
jsr EHexout
jsr ECrlfout
tya
tax
pla
plp
#endif

	bcs discardcs

	/* check my IP address */
	ldy #IPH_TRG
l2 	lda MyIP-IPH_TRG,y
	cmp (ip),y
	beq bla
	jmp discardip
bla
	iny
	cpy #IPH_TRG+4
	bcc l2

	/**** so that packet is valid -> process it ****/
	/* ip has a pointer to the packet, ihl the header length */
	/* ilen has the total packet length */

	ldy #IPH_PROT
	lda (ip),y

	cmp #1
	bne noicmp
	jsr putbuf
	jmp icmp2
noicmp
	cmp #6
	bne notcp
	jsr putbuf
	jmp tcprx2
notcp
	DB("Packet discarded: unknown protocol^m^j")
	jmp discard

discardcs
	DB("Packet discarded: IP Header checksum^m^j")
disc	jmp discard

discardip
	DB("Packet discarded: wrong IP^m^j")
	jmp discard

discardlen
	DB("Packet discarded: length mismatch^m^j")
	jmp discard

	.)

putbuf	.(
	ldx islot
	lda ilen
	ldy ilen+1
	jsr btrunc	; cut to size
	
	ldx islot
	lda #<-1
	sta islot
	lda ihl
	rts
	.)

	.)
