; TeleSwat.asm ; Copyright Xerox Corporation 1979 ; Last modified August 10, 1979 5:24 PM by Boggs ; outgoing procedures .ent InLd, OutLd ; incoming procedures .bext UpdateTimer .srel InLd: .InLd OutLd: .OutLd il1: .il1 MoveBlock: .MoveBlock userCursor: .userCursor swatCursor: .swatCursor etherState: .etherState pbi: .pbi .nrel ; structure PBI: //Packet Buffer ; [ eDestSrc = 0 ; eDest byte; eSrc byte eType = 1 ; eType word ; // The Pup begins here. length = 2 ; length word type = 3 ; transport byte; type byte pupID = 4 ; id word 2 dPort = 6 ; dPort: @Port sPort = 11 ; sPort: @Port address = 14 ; address word value = 15 ; value word lenBlock = 16 ; lenBlock word block = 17 ; block word maxBlkLen ; ] maxBlkLen = 32. lenPBI = 2+11+3+maxBlkLen .lenPBI: lenPBI etherReset: 3 ; reset the Ethernet interface etherInput: 2 ; start the Ethernet receiver .ePLoc: 600 .eELoc: 602 .eICLoc: 604 .eIPLoc: 605 .eHLoc: 610 ; Call with interrupts disabled. It is the caller's responsibility ; to save and restore the interrupt system state. ; Returns to the return address of the most recent call on OutLd ; with AC0 nonzero. .InLd: jsrii .+1 ; we are going to use the Ethernet etherState mov 3 0 lda 1 .ePLoc ; so save its old state lda 2 lenEtherState jsrii .+1 MoveBlock lda 0 etherReset sio ; reset the interface lda 1 c377 and 1 0 sta 0 @.eHLoc ; our host address ; exchange cursors jsrii .+1 userCursor mov 3 0 ; destination lda 1 .cursorBitMap ; source lda 2 lenCursor ; length jsrii .+1 ; save user cursor MoveBlock lda 0 .cursorBitMap ; destination jsrii .+1 swatCursor mov 3 1 ; source lda 2 lenCursor ; length jsrii .+1 ; install swat cursor MoveBlock ; setup to receive a packet .il1: jsrii .+1 pbi sta 3 @.eIPLoc lda 0 .lenPBI sta 0 @.eICLoc mkzero 0 0 sta 0 @.ePLoc ; done when nonzero lda 0 etherInput sio ; start the receiver ; wait for a packet to arrive or dally to expire il2: jsrii .+1 ; keep the calendar clock updated UpdateTimer lda 0 dally snz 0 0 ; are we dallying? jmp il3 ; no lda 1 @.rtc subl# 1 0 szc ; (dally-@realTimeClock) le 0? jmp SwapReply ; yes. dally expired il3: lda 0 @.ePLoc ; receiver status snz 0 0 ; has it finished? jmp il2 ; no ; a packet has arrived. Filter it. lda 3 @.eIPLoc ; make ac3 -> pbi lda 1 c377 se 0 1 ; good receiver status? jmp .il1 ; no. reject lda 0 eDestSrc,3 and# 1 0 snr ; zero source host? jmp .il1 ; yes. reject movs 0 0 and# 1 0 snr ; broadcast? jmp .il1 ; yes. reject lda 0 eType,3 lda 1 typePup se 0 0 ; does it claim to be a Pup? jmp .il1 ; no. reject lda 0 @.eICLoc lda 1 @.eELoc sub 1 0 ; packet length reported by interface lda 1 length,3 lda 2 c5 addzr 2 1 ; length packet claims to be se 1 0 jmp .il1 ; they disagree. reject lda 0 dPort+1,3 sz 0 0 ; high half of dPort.socket jmp .il1 ; reject lda 0 dPort+2,3 lda 1 socTeleSwat se 0 1 ; low half of dPort.socket jmp .il1 ; reject ; Looks good so far. Dispatch on packet type. lda 0 type,3 lda 1 c377 and 1 0 ; mask off transport byte lda 1 ptSwatStore sne 0 1 ; ptSwatStore? (200b) jmp Store ; yes inc 1 1 sne 0 1 ; ptSwatFetch? (201b) jmp Fetch ; yes inc 1 1 sne 0 1 ; ptSwatSwap? (202b) jmp Swap ; yes inc 1 1 sne 0 1 ; ptSwatSwapReply? (203b) jmp SwapReply ; yes jmp .il1 ; unknown type. reject .cursorBitMap: 431 lenCursor: 16. lenEtherState: 9. typePup: 1000 ; I'm a Pup in an Ether packet socTeleSwat: 60 ; well known server socket c377: 377 ptSwatStore: 200 lenDally: 5*27. ; ~5 seconds in units of RTC ticks (38 ms) c5: 5 dally: 0 .rtc: 430 ; -> real time clock .OutLd: sta 3 OutLdRet mkzero 0 0 sta 0 @.dumperFlg ; page 0 is OK jmp 1 3 OutLdRet: .blk 1 .dumperFlg: 706 SwapReply: lda 0 dally snz 0 0 ; are we dallying? jmp sa1 ; no. hmmm. lda 0 .cursorBitMap jsrii .+1 ; restore user cursor userCursor mov 3 1 lda 2 lenCursor jsrii .+1 MoveBlock lda 0 .ePLoc1 ; restore Ethernet state jsrii .+1 etherState mov 3 1 lda 2 lenEtherState jsrii .+1 MoveBlock mkzero 1 1 ; no longer dallying sta 1 dally lda 3 OutLdRet jmp 1 3 ; resume user program Store: lda 0 value,3 sta 0 @address,3 jmp SendBlk Fetch: lda 0 @address,3 sta 0 value,3 ; fall through into SendBlk ; see if user is requesting a block. SendBlk:lda 0 length,3 lda 1 lenAckPup sgeu 0 1 ; long enough to request a block? jmp sb1 ; no lda 2 lenBlock,3 snz 2 2 ; is he requesting one? jmp sb1 ; no lda 1 .maxBlkLen sgeu 1 2 mov 1 2 ; Max(requested length, our limit) sta 2 lenBlock,3 ; # words we are sending neg 2 0 lda 1 address,3 and 0 1 ; source base address = address & -length lda 0 .block add 3 0 ; destination = PBI.block jsrii .+1 ; move the block into the packet MoveBlock jsrii .+1 pbi sb1: mkzero 0 0 jmp SendAck .maxBlkLen: maxBlkLen .block: block Swap: mkzero 0 0 sta 0 lenBlock,3 lda 0 lenDally lda 1 @.rtc add 1 0 ; fall through into SendAck SendAck:sta 0 dally lda 1 lenCursor ; Invert the cursor neg 1 1 lda 2 .cursorBitMap sa2: lda 0 0 2 com 0 0 sta 0 0 2 inc 2 2 inc 1 1 szr jmp sa2 lda 0 eDestSrc,3 ; exchange Ethernet addresses movs 0 0 sta 0 eDestSrc,3 lda 2 lenBlock,3 movzl 2 2 ; convert to bytes lda 1 lenAckPup add 1 2 sta 2 length,3 ; Pup.length mkminusone 0 0 addor 0 2 ; (Pup.length-1)/2 = checksum offset add 3 2 ; Pup base address sta 0 2,2 ; 2 accounts for the encapsulation lda 0 ptSwatAck sta 0 type,3 ; Pup.type lda 0 sPort,3 ; exchange Pup ports lda 1 dPort,3 sta 0 dPort,3 sta 1 sPort,3 lda 0 sPort+1,3 lda 1 dPort+1,3 sta 0 dPort+1,3 sta 1 sPort+1,3 lda 0 sPort+2,3 lda 1 dPort+2,3 sta 0 dPort+2,3 sta 1 sPort+2,3 lda 0 c3777 ; delay about 4 ms to ensure that neg 0 0 ; our ack is heard inc 0 0 szr jmp .-1 sta 0 @.ePLoc1 ; status sta 0 @.eLLoc ; zero load sta 0 @.eICLoc1 ; no input under output sta 3 @.eOPLoc lda 3 length,3 lda 0 c5 addzr 3 0 ; physical length = (Pup.length+5)/2 sta 0 @.eOCLoc mkone 0 0 ; etherOutput command sio ; start transmitter lda 0 @.ePLoc1 snz 0 0 ; done? jmp .-2 ; no sa1: jsrii .+1 il1 c3777: 3777 lenAckPup: 28. ; pupOvBytes + 6 ptSwatAck: 204 .ePLoc1: 600 .eLLoc: 603 .eICLoc1: 604 .eOCLoc: 606 .eOPLoc: 607 .MoveBlock: ; AC0 = dest, AC1 = src, AC2 = length sta 3 mbRet mkone 3 3 sub 3 1 sub 0 3 mov 1 0 neg 3 1 mov 2 3 add 3 1 neg 3 3 blt lda 3 mbRet jmp 1 3 mbRet: .blk 1 .pbi: jsr 1,3 .blk lenPBI 125252 125252 125252 125252 .etherState: jsr 1,3 .blk 9. .userCursor: jsr 1,3 .blk 16. .swatCursor: jsr 1,3 0 73507 22104 23106 ; Tele 22104 23567 0 0 65227 105252 45252 ; Swat 25272 142452 0 0 0 .end