NEW PREFIX /A2OSX.BUILD AUTO 4,1 .LIST OFF *-------------------------------------- * FRM.New * In: * Y,A = DataLen * X = S.IP.PROTOCOL.xxx * Out: * Y,A = Frame PTR * X = hMem *-------------------------------------- FRM.NewIP stx .8+1 >STYA ZPDataOutLen cpx #S.IP.PROTOCOL.TCP bne .1 lda #S.TCP bra .4 .1 cpx #S.IP.PROTOCOL.UDP bne .2 lda #S.UDP bra .4 .2 lda #S.IP bra .4 .4 sta .5+1 save Header len for reset later clc adc ZPDataOutLen sta ZPFrameOutLen tay lda #0 adc ZPDataOutLen+1 sta ZPFrameOutLen+1 >SYSCALL getmem bcs .9 stx hFrameOut >STYA ZPFrameOutPtr ldy #0 .5 ldx #$ff Self Modified, header length lda #0 .6 sta (ZPFrameOutPtr),y iny dex bne .6 tya * clc adc ZPFrameOutPtr sta ZPDataOutPtr lda #0 adc ZPFrameOutPtr+1 sta ZPDataOutPtr+1 lda DCB.NIC+S.DCB.NIC.FLAGS and #S.DCB.NIC.FLAGS.IPOFFLOAD bne .7 ldy #S.ETH.ETHERTYPE lda /S.ETH.ETHERTYPE.IP sta (ZPFrameOutPtr),y iny lda #S.ETH.ETHERTYPE.IP sta (ZPFrameOutPtr),y ldy #S.IP.V.IHL.DSCP.ECN lda #$45 sta (ZPFrameOutPtr),y * iny * lda #$0 * sta (ZPFrameOutPtr),y * ldy #S.IP.FRAGMENT.FLAGS * sta (ZPFrameOutPtr),y * iny * sta (ZPFrameOutPtr),y ldy #S.IP.IDENTIFICATION+1 lda IP.ID ldx IP.ID+1 inc bne .61 inx stx IP.ID+1 .61 sta IP.ID sta (ZPFrameOutPtr),y dey txa sta (ZPFrameOutPtr),y ldy #S.IP.TTL lda #K.IP.TTL sta (ZPFrameOutPtr),y .7 ldy #S.IP.PROTOCOL .8 lda #$ff sta (ZPFrameOutPtr),y .9 rts *-------------------------------------- FRM.SendIP ldx #3 Copy SRC.IP even if IP offload ldy #S.IP.SRC+3 for proper UDP/TCP CRC calculation .1 lda IPCFG+S.IPCFG.IP,x sta (ZPFrameOutPtr),y dey dex bpl .1 lda DCB.NIC+S.DCB.NIC.FLAGS and #S.DCB.NIC.FLAGS.IPOFFLOAD bne .21 ldy #S.IP.TOTAL.LENGTH+1 lda ZPFrameOutLen sec sbc #S.ETH-2 sta (ZPFrameOutPtr),y dey lda ZPFrameOutLen+1 sbc /S.ETH-2 sta (ZPFrameOutPtr),y lda #0 ldy #S.IP.HDR.CHECKSUM sta (ZPFrameOutPtr),y iny sta (ZPFrameOutPtr),y stz IP.CHECKSUM RESET.IP.CHECKSUM stz IP.CHECKSUM+1 clc ldy #S.IP.V.IHL.DSCP.ECN ldx #10 10 words for IP Header .2 lda (ZPFrameOutPtr),y adc IP.CHECKSUM sta IP.CHECKSUM iny lda (ZPFrameOutPtr),y adc IP.CHECKSUM+1 sta IP.CHECKSUM+1 iny dex bne .2 ldy #S.IP.HDR.CHECKSUM lda IP.CHECKSUM adc #0 eor #$FF sta (ZPFrameOutPtr),y iny lda IP.CHECKSUM+1 adc #0 eor #$FF sta (ZPFrameOutPtr),y .21 ldy #S.IP.PROTOCOL lda (ZPFrameOutPtr),y cmp #S.IP.PROTOCOL.TCP bne .3 jsr TCP.ComputeChecksum bra .5 .3 cmp #S.IP.PROTOCOL.UDP bne .4 lda ZPFrameOutLen sec sbc #S.IP ldy #S.UDP.LENGTH+1 sta (ZPFrameOutPtr),y lda ZPFrameOutLen+1 sbc /S.IP dey sta (ZPFrameOutPtr),y jsr UDP.ComputeChecksum bra .5 .4 cmp #S.IP.PROTOCOL.ICMP bne .5 jsr ICMP.ComputeChecksum .5 lda DCB.NIC+S.DCB.NIC.FLAGS and #S.DCB.NIC.FLAGS.ARPOFFLOAD bne .6 jsr IP.SetDestMAC bcs FRM.Queue .6 jsr FRM.Send.Out bcs FRM.Queue lda hFrameOut beq .9 >SYSCALL FreeMem clc .9 rts *-------------------------------------- FRM.Queue ldy hFrameOut no hFrame, cannot queue for retry beq .9 ldx FRM.QUEUE.Head inx cpx #K.FRMQUEUE.SIZE bne .1 ldx #0 .1 cpx FRM.QUEUE.Tail beq .9 ldy FRM.QUEUE.Head stx FRM.QUEUE.Head sta FRM.QUEUE.State,y lda #K.FRMSEND.RETRY sta FRM.QUEUE.Retry,y lda hFrameOut sta FRM.QUEUE.hMem,y lda ZPFrameOutLen sta FRM.QUEUE.LenL,x lda ZPFrameOutLen+1 sta FRM.QUEUE.LenH,x clc rts .9 sec rts *-------------------------------------- FRM.Retry ldx FRM.QUEUE.Tail .10 cpx FRM.QUEUE.Head beq .8 Queue is empty, exit... lda FRM.QUEUE.hMem,x >SYSCALL GetMemPtr >STYA ZPFrameOutPtr >STYA IOCTL+S.IOCTL.BUFPTR ldx FRM.QUEUE.Tail lda FRM.QUEUE.State,x cmp #ERR.DEV+1 Device error ? bcc .1 yes, retry sending... jsr IP.SetDestMAC Err is ARP or higher, retry getting MAC bcs .2 still error getting dest MAC .1 lda FRM.QUEUE.LenL,x sta IOCTL+S.IOCTL.BYTECNT lda FRM.QUEUE.LenH,x sta IOCTL+S.IOCTL.BYTECNT+1 jsr FRM.Send.IOCTL try sending again to DRV bcc .3 .2 ldx FRM.QUEUE.Tail save error... sta FRM.QUEUE.State,x dec FRM.QUEUE.Retry,x bne .8 exit....until next run! .3 ldx FRM.QUEUE.Tail Success,or max retry, discard entry lda FRM.QUEUE.hMem,x >SYSCALL FreeMem .4 ldx FRM.QUEUE.Tail inx cpx #K.FRMQUEUE.SIZE bne .5 ldx #0 .5 stx FRM.QUEUE.Tail bra .10 .8 rts *-------------------------------------- FRM.Send.Out >DEBUG >LDYA ZPDataOutPtr >STYA IOCTL+S.IOCTL.BUFPTR >LDYA ZPDataOutLen >STYA IOCTL+S.IOCTL.BYTECNT FRM.Send.IOCTL >PUSHW L.IOCTL >PUSHBI IOCTL.WRITE lda IPCFG+S.IPCFG.HDEV >SYSCALL IOCTL rts *-------------------------------------- MAN SAVE /A2OSX.SRC/LIB/LIBTCPIP.S.FRM LOAD /A2OSX.SRC/LIB/LIBTCPIP.S ASM