; File: CC.PROM.OD.TEXT ; Date: 18-Jan-84 ; OMNINET disk driver data area equates ; DCmd EQU 0 ;byte - disk command offset DCdrv EQU 1+DCmd ;byte - offset for drive number DCblklo EQU 2+DCmd ;byte - LSB of block number to read or write DCblkhi EQU 3+DCmd ;byte - MSB " " DClen EQU 4+DCmd ;word - length of request (in bytes) ; result vector and header used for all setuprecv commands ; RHdr EQU 6 ; RHpktRC EQU 0+RHdr ;byte - return code from transporter RHsor EQU 1+RHdr ;byte - the source of the message RHpktLN EQU 2+RHdr ;word - total length of data portion of packet RHdskLN EQU 4+RHdr ;word - length of info returned from drive RHdskRC EQU 6+RHdr ;byte - return code from drive ; ; result vector and header for all sendmsg commands ; SHdr EQU 14 ; SHpktRC EQU 0+SHdr ;byte - return code from transporter ; EQU 1+SHdr ;byte - unused ; EQU 2+SHdr ;word - unused SHtoLN EQU 4+SHdr ;word - number of bytes to send to drive SHfmLN EQU 6+SHdr ;word - number of bytes expected from drive ; GData EQU 22 ;word - area to receive "GO" into ; area used for constructing Transporter commands ; TCmd EQU 24 ; TCop EQU 0+TCmd ;byte - op code TCrADhi EQU 1+TCmd ;byte - result address HI TCrADlo EQU 2+TCmd ;word - result address MED, LO TCsock EQU 4+TCmd ;byte - socket number TC6801Ad EQU 4+TCmd ;word - 6801 addr for peek/poke 0.8 TCdADhi EQU 5+TCmd ;byte - data buffer address HI TCdADlo EQU 6+TCmd ;word - data buffer address MED, LO TCpekpok EQU 6+TCmd ;byte - peek/poke function code 0.8 TCdtaLN EQU 8+TCmd ;word - data length TChdrLN EQU 10+TCmd ;byte - header length TCdest EQU 11+TCmd ;byte - destination host number ; ODdw EQU 36 ;lint - temporary buffer (for 3 byte nmbrs) ODdwhi EQU 37 ;byte - temporary HI ODdwlo EQU 38 ;word - temporary MID, LO ODwrAD EQU 40 ;lint - to save buffer address for CWrites ODvalid EQU 44 ;word - for marking buffer as valid EHpktRC EQU 46 ;byte - End Recv result code page ; Transporter Return Codes ; Waiting EQU $FF ; CmdAcpt EQU $FE ; Echoed EQU $C0 ;echo command was successful ; GaveUp EQU $80 ;aborted a send command after MaxRetries tries TooLong EQU $81 ;last message sent was too long for the receiver NoSockt EQU $82 ;sent to an unititialized socket HdrErr EQU $83 ;sender's header length did not match receiver's BadSock EQU $84 ;illegal socket number Inuse EQU $85 ;tried to set up a receive on an active socket BadDest EQU $86 ;sent to an illegal host number NoTrans EQU -112 ;could not strobe cmd addr to Transporter TimeOut EQU -111 ;timed out waiting for an Omninet event NoBufr EQU -110 ;tried a CRRead without a valid write buffer ; ; Transporter Opcodes ; RecvOp EQU $F0 ;SETUPRECV opcode SendOp EQU $40 ;SENDMSG opcode InitOp EQU $20 ;INIT opcode EndOp EQU $10 ;ENDRECV opcode DebOp EQU $08 ;PEEK/POKE opcode EchoOp EQU $02 ;ECHOCMD opcode WhoOp EQU $01 ;WHOAMI opcode ; Socket numbers ; RestSkt EQU $A0 ;dest. socket for REST packet CnstSkt EQU $B0 ;socket for disk server protocol CIIpSkt EQU $80 ;socket for Const II protocol 0.8 ; Const II protocol ; C2pid EQU $01FE ;Const II protocol id 0.8 C2whomg EQU $0200 ;msgtype= who msg 0.8 C2idmsg EQU $1000 ;msgtype= identification 0.8 C2dsksrv EQU $0001 ;devtype= disk server 0.8 C2omndsk EQU $0006 ;devtype= omnidisk 1.0 ; Const II protocol message form 0.8 ; 0.8 C2Ppid EQU 0 ;word - protocol id 0.8 C2Pmsgtp EQU C2Ppid+2 ;word - message type 0.8 C2Psrc EQU C2Pmsgtp+2 ;word - source host number 0.8 C2Pdevtp EQU C2Psrc+2 ;word - device type 0.8 C2PwhoLn EQU C2Pdevtp+2 ;length of "who" msg 0.8 C2Pname EQU C2Pdevtp+2 ;chars - name 10 bytes 0.8 C2PmaxLn EQU C2Pname+10 ;length of other msgs 0.8 TOintvl EQU $2FFFF ;timeout interval 0.8 page ; ; Oboot -- OMNINET disk server boot processing ; Oboot tst.b CPbtsrvr.w ;is server number valid? 0.7 bge.s Oboot10 ;yes, go on 0.7 bsr ODbroad ;send broadcast message to disk srvr 0.7 ;* in order to get disk server 0.7 ;* Transporter number 0.7 move.b d7,CPbtsrvr.w ;save boot server number 0.7 Oboot10 move.b #5,CPbtslot.w ;set boot slot number lea ODblkIO,a6 ;set boot disk blk i/o subr pointer move.l a6,CPblkio.w ;* lea ODdskIO,a6 ;set boot disk i/o subr pointer move.l a6,CPdskio.w ;* bra Lboot80 ;load boot code ; (Lboot80 is in CC.PROM.LD) ; ; ODcomnd -- send simple command to Transporter ; ; Enter: D0.B - Transporter command ; D1.B - Destination host number (if ECHO) 0.7 ; D1.B - Socket number (if ENDRECV) 0.7 ; D1.B - MSB 6801 address (if PEEK/POKE) 0.8 ; ; Exit: D7.B - IORESULT (OMNINET status) ; ODcomnd movem.l a1-a3/d0,-(sp) ;save registers 0.8 move.l #CPomnibf,a1 ;get pointer to Data Area lea RHpktRc(A1), A3 ;assume not end recv 0.8 cmpi.b #EndOp, D0 ;if is a end recv use different 0.8 bne.s ODcmdgo ; result code location than 0.8 lea EHpktRC(A1), A3 ; the recv 0.8 ODcmdgo move.l A3,TCop(a1) ;(A3) = result record pointer 0.8 move.b d0,TCop(a1) ;set Transporter command move.b d1,TCsock(a1) ;set dest host number (ECHO) 0.7 ;set socket number (ENDRECV) 0.7 move.b #Waiting,(A3) ;set Transporter waiting flag 0.8 lea TCmd(A1),A2 ;get command address bsr StrobIt ;strobe command address to Transporter bne.s ODcmd9 ;Transporter not responding move.l #TOintvl,D0 ;get timeout interval 0.8 ODcmd1 move.b (A3),d7 ;get Transporter return code 0.8 cmpi.b #Waiting, d7 ;has Transporter responded? 0.8 bne.s ODcmd9 ;yes, ready to return 0.8 subq.l #1, D0 ;see if waited long enough 0.8 bpl.s ODcmd1 ;no, look again 0.8 moveq #TimeOut, d7 ;yes, set timeout error & return0.8 ODcmd9 movem.l (sp)+,a1-a3/d0 ;restore registers 0.8 move.b d7,CPomniRC.w ;save OMNINET return code 0.7 rts ;return page ; ; ODblkIO - Read or write an OMNINET disk server block subroutine ; ; Enter: A0.L - Buffer address ; D0.L - Block number 0.7 ; D1.W - Drive number ; D5.W - Read ($32) or Write ($33) command ; D6.W - Destination host number * 256 ; ; Exit: A0.L - Next free location in buffer ; D0.L - Updated block number 0.7 ; D7.W - IORESULT (OMNINET/disk controller status) ; ; All other registers are preserved. ; ODblkIO movem.l d0-d2/a1-a2,-(sp);Save registers move.l #CPomnibf,a1 ;A1 points to the start of the Data Area clr.w ODvalid(A1) ;buffer valid = False... see ODdskIO move.b D5,DCmd(A1) ;Stuff disk command - read or write move.l d0,d2 ;Compute drive nmbr/MSN block nmbr 0.7 swap d2 ;* 0.7 lsl.w #4,d2 ;* 0.7 or.b d1,d2 ;* 0.7 move.b D2,DCDrv(A1) ;stuff drive number 0.7 move.b D0,DCBlkLo(A1) ;lo order byte of block number lsr.w #8,D0 ; move.b D0,DCBlkHi(A1) ;hi order byte of block number move.w #512,DCLen(A1) ;set length to 512... cmpi.w #DskWrit,D5 ;Are we reading or writing? bne.s ODblk2 ;Reading ; ODblk1 move.w #516,SHtoLN(A1) ;number of bytes to send to drive clr.w SHfmLN(A1) ;number of bytes expected back move.l A0,ODwrAD(A1) ;save address of REST of data bsr LongCmds ;Writing bra.s ODblk3 ;return ; ODblk2 move.w #4,SHtoLN(A1) ;number of bytes to send to drive move.w #512,SHfmLN(A1) ;number of bytes expected back bsr ShortCmds ; ; ODblk3 movem.l (sp)+,d0-d2/a1-a2;Restore registers adda.w #512,a0 ;Update buffer pointer addq.l #1,d0 ;Update disk block number 0.8 move.b d7,CPdiskRC.w ;Save current disk return code 0.7 ext.w d7 ;Set return condition code rts ;Return page ; 0.7 ; ODbroad - Send broadcast message to disk server 0.7 ; 0.7 ; Exit: D7.W - disk server number 0.7 ; 0.7 ; All other registers are preserved. 0.7 ; 0.7 ODbroad movem.l d2-d6/a0,-(sp) ;save registers 0.7 move.l #NTO1,CPtimout.w;set timeout for broadcast 0.7 bsr.s ODC2broad ;do const II broadcast 0.8 bpl.s ODbrd90 ;found disk server 0.8 move.l #USRbase,a0 ;send broadcast message to disk srvr 0.7 move.b #$FF,(a0) ;* in order to get disk server 0.7 moveq #1,d2 ;* Transporter number 0.7 moveq #$33,d5 ;* 0.7 moveq #-1,d6 ;* 0.7 bsr ODdskIO ;* 0.7 moveq #$32,d5 ;* 0.7 bsr ODdskIO ;* 0.7 ODbrd90 move.l #NTO2,CPtimout.w;set timeout for normal network traffic 0.7 movem.l (sp)+,d2-d6/a0 ;restore registers 0.7 rts ;return 0.7 ; ; ODpeek - do peek at $F800 to find version number 0.8 ; 0.8 ; Exit: D7.B - peek data or error code 0.8 ; 0.8 ODpeek LEA CPomnibf.L, A1 ;omninet data area 0.8 MOVE.W #$F800, TC6801Ad(A1) ;put in 6801 addr to peek 0.8 CLR.B TCpekpok(A1) ;do peek 0.8 MOVEQ #DebOp, D0 ;peek/poke op code 0.8 MOVE.W #$F8, D1 ;ODcomnd puts D1 over TC6801Ad 0.8 BSR ODcomnd ;do peek 0.8 MOVE.B RHpktRC(A1), D7 ;get version number 0.8 RTS ; 0.8 page ; ; ODC2broad - broadcast the Const II who are you to find disk server 0.8 ; receive ident msg from disk server. 0.8 ; 0.8 ; Exit: MI - no response or error 0.8 ; PL - found disk server 0.8 ; D7.W - disk server number or error code 0.8 ; 0.8 ODC2broad ; 0.8 MOVEQ #1, D2 ;try 2 times max. 0.8 LEA CPomnibf.L, A1 ;omninet data area 0.8 ODC2b10 BSR.S Set80Rcv ;setup recv on socket $80 0.8 BNE.S ODC2Err ;error, do end recv 0.8 BSR SendWhoDS ;send who msg 0.8 BMI.S ODC2Err ;error, do end recv 0.8 MOVE.L CPtimout.W, D0 ;wait for response 0.8 ODC2wait MOVE.B RHpktRC(A1), D7 ;got it? 0.8 BEQ.S ODC2chk ;yes, check it out 0.8 SUBQ.L #1, D0 ;no, dec retry count 0.8 BNE.S ODC2wait ;if not zero test again 0.8 ODC2Err MOVEQ #EndOp, D0 ;ERROR - do endrecv 0.8 MOVE.W #CIIpSkt, D1 ; on socket $80 0.8 MOVE.W D7, -(SP) ;save error code or server host #0.8 BSR ODcomnd ;do end recv 0.8 MOVE.W (SP)+, D7 ;restore error code 0.8 DBRA D2, ODC2b10 ;do again if another retry 0.8 ODC2b90 EXT.W D7 ;set cc 0.8 RTS ;EXIT 0.8 ODC2chk BSR.S Set80Rcv ;setup recv again just in case 0.8 BNE.S ODC2Err ;error, restart 0.8 LEA USRbase.L, A0 ;verify msg is correct type 0.8 CMPI.W #C2pid, (A0) ;Const II pid? 0.8 BNE.S ODC2wait ;no, wait for correct msg 0.8 CMPI.W #C2idmsg, C2Pmsgtp(A0) ;Ident msg type? 0.8 BNE.S ODC2wait ;no, wait for correct msg 0.8 CMPI.W #C2dsksrv, C2Pdevtp(A0) ;from a disk server? 0.8 BEQ.S ODC2bDS ;yes, got old disk server 1.0 CMPI.W #C2omndsk, C2Pdevtp(A0) ;from a omnidisk? 1.0 BNE.S ODC2wait ;no, wait for correct msg 1.0 ODC2bDS MOVE.W C2Psrc(A0), D7 ;get disk server host number 0.8 LEA C2Pname(A0), A0 ;move disk server name 0.8 LEA CPsrvnam.W, A1 ; into static memory 0.8 MOVEQ #C2PmaxLn-C2Pname-1, D0 ;10 bytes 0.8 ODC2move MOVE.B (A0)+, (A1)+ ; 0.8 DBRA D0, ODC2move ; 0.8 CLR.L D2 ;clear retry counter to show done0.8 BRA.S ODC2Err ;do end recv and exit 0.8 page ; ; Set80Rcv - setup a recv on socket 80 for Const II ident msg. 0.8 ; 0.8 ; Enter: A1 - omninet data area address 0.8 ; Exit: NE - error 0.8 ; EQ - setup worked 0.8 ; D7.W - error code 0.8 ; 0.8 Set80Rcv LEA USRbase.L, A0 ;address to receive ident msg 0.8 MOVE.L A0, TCdADhi-1(A1) ;put in transporter cmd block 0.8 MOVE.W #C2PmaxLn, TCdtaLN(A1) ;ident msg is 18 bytes 0.8 CLR.B TChdrLN(A1) ;socket $80 has no header area 0.8 MOVE.W #RecvOp, D0 ;setup recv 0.8 MOVE.W #CIIpSkt, D1 ; on socket $80 0.8 BSR ODcomnd ;do setup 0.8 CMPI.B #CmdAcpt, D7 ;was socket setup? 0.8 BNE.S S80Rexit ;no, report error 0.8 CLR.L D7 ;yes, show no error 0.8 S80Rexit RTS ; 0.8 page ; ; SendWhoDS - send Const II who are you msg to find disk server. 0.8 ; 0.8 ; Enter: A1 - omninet data area address 0.8 ; Exit: MI - error 0.8 ; PL - send worked 0.8 ; D7.B - error code 0.8 ; 0.8 SendWhoDS ; 0.8 LEA USRbase+$20.L, A0 ;address to put who msg 0.8 MOVE.L WhoMsg, (A0) ;move who msg from ROM 0.8 MOVE.L WhoMsg+4, 4(A0) ; to dynamic RAM 0.8 MOVE.B CPtprnbr.W, C2Psrc+1(A0) ;put in station's host # 0.8 MOVE.L A0, TCdADhi-1(A1) ;put in adr of msg as data 0.8 PEA SHdr(A1) ;result vector adr 0.8 MOVE.L (SP)+, TCrADhi-1(A1) ; put in cmd block 0.8 MOVE.B #SendOp, TCop(A1) ;send msg 0.8 MOVE.B #CIIpSkt, TCsock(A1); on socket $80 0.8 MOVE.W #C2PwhoLn, TCdtaLN(A1) ;msg length = 8 bytes 0.8 CLR.B TChdrLN(A1) ;socket $80 has no header area 0.8 MOVEQ #-1, D0 ; 0.8 MOVE.B D0, TCdest(A1) ;$FF means broadcast 0.8 MOVE.B D0, SHpktRC(A1) ;$FF means waiting for trnsprtr 0.8 LEA TCmd(A1), A2 ;stobe in cmd 0.8 BSR Strobit ; block 0.8 BNE.S SWDSexit ;timed out waiting for Ready 0.8 MOVE.L #TOintvl, D0 ;get timeout interval 0.8 SWDSwait MOVE.B SHpktRC(A1), D7 ;get result code 0.8 CMPI.B #Waiting, D7 ;has Transporter responded? 0.8 BNE.S SWDSdone ;yes, ready to return 0.8 SUBQ.L #1, D0 ;see if waited long enough 0.8 BPL.S SWDSwait ;no, look again 0.8 MOVEQ #TimeOut, D7 ;yes, set timeout error 0.8 SWDSdone MOVE.B D7, CPomniRC.w ;save OMNINET return code 0.8 SWDSexit RTS ;return 0.8 WhoMsg DATA.W C2pid ;Const II protocol id 0.8 DATA.W C2whomg ;who msg type code 0.8 DATA.W 0 ;source host number 0.8 DATA.W C2dsksrv ;disk server host type 0.8 page ; ; ODdskIO - Read from/write to Corvus disk ; ; Enter: A0.L - Buffer address ; D2.W - Count ; D5.W - Read ($32) or Write ($33) command ; D6.W - Destination host number * 256 ; ; Exit: D7.W - IORESULT (OMNINET/disk controller status) ; ; All other registers are preserved. ; ODdskIO movem.l d0-d2/a0-a2,-(sp);Save registers move.l #CPomnibf,a1 ;A1 points to the start of the Data Area moveq #-1, d0 ;get word of $FFFF 0.8 cmpi.w #DskWrit,D5 ;do we want to read or write bne.s ODdsk2 ;read ; ODdsk1 move.w D2,SHtoLN(A1) ; move.l (A0)+,DCmd(A1) ;move first four bytes of send data to DiskCmd move.l A0,ODwrAD(A1) ;save address of REST of data clr.w D7 ;force successful IOResult move.w d0, ODvalid(A1) ;mark send buffer as valid... 0.8 bra.s ODdsk9 ;return ODdsk2 cmp.w ODvalid(A1),d0 ;is send buffer valid? (=$FFFF) 0.8 beq.s ODdsk3 ;yes, go on moveq #NoBufr,D7 ;set IOresult to "no buffer" error 0.8 bra.s ODdsk6 ;return ; ODdsk3 clr.w ODvalid(A1) ;mark send buffer as invalid move.w D2,SHfmLN(A1) ; subq.w #1,SHfmLN(A1) ;subtract one for the return code 0.8 addq.l #1,A0 ;inc buffer pointer past return code 0.8 cmpi.w #4,SHtoLN(A1) ;are we doing a longcmd? bhi.s ODdsk4 ;yes bsr ShortCmds ;no bra.s ODdsk5 ; ODdsk4 bsr LongCmds ; ODdsk5 subq.l #1,A0 ;dec buffer pointer past return code 0.8 ODdsk6 ; ; the return code must be loaded explicitly since it comes from ; the header portion of the results packet.... ; move.b D7,(A0) ;stuff return code in read buffer ; ODdsk9 movem.l (sp)+,d0-d2/a0-a2;Restore registers move.b d7,CPdiskRC.w ;Save current disk return code 0.7 ext.w d7 ;Set return condition code rts ;Return page ; 0.7 ; EndRecv -- end receive on disk server socket 0.7 ; 0.7 EndRecv movem.l d0-d1,-(sp) ;save registers 0.7 moveq #EndOp,d0 ;set command to ENDRECV 0.8 move.w #CnstSkt,d1 ;set socket number 0.7 bsr ODcomnd ;do ENDRECV on disk srvr socket 0.7 movem.l (sp)+,d0-d1 ;restore registers 0.7 moveq #0,d7 ;set no error IOresult 0.7 rts ;return 0.7 page ; ; StrobIt -- Strobe command address to Transporter ; ; Enter: A2 = command address ; ; Exit: D7 = Transporter strobe status ; ; EQ = successful ; NE = Transporter not responding ; ; All other registers are preserved ; StrobIt movem.l D0-D1/A0,-(sp) ;save registers 0.8 lea RdyAdr.L,A0 ;get address of ready flag 0.8 clr.l D7 ;assume no Transporter error 0.8 move.l A2,D0 ;get command address rol.l #8,D0 ;move command address to msb ; bsr.s SBstrob ;strobe address HI beq.s SBerr ; bsr.s SBstrob ;strobe address MED beq.s SBerr ; bsr.s SBstrob ;strobe address LO beq.s SBerr ; bsr.s SBwait ;wait for Transporter ready bne.s SBexit ; ; SBerr moveq #NoTrans,d7 ;no transporter ... ; SBexit movem.l (sp)+,D0-D1/A0 ;restore registers 0.8 tst.w d7 ;set return condition code rts ;return ; SBstrob rol.l #8,D0 ;shift address byte to lsb move.b D0,StrAdr-RdyAdr(A0) ;strobe address 0.8 SBwait move.l #TOintvl,D1 ;get timeout interval 0.8 SBW1 btst #0, (A0) ;is transporter ready? bon.s SBWchk ;yes, return 0.8 subq.l #1, D0 ;see if waited long enough 0.8 bne.s SBW1 ;no, look again 0.8 bra.s SBWexit ;timed out 0.8 SBWchk nop ;check for glitch in ready 0.8 btst #0, (A0) ;is transporter ready? 0.8 boff.s SBW1 ;no, then continue to wait 0.8 SBWexit rts ;return page ; ; SetGo -- set up a receive for the 'GO' packet ; SetGo move.w #2,TCdtaLN(A1) ;2 bytes of data clr.b TChdrLN(A1) ;no header pea GData(A1) ;get address of data area move.l (SP)+,TCdADhi-1(A1) ;load data buffer address -- TCsock destroyed bra.s SetGo1 ; ; ; SetRecv -- set up a receive for the disk results and read data ; returns result in D0 ; SetRecv move.l A0,TCdADhi-1(A1) ;load data buffer address -- TCsock destroyed move.w SHfmLN(A1),TCdtaLN(A1) ; move.b #3,TChdrLN(A1) ;disk results have a hdr len of 3 ; SetGo1 move.b #Waiting,RHpktRC(A1) ;set result to FF to see it change ;prepare the command vector pea RHdr(A1) ;load result vector address move.l (SP)+,TCrADhi-1(A1) ; -- TCop destroyed move.b #RecvOp,TCop(A1) ;set up a receive move.b #CnstSkt,TCsock(A1) ; on socket B0 ; lea TCmd(A1),A2 ;get command address bsr StrobIt ;strobe command address to Transporter bne SCerr2 ;Transporter not responding move.l #TOintvl,D0 ;for time out 0.8 SC10 cmpi.b #Waiting,RHpktRC(A1) bne.s SC12 ;wait till result changes subq.l #1, D0 ;see if waited long enough 0.8 bne.s SC10 ;no, look again 0.8 bra SCerr3 ;timeout error SC12 move.b RHpktRC(A1),d0 ;get Transporter return code cmpi.b #CmdAcpt,d0 ;was command accepted? blt SCexit ;no, fatal error clr.w D0 ;indicate success bra SCexit ;return page ; SndRest -- send the rest of the data (from long command) to the disk server ; result of call is in D0, 0 = success ; SndRest move.l ODwrAD(A1),TCdADhi-1(A1);load data buffer address move.b #RestSkt,TCSock(A1) ; - TCsock destroyed subq.w #4,SHtoLN(A1) ; 0.8 bge.s SC20 ; clr.w SHtoLN(A1) ;result was negative, make it zero SC20 move.w SHtoLN(A1),TCdtaLN(A1) ;send length - 4 bytes clr.b TChdrLN(A1) ;no header for rest packets bra.s SC40 ;send it ; SndCmds -- send a disk command to the disk server ; result of call is in D0, 0 = success ; SndCmds pea DCmd(A1) ;data is the Disk command move.l (SP)+,TCdADhi-1(A1) ;load data buffer address move.b #CnstSkt,TCsock(A1) ; - TCsock destroyed moveq #4, D0 ;4 is data and header lengt 0.8 move.w D0,TCdtaLN(A1) ;disk command is 4 bytes long 0.8 cmp.w SHtoLN(A1), D0 ;are we sending less than 4 bytes ble.s SC30 ;no (dest <= src) move.w SHtoLN(A1),TCdtaLN(A1) ;less SC30 move.b D0,TChdrLN(A1) ;send header is 4 bytes 0.8 ror.w #8,d6 ;set destination host number move.b d6,TCdest(A1) rol.w #8,d6 SC40 move.b #Waiting,SHpktRC(A1) ;set result to FF to see it change pea SHdr(A1) ;load result vector address move.l (SP)+,TCrADhi-1(A1) ; -- TCop destroyed move.b #SendOp,TCop(A1) ;sendmsg opcode lea TCmd(A1),A2 ;get command address bsr StrobIt ;strobe command address to Transporter bne.s SCerr2 ;Transporter not responding SC60 move.b SHpktRC(A1), D7 ;get send result code 0.8 cmpi.b #Waiting, D7 ;still waiting? 0.8 beq.s SC60 ;yes, check status again 0.7 cmpi.b #GaveUp, D7 ;did disk srvr accept message? 0.8 beq.s SC40 ;no, try again 0.7 cmpi.b #NoSockt, D7 ;did disk srvr accept message? 0.8 beq.s SC40 ;no, try again 0.8 clr.w D0 ;indicate success 0.7 tst.b D7 ;did it work? 0.8 bge.s SCexit ;yes, return 0.7 SCerr2 move.b D7,D0 ;no transporter ... 0.8 bra.s SCexit ;return SCerr3 moveq #TimeOut,D0 ;time out ... SCexit ext.w D0 ;make return code a word rts ;return page LongCmds ; 1. set up a receive for the GO message ; bsr SetGo ; blt.s LcmdErr ;if D0 < 0 then fatal DRW error ; ; 2. send disk command ; bsr SndCmds ;doit blt.s LcmdErr ;if D0 < 0 then fatal DRW error ; ; 3. wait to receive GO ; Lcmd1 move.b RHpktRC(A1),d0 ;get Transporter return code cmpi.b #CmdAcpt,d0 ;has return code changed? beq.s Lcmd1 ;no, wait some more tst.b D0 ;successful receive? blt.s LcmdErr ;no, set error return ; ; 4. validate GO packet ; Lcmd3 move.b TCdest(A1),D0 ;response come from the right place? 0.7 cmp.b RHsor(A1),D0 ;* 0.7 bne.s Lcmd4 ;no, setup receive again 0.7 btst #7,Gdata(A1) ;disk server restart? 0.7 bon.s LongCmds ;yes, start request over 0.7 cmpi.w #'GO',Gdata(A1) ;"GO" command? 0.7 beq.s Lcmd5 ;yes, go on 0.7 ; Lcmd4 bsr SetGo ;set up for GO receive again blt.s LcmdErr ; bra.s Lcmd1 ; page ; ; 5. set up receive for results ; Lcmd5 bsr SetRecv ; blt.s LcmdErr ;if D0 < 0 then fatal DRW error ; ; 6. send REST ; bsr SndRest ; blt.s LcmdErr ; ; ; 7. wait for results ; Lcmd6 move.b RHpktRC(A1),d0 ;get Transporter return code cmpi.b #CmdAcpt,d0 ;has return code changed? beq.s Lcmd6 ;no, wait some more tst.b D0 ;successful receive? blt.s LcmdErr ;no, set error return ; ; 8. validate results ; Lcmd7 move.b TCdest(A1),D0 ;response come from the right place? 0.7 cmp.b RHsor(A1),D0 ;* 0.7 beq.s Lcmd8 ;yes 0.7 bsr SetRecv ;no, set up receive again.... 0.7 blt.s LcmdErr ;if D0 < 0 then fatal DRW error 0.7 bra.s Lcmd6 ;go back and wait again... 0.7 ; 0.7 Lcmd8 btst #7,RHdskLN(a1) ;disk server restart? 0.7 bon.s LongCmds ;yes, start request over 0.7 ;no, done with request 0.7 ; 0.7 LcmdOK move.b RHdskRC(A1),D0 ;get disk server return code 0.7 ; 0.7 LcmdErr move.w #$1FFF,d7 ;--UP- wait a little 0.8 lc1err1 dbra d7,lc1err1 ;--UP- Why???? a bug 0.8 bsr EndRecv ;end receive on disk server socket 0.7 move.b D0,D7 ;get error return code 0.7 ext.w D7 ;make return code a word 0.7 rts ;return for ShortCmds or LongCmds 0.7 page ShortCmds ; ; 1. set up a receive for the results ; bsr SetRecv ; blt.s LcmdErr ;if D0 < 0 then fatal DRW error ; ; 2. send disk command to disk server ; bsr SndCmds ;doit blt.s LcmdErr ;if D0 < 0 then fatal DRW error ; ; 3. wait to receive results ; Scmd2 move.l CPtimout.w,d7 ;get timeout value 0.7 Scmd2A move.b RHpktRC(A1),d0 ;get Transporter return code 0.7 bge.s Scmd3 ;successful receive, go on cmpi.b #CmdAcpt,d0 ;has return code changed? bne.s LcmdErr ;yes, set error return subq.l #1,d7 ;time out? bne.s Scmd2A ;no, wait some more 0.7 bra.s LcmdErr ;set error return ; ; 4. validate results ; Scmd3 move.b RHsor(A1),D7 ;get source of response cmpi.b #$FF,TCdest(a1) ;is this a broadcast? bne.s Scmd4 ;no, go on move.b d7,RHdskRC(A1) ;save disk server number bra.s LcmdOk ;return ; Scmd4 cmp.b TCdest(A1),D7 ;response come from the right place? bne.s Scmd5 ;no 0.7 btst #7,RHdskLN(a1) ;disk server restart? 0.7 bon.s ShortCmds ;yes, start request over 0.7 bra.s LcmdOK ;no, done with request 0.7 ; 0.7 Scmd5 bsr SetRecv ;set up receive again.... 0.7 blt.s LcmdErr ;if D0 < 0 then fatal DRW error 0.7 bra.s Scmd2 ;go back and wait again... 0.7