; DMTEther.asm ; Copyright Xerox Corporation 1979, 1980, 1983 ; Last modified July 1, 1983 2:55 PM by Boggs ; OUTGOING .ENT INITETHER, STOPETHER, STARTETHER .ENT INITETHEROUT, STARTETHEROUT, PACKCHAR ; INCOMING .BEXT INITINT .BEXTZ CHANGEBANK .BEXT mayDayPacket, bootLoaderPacket .SREL INITETHER: .INITETHER STOPETHER: .STOPETHER STARTETHER: .STARTETHER INITETHEROUT: .INITETHEROUT STARTETHEROUT: .STARTETHEROUT PACKCHAR: .PACKCHAR ETHERINT: .ETHERINT .ZREL ETHERCHAN: 0 ; INTERRUPT CHANNEL BIT EPLOC: 600 ; ENDING STATUS EBLOC: 601 ; INTERRUPT BIT MASK EELOC: 602 ; ENDING LENGTH ELLOC: 603 ; LOAD EICLOC: 604 ; INPUT BUFFER LENGTH EIPLOC: 605 ; -> INPUT BUFFER EOCLOC: 606 ; OUTPUT BUFFER LENGTH EOPLOC: 607 ; -> OUTPUT BUFFER EHLOC: 610 ; HOST ADDRESS pEIBUF: EIBUF ; -> INPUT BUFFER pEOBUF: EOBUF ; -> OUTPUT BUFFER .NREL OBL = 300. ; OUTPUT BUFFER LENGTH IBL = 300. ; INPUT BUFFER LENGTH EOBUF: .BLK OBL EIBUF: .BLK IBL ;Ethernet encapsulation: ether.ds = 0 ether.type = 1 ;Peek format: peek.type = 2 peek.string = 3 ;Pup format: pup.length = 2 pup.type = 3 pup.id = 4 pup.dPort = 6 pup.sPort = 11 pup.words = 14 ;----------------------------------------------------------------------------- .INITETHER: ;----------------------------------------------------------------------------- STA 3 IEIRET LDA 0 @ppETHERINT ; SET INTERRUPT HANDLER JSRII ppINITINT STA 0 ETHERCHAN MKZERO 0 0 ; SET HOST ADDRESS SIO LDA 1 C377 AND 1 0 STA 0 @EHLOC JSR .STARTETHER ; START THE RECEIVER JMP @IEIRET IEIRET: 0 ppINITINT: INITINT ppETHERINT: ETHERINT ;----------------------------------------------------------------------------- .STARTETHER: ;----------------------------------------------------------------------------- LDA 0 ETHERCHAN JMP SEBLOC ;----------------------------------------------------------------------------- .STOPETHER: ;----------------------------------------------------------------------------- MKZERO 0 0 SEBLOC: STA 0 @EBLOC LDA 0 ETHERRESET SIO JMP 0 3 ;----------------------------------------------------------------------------- .ETHERINT: ; ETHERNET INTERRUPT ;----------------------------------------------------------------------------- STA 0 SAC0 ; SAVE STATE STA 1 SAC1 STA 2 SAC2 STA 3 SAC3 MOVL 0 0 STA 0 SCRY LDA 0 @EPLOC ; GET STATUS LDA 1 C377 SE 0 1 ; RECEIVER DONE STATUS? JMP STARTETHERIN ; NO. RESTART RECEIVER ; FILTER THE NEWLY ARRIVED PACKET LDA 2 pEIBUF ; INPUT BUFFER POINTER LDA 0 ether.ds,2 ; DEST,,SRC LDA 1 C177400 ANDS 1 0 LDA 1 @EHLOC ; OUR HOST ADDRESS SE 1 0 ; TO US (No BroadCasts Allowed!!!)? JMP STARTETHERIN ; NO LDA 0 etPup LDA 1 ether.type,2 ; TYPE WORD IN PACKET SE 0 1 ; IS IT A PUP? JMP STARTETHERIN ; NO LDA 0 @EICLOC LDA 1 @EELOC SUB 1 0 ; LENGTH REPORTED BY INTERFACE LDA 1 pup.length,2 LDA 3 C5 ADDZR 3 1 ; LENGTH CLAIMED IN PUP HEADER SE 1 0 ; DO THEY AGREE? JMP STARTETHERIN ; NO LDA 0 C377 LDA 1 pup.type,2 AND 1 0 ; Pup Type in AC0 LDA 1 pup.dPort+2,2 ; IS SOCKET MISC SERVICES? LDA 3 socMiscServ SE 1 3 JMP NOTMISCSERV ; NO LDA 1 pup.dPort+1,2 SZ 1 1 JMP NOTMISCSERV ; NO LDA 1 ptIDLEREQUEST SNE 0 1 ; IDLE REQUEST? JMP IDLEREPLY LDA 1 ptKOD SE 0 1 ; KOD? JMP NOTMISCSERV ; NO LDA 0 C170000 ; HOP COUNT FIELD MASK LDA 1 pup.type,2 AND# 1 0 SNR ; HOP COUNT MUST BE ZERO JMP NETBOOT ; I.E. SRC MUST BE ON THIS NET NOTMISCSERV: LDA 1 ptRFC SNE 0 1 ; RFC? JMP DISKBOOT ; YES ; LDA 1 ptEFTP ; SE 0 1 ; EFTP? ; JMP STARTETHERIN ; NO ; LDA 0 pup.id+1,2 ; SNZ 0 0 ; SEQUENCE NUMBER 0? ; JMP DISKBOOT ; YES STARTETHERIN: LDA 0 pEIBUF ; BUFFER POINTER STA 0 @EIPLOC LDA 0 BUFFLEN ; BUFFER LENGTH STA 0 @EICLOC MKZERO 0 0 STA 0 @EPLOC LDA 0 ETHERCHAN STA 0 @EBLOC LDA 0 ETHERINPUT SIO LDA 0 SCRY MOVR 0 0 LDA 0 SAC0 ; RESTORE STATE LDA 1 SAC1 LDA 2 SAC2 LDA 3 SAC3 BRI ; DISMISS INTERRUPT SAC0: 0 SAC1: 0 SAC2: 0 SAC3: 0 SCRY: 0 socMiscServ: 4 ptKOD: 247 ; KISS-OF-DEATH ptRFC: 10 ; REQUEST-FOR-CONNECTION ptEFTP: 30 ; EFTP-DATA ptIDLEREQUEST: 262 ; IDLE-REQUEST ptIDLEREPLY: 263 ; IDLE-REPLY etPup: 1000 ; I'm a Pup in an Ether packet BUFFLEN: IBL C5: 5 C6: 6 C3: ETHERRESET: 3 ; ETHER RESET COMMAND ETHERINPUT: 2 ; ETHER INPUT COMMAND C177400: 177400 C170000: 170000 C377: 377 IDLEREPLY:LDA 0 C3000 ; REPLY TO REQUESTING HOST NEG 0 0 INC 0 0 SZR ; DELAY FOR A FEW MS. JMP .-1 LDA 0 ptIDLEREPLY STA 0 pup.type,2 ; CHANGE TYPE TO IDLE-REPLY LDA 0 LENREPLY STA 0 pup.length,2 ; FILL IN PUP LENGTH LDA 0 IDLEVERSION STA 0 pup.words,2 ; IDLE REPLY VERSION NUMBER VERS STA 0 pup.words+1,2 ; ALTO UCODE INFORMATION MKMINUSONE 0 0 STA 0 pup.words+2,2 ; TURN OFF CHECKSUM LDA 0 pup.dPort,2 ; SWAP PORTS LDA 1 pup.sPort,2 STA 1 pup.dPort,2 STA 0 pup.sPort,2 LDA 0 pup.dPort+1,2 LDA 1 pup.sPort+1,2 STA 1 pup.dPort+1,2 STA 0 pup.sPort+1,2 LDA 0 pup.dPort+2,2 LDA 1 pup.sPort+2,2 STA 1 pup.dPort+2,2 STA 0 pup.sPort+2,2 LDA 0 ether.ds,2 ; SWAP DEST-SOURCE BYTES MOVS 0 0 STA 0 ether.ds,2 LDA 0 pup.length,2 ; COMPUTE PACKET LENGTH LDA 1 C5 ADDZR 1 0 ; PACKETLEN = (PUPLEN + 5)/2 JSR SENDPACKET ; LENGTH IN AC0, PACKET POINTER IN AC2 JMP STARTETHERIN LENREPLY: 32 IDLEVERSION: 1 C3000: 3000 NETBOOT:MKZERO 0 0 ; BOOT FROM NET JSR @CHANGEBANK ; FLIP BACK INTO BANK 0 LDA 2 pEIBUF LDA 0 pup.id+1,2 LDA 3 @lvMayDayPacket STA 0 pup.id+1,3 ; BOOT FILE NUMBER LDA 0 pup.sPort,2 STA 0 pup.dPort,3 LDA 0 pup.sPort+1,2 STA 0 pup.dPort+1,3 LDA 0 pup.sPort+2,2 STA 0 pup.dPort+2,3 ; COPY KOD sPort INTO MAYDAY dPort LDA 0 @lvBootLoaderPacket INC 0 0 LDA 1 K400 LDA 3 LBLT BLT ; MOVE LOADER INTO PAGE 0 JMP 6 ; JUMP INTO BOOT LOADER lvMayDayPacket: mayDayPacket lvBootLoaderPacket: bootLoaderPacket LBLT: -401+3 K400: 400 DISKBOOT:LDA 0 @KSTAT ; DISK STATUS LDA 1 DISKREADY AND 1 0 SZR ; BIT 10 ZERO MEANS DISK READY JMP STARTETHERIN STA 0 @DSTART ; TURN OFF DISPLAY INC 0 0 SZR ; WAIT FOR IT TO STOP JMP .-1 JSR @CHANGEBANK ; BUILD A DISK COMMAND TO READ DISK ADDRESS 0 INTO CORE PAGE 0 ; STORE THE LABEL BLOCK IN LOC 402-411. HEADER IS ALSO READ INTO ; 402 - JUST TO PUT IT SOMEWHERE - IT IS OVERWRITTEN BY THE LABEL JSR DB3 ; GET POINTER TO KCB: 0 ; LINK 0 ; STATUS 44000 ; READ HEADER, LABEL, DATA 412 ; HEADER BLOCK ADDRESS 402 ; LABEL BLOCK ADDRESS 1 ; DATA BLOCK ADDRESS 0 ; NO ERROR INTERRUPT WORD 0 ; ERROR INTERRUPT WORD 0 ; NOT USED 0 ; DISK ADDRESS ; *** From here on, can't assume page zero is valid *** DB3: LDA 2 pEIBUF ; pEIBUF IS ZREL - CLOBBERED BY THE READ MKMINUSONE 0 0 STA 0 @KADDR ; FORCE A SEEK STA 3 @KBLK ; START THE DISK ; WAIT FOR THE DISK COMMAND TO FINISH WAITDISK:LDA 0 1 3 ; NON-ZERO STATUS MEANS DONE SNZ 0 0 ; DONE? JMP WAITDISK ; NO LDA 1 STATUSMASK AND 0 1 SNR JMP EVENT MKZERO 0 0 STA 0 1 3 STA 3 @KBLK JMP WAITDISK STATUSMASK: 267 ; BUILD AN EVENT MESSAGE AND LEAVE IT FOR THE BOOTEE. ; THE EVENT VECTOR CONTAINS: ; CONNECTION ID (2 WORDS) ; DESTINATION PORT (3 WORDS) ; SOURCE PORT (3 WORDS) ; CONNECTION PORT (RFC ONLY) (3 WORDS) EVENT: LDA 3 2 ; POINTER TO EVENT AREA MKONE 0 0 STA 0 0,3 ; HEY, OS: THERE'S AN EVENT HERE LDA 0 pup.type,2 LDA 1 C377 AND 1 0 LDA 1 ptRFC SE 0 1 JMP DB1 LDA 0 EVENTRFC ; IT'S AN RFC EVENT STA 0 1,3 ; CNT ALREADY CONTAINS 11D DB2: LDA 0 4,2 ; GET A WORD FROM THE PACKET STA 0 2,3 ; PUT IT IN THE EVENT VECTOR INC 3 3 INC 2 2 DSZ CNT JMP DB2 MKZERO 0 0 STA 0 2,3 ; END OF EVENT VECTOR JMP 3 ; JUMP INTO THE BOOT LOADER DB1: LDA 0 EVENTEFTP ; IT'S AN EFTP EVENT STA 0 1,3 LDA 0 D8 ; IT'S 8D WORDS LONG STA 0 CNT JMP DB2 EVENTRFC: 4B11+13+1 ; TYPE RFC, LENGTH 13 EVENTEFTP: 7B11+10+1 ; TYPE EFTPDATA, LENGTH 10 KADDR: 523 ; -> DISK ADDR OF LAST COMMAND KSTAT: 522 ; -> SECTOR STATUS KBLK: 521 ; -> DISK COMMAND LIST DSTART: 420 ; -> DISPLAY COMMAND LIST DISKREADY: 40 ; DISK READY BIT IN STATUS WORD C4: 4 D8: 8. ; SIZE OF AN EFTP EVENT CNT: 11. ; SIZE OF AN RFC EVENT ;----------------------------------------------------------------------------- .STARTETHEROUT: ; START ETHER OUTPUT ;----------------------------------------------------------------------------- STA 3 SEORET JSRII ppSTOPETHER LDA 2 pEOBUF ; OUTPUT BUFFER LDA 0 peek.string,2 LDA 1 RIGHTMASK ; AKA C377 MOVS 0 0 ; STRING BYTE COUNT ANDZR 1 0 ; WORDCOUNT +0,-1 LDA 1 C4 ; 3 FOR HEADER, 1 FOR POSSIBLE LEFT OVER BYTE ADD 1 0 ; PACKET LENGTH IN WORDS JSR SENDPACKET JSRII ppSTARTETHER JSR .INITETHEROUT JMP @SEORET ppSTOPETHER: STOPETHER ppSTARTETHER: STARTETHER SEORET: 0 ;----------------------------------------------------------------------------- SENDPACKET: ; OUTPUT A PACKET ; ASSUMES PACKET LENGTH IN AC0, PACKET POINTER IN AC2, RETURN IN AC3 ;----------------------------------------------------------------------------- STA 0 @EOCLOC STA 2 @EOPLOC MKZERO 0 0 STA 0 @EPLOC STA 0 @ELLOC STA 0 @EICLOC STA 0 @EIPLOC LDA 0 POSTTIME ; SET UP WAIT COUNTER STA 0 POSTCNT LDA 0 ETHEROUTPUT SIO ; START TRANSMITTER WAIT: LDA 0 @EPLOC ; NON ZERO MEANS DONE MOV 0 0 SZR JMP DONE ; DONE DSZ POSTCNT ; NOT DONE...WAIT JMP WAIT DONE: JMP 0 3 ; RETURN POSTTIME: 5000. ; ABOUT 50 MS. POSTCNT: 0 ETHEROUTPUT: 1 ;----------------------------------------------------------------------------- .INITETHEROUT: ;----------------------------------------------------------------------------- LDA 2 pEOBUF ; OUTPUT BUFFER LDA 0 PEEKER ; PEEKER,,0 LDA 1 @EHLOC ; 0,,US ADD 1 0 STA 0 ether.ds,2 ; PEEKER,,US LDA 0 TYPE ; PACKET TYPE STA 0 ether.type,2 MKONE 0 0 STA 0 peek.type,2 MKZERO 0 0 STA 0 peek.string,2 ; STRING LENGTH = 0 JMP 0 3 PEEKER: 376B7 ; PEEK ADDRESS,,0 TYPE: 402 ; PEEK PACKET TYPE ;----------------------------------------------------------------------------- .PACKCHAR: ; PACK 7 BIT CHARACTER IN AC1 INTO OUTPUT BUFFER ;----------------------------------------------------------------------------- STA 3 PCRET ; RETURN LDA 2 pEOBUF ; OUTPUT BUFFER LDA 0 STRINGOFF ADD 0 2 LDA 0 0 2 ; ->BCPL STRING LDA 3 C400 ADD 3 0 ; INCREMENT BYTE COUNT STA 0 0 2 MOVS 0 0 LDA 3 RIGHTMASK ANDZR 3 0 ; AC0=WRD OFFS, CRY='PUT IN RIGHT BYTE' ADD 0 2 ; CAN'T CARRY LDA 0 0 2 ; TARGET WORD LDA 3 LEFTMASK MOV# 0 0 SNC ; LEFT OR RIGHT? MOVS 0 0 ; LEFT AND 3 0 ADD 1 0 SNC ; ADD CAN'T CARRY MOVS 0 0 STA 0 0 2 JMP @PCRET STRINGOFF: peek.string C400: 400 PCRET: 0 RIGHTMASK: 377 LEFTMASK: 177400 .END