; C11SIM - CAL11. simulation for TOPS20. ; ; COPYRIGHT (c) 1980, 1979, 1978,1977 ; DIGITAL EQUIPMENT CORPORATION ; ; This software is furnished under a license and may be used ; and copied only in accordance with the terms of such license ; and with the inclusion of the above copyright notice. This ; software or any other copies thereof may not be provided or ; otherwise made available to any other person. No title to ; and ownership of the software is hereby transferred. ; ; The information in this software is subject to change ; without notice and should not be construed as a commitment ; by DIGITAL EQUIPMENT CORPORATION. ; ; DIGITAL assumes no responsibility for the use or reliability ; of its software on equipment which is not supplied by ; DIGITAL. ; SUBTTL Entries, Universals, and version ENTRY CAL11$ ; CAL11. simulation routines ENTRY FLSHFE ; 2020 DDCMP Q flush routine ENTRY PRCTYP ; Processor typing routine SEARCH MACTEN,UUOSYM,MONSYM %%MACT==%%MACT ; Show MACTEN version %%UUOS==%%UUOS ; Show UUOSYM version ; %%MONS==%%MONS ; Show MONSYM version SALL ; Suppress macro expansion ; Version information C11VER==1 ; Major version number C11MIN==2 ; Minor version number C11EDT==24 ; Edit level C11WHO==0 ; Who last patched TWOSEG ; Two segment program RELOC 400000 ; Start in the HISEG ; Now Define a Title Macro DEFINE ..TITL(V,E,W),< IFE W, IFN W,<TITLE C11SIM CAL11. UUO (.C11QU) Simulation Facility - Ver V(E)-W> > ; Now make a Title ..TITL \C11VER,\C11EDT,\C11WHO SUBTTL Revision History ; Revision History ; ; Edit 16 - June 29, 1977 ; ; Edit 17 - September 29, 1977 ; Remove SIBE to improve performance. TOPS-20 Monitor Group ; claims that if the -11 crashes the SIN will give an error ; return. ; Edit 20 - September 25, 1978 ; Add Macro definitions for accessing RCVHDR and XMTHDR. ; Fix bug in returning JSYS error code. Change LIMBYT from ; 4000 to 4064 (MAXBYT*16). ; ; Edit 21 - May 2, 1979 ; Add 2020 support code. Add new copyright notice. Remove ; ego-building initials from code. ; ; Edit 22 - May 11, 1979 ; Put check for sending more than LIMBYT bytes to front-end ; at the correct place to prevent -11 from receiving two ; successive headers. ; ; Edit 23 - May 15, 1979 ; Word allignment no longer required for reading and writing ; to the DN22 so take out the extra layer of buffering. ; ; ; (24) 06-AUG-81 Add version 5 DN60 protocol cruft. SUBTTL Definitions ; AC Definitions T1=1 ; Temporary T2=2 T3=3 T4=4 C11=5 ; Points to the CAL11. Block P=17 ; Points to the Pushdown list ND MXB220,^O274 ; Maximum number of bytes that 2020 ; can ship over DDCMP link. ND MAXBYT,^D254 ; Maximum number of bytes that can be ; to the PDP11 at a time. ND LIMBYT,<MAXBYT*^D16> ; Maximum number of bytes to transfer ; without giving up the resources. SUBTTL CAL11. UUO Definitions ; Functions .C11DP==0 ; Deposit function .C11EX==1 ; Examine function .C11QU==2 ; Queue request function .C11NM==3 ; Return name of program running .C11UP==4 ; Return 0 if PDP11 is down ; Return 1 if PDP11 is up ; Error codes C11NP%==1 ; Caller does not have POKE privileges C11UF%==2 ; The function is undefined on this ; type of front end C11ND%==3 ; Invalid DL10 port number C11IU%==4 ; CAL11. in use, try again later C11NA%==5 ; No answer from the front end after ; 1-2 seconds C11TS%==6 ; Queue entry too short (DC76 only) C11NE%==7 ; Not enough arguments C11AI%==10 ; Examine/Deposit address was invalid ; (more than 16 bits or front end ; flagged it as invalid), or deposit ; data was more than 16 bits C11OR%==11 ; In .C11QU, illegal function code, ; address check, illegal byte size, ; byteoffset is outside buffer, or ; buffer is too large (requires more ; than 16 DL10 byte pointers), or more ; than 4095 bytes on a DTE20. ; Result codes returned by PDP11 in header RC.SUC==1 ; Operation successful RC.DLY==2 ; Operation delayed RC.REJ==3 ; Operation rejected, read status ; For .C11QU function ; ; MOVE AC,[XWD Length,Address] ; CAL11. AC, ; Error return ; Success return ; ; ; ADR: XWD Port number,.C11QU ; XWD Line number,Device number ; XWD Number of bytes,Function code ; XWD Length of buffer,Buffer address ; BYTE (12) Number of bytes per word (24) Position of first byte ; XWD Number of bytes transferred,Result code ; Definitions to access the "C11BLK" DEFST. (C%PORT,0(C11),-1B17) ; The port number DEFST. (C%LINE,1(C11),-1B17) ; The line number DEFST. (C%DEV,1(C11),777777) ; The device number DEFST. (C%NBYT,2(C11),-1B17) ; The number of bytes DEFST. (C%FC,2(C11),777777) ; The function code DEFST. (C%BUFS,3(C11),-1B17) ; The buffer size in words DEFST. (C%BUFA,3(C11),777777) ; The buffer address DEFST. (C%BPW,4(C11),-1B11) ; The number of bytes per word DEFST. (C%PFB,4(C11),77777777) ; The position of the first byte DEFST. (C%BXFD,5(C11),-1B17) ; The number of bytes transferred DEFST. (C%RC,5(C11),777777) ; The result code ; Definitions to access XMTHDR DEFST. (X%FC,XMTHDR,377B15) ; Function code DEFST. (X%LINE,XMTHDR,377B23) ; Line number DEFST. (X%DEV,XMTHDR,377B31) ; Device number DEFST. (X%LEN,XMTHDR+1,377B15) ; Number of data bytes ; Definitions to access RCVHDR DEFST. (R%RC,RCVHDR,377B7) ; Result code returned by PDP11 DEFST. (R%LINE,RCVHDR,377B23) ; Line number DEFST. (R%DEV,RCVHDR,377B31) ; Device number DEFST. (R%LEN,RCVHDR+1,377B15) ; Number of data bytes the -11 absorbed SUBTTL TOPS-20 version 5 DN60 protocol ;port enqueues are not necessary - BOOT will mediate use of port. ;one call will perform an entire io transaction similar to CAL11. uuo. ;if the error return is taken, BT6ERR will contain both a history of the ;transaction up to time of a fatal error(left half flags) as well a specific ;error flags(right half). .BTD60==16 ;DN60 protocol operation - BOOT JSYS .VND60==2 ;DN60 protocol type ;BTD60 ARG BLOCK DEFST. (BT6DTE,0(T2),-1B35) ;DTE number DEFST. (BT6ERR,1(T2),-1B35) ;returned error flags .BT6ERR==1 ;protocol flags D6.BSY==1B0 ;port is busy - sign bitness is used in testing D6.QHD==1B1 ;header has been queued D6.HDD==1B2 ;to -11 done for header seen D6.NDT==1B3 ;this is a no-data-transfer operation D6.RED==1B4 ;this is a read data type operation D6.QDT==1B5 ;data has been queued(for write fcn) D6.DTD==1B6 ;to -11 done for write data seen D6.RBL==1B7 ;to -10 doorbell for response header seen D6.RDN==1B8 ;to -10 done for response header seen D6.DBL==1B9 ;to -10 doorbell for read data seen D6.DDN==1B10 ;to -10 done for read data seen D6.FDN==1B11 ;to -10 done for read data was faked ;error flags D6.BDP==1B30 ;bad data byte ptr D6.ARD==1B31 ;11 attempted to send read data when ; when none was expected D6.TRS==1B32 ;timed out waiting for response header D6.TDT==1B33 ;timed out waiting for read data D6.TPO==1B34 ;timed out waiting for port to be free D6.NT6==1B35 ;not a DN60 front end D6.SER==D6.BDP!D6.ARD!D6.TRS!D6.TDT!D6.TPO!D6.NT6 ;all errors DEFST. (BT6HBC,2(T2),-1B17) ;DN60 header byte count DEFST. (BT6HDR,2(T2),777777B35);DN60 header address(begins on word) DEFST. (BT6DBC,3(T2),-1B35) ;data byte count ; positive => write data mode ; zero => no data transfer ; negative => read data mode DEFST. (BT6PTR,4(T2),-1B35) ;data byte ptr ;the following are returned for timing analysis DEFST. (BT6TMR,5(T2),-1B35) ;time of request DEFST. (BT6TAS,6(T2),-1B35) ;TIME DTE ASSIGNED DEFST. (BT6THQ,7(T2),-1B35) ;time header queued to 11 DEFST. (BT6TRD,10(T2),-1B35) ;time of -10 done for response header DEFST. (BT6TDD,11(T2),-1B35) ;time of -10 done for data DEFST. (BT6TFR,12(T2),-1B35) ;time finished request BT6SIZ==13 ; length of boot block ;DN60 header definitions DEFST. (D6FCN,XMTHDR+0,177777B15);xmitted function code DEFST. (D6RSP,XMTHDR+0,377B7) ;returned response code DEFST. (D6FCD,XMTHDR+0,377B15) ;returned function code DEFST. (D6ADR,XMTHDR+0,177777B31);address for examine/deposit DEFST. (D6DAT,XMTHDR+1,177777B15);data from examine/for deposit DEFST. (D6LIN,XMTHDR+0,377B23) ;line number DEFST. (D6DEV,XMTHDR+0,377B31) ;device code DEFST. (D6CNT,XMTHDR+1,177777B15);requested byte count to transfer ;end of original header definitons ;begin extended header DEFST. (D6AR3,XMTHDR+1,177777B31);reserved DEFST. (D6DST,XMTHDR+2,37777777777B31);returned device status DEFST. (D6LST,XMTHDR+3,37777777777B31);returned line status D6HWSZ==4 ;number of 36 bit words in header D6HBSZ==4*D6HWSZ ;number of 8 bit bytes in header SUBTTL Simulate the CAL11. UUO ; Here to simulate the .C11QU function of the CAL11. UUO ; ; CALL: PUSHJ P,CAL11$ ; AC 1 points to the CAL11. block ; ; AC 2 contains the JFN (TOPS20) ; ; or -1,,line number on 2020. ; ; AC P points to a PDL ; ERROR RETURN ; T1 contains the error code ; OK RETURN ; T1 points to the CAL11. block ; ; T2 contains the JFN CAL11$: PUSH P,1 ; Remember where CAL11. block is MOVE 1,[XWD 2,SAVEAC] ; Save AC'S 2-5 BLT 1,SAVEAC+3 ; Do it POP P,C11 ; Put adr of CAL11. block here HRRZM 2,JFN ; Remember the JFN (TOPS20) MOVEM P,PDL ; Remember where the PDL was STORE (T1,FIRZRO,LSTZRO,0) ; Zero from FIRZRO thru LSTZRO LOAD. (T3,C%PORT) ; Get the port number SKIPL KSFLG ; allow line nos. for 2020 SUBX T3,10 ; Make it the DTE number CAXL T3,0 ; Make sure its in CAXLE T3,3 ; the range of 0-3 (10-13) PJRST ILLPRT ; Illegal port number SKIPE PVTYP ; determine protocol running JRST D60IO ; DN60 protocol MOVX T2,<POINT 8,XMTHDR,7> ; Pointer to where the XMT HDR is LOAD. (T1,C%FC) ; Get the function code IDPB T1,T2 ; Put function code in XMIT HDR LOAD. (T1,C%LINE) ; Get the line number IDPB T1,T2 ; Put the line number in the XMIT HDR LOAD. (T1,C%DEV) ; Get the line number IDPB T1,T2 ; Put the device number in the XMIT HDR IBP T2 ; Go over high order of length ; cause can only have 8 bits worth ; under TOPS20 LOAD. (T1,C%NBYT) ; Get number of bytes JUMPLE T1,ILLARG ; Zero is illegal SKIPE KSFLG ; Check for 2020 JRST [CAXLE T1,MXB220 ; Check for max bytes for DDCMP MOVX T1,MXB220 ; Too many .. truncate JRST HDR.5] CAXLE T1,MAXBYT ; Larger than max allowed? MOVX T1,MAXBYT ; Set to max for DTE HDR.5: IDPB T1,T2 ; Put the number of bytes in XMIT HDR MOVE 1,C11 ; Point reg. 1 to CAL11. block PUSHJ P,ENQ$ ; Request access JRST [CAIE T1,ENQX6 ; Inuse? PJRST JSYER1 ; Yes, give JSYS error PJRST C11E4] ; Yes, give CAL11. error 4 MOVX T2,<POINT 8,XMTHDR> ; Pointer to the xmit hdr for SOUT MOVX T3,-6 ; Length of header to go out SKIPE KSFLG ; Check for 2020 JRST [LOAD. (T1,C%PORT) ; Get the port number PUSHJ P,WR2020 ; Write to the DN200 JRST TIMOUT ; No answer from front end JRST CL1S.2] ; Continue on. MOVE T1,JFN ; JFN for SOUT SOUT ; Output the header ERJMP JSYER2 ; SOUT failed on FE device PUSHJ P,FLUSH ; Make sure header is out of TOPS20 CL1S.2: LOAD. (T1,C%FC) ; Get function code TRNN T1,1 ; Odd function code means read JRST WRITE ; take care of write JRST READ D60IO: ; T3/dte number ; C11/ptr to CALL11 block MOVEI T2,PROARG ; get boot block ptr STOR. T3,BT6DTE ; set dte number SETZM .BT6ERR(T2) ; clear error status MOVEI T1,6 STOR. T1,BT6HBC ; set length of DN60 header MOVEI T1,XMTHDR STOR. T1,BT6HDR ; set DN60 header ptr PUSHJ P,MKPNT ; get data byte ptr MOVE T1,T2 MOVEI T2,PROARG ; restore boot block ptr ; T1/data byte ptr ; T3/negative byte count STOR. T1,BT6PTR ; set data byte ptr LOAD. (T1,C%FC) ; get function code TRNN T1,1 ; determine read/write MOVMS T3 ; write => positive byte count STOR. T3,BT6DBC ; set data byte count STOR. T1,D6FCN ; set DN60 function code(clears result) MOVMS T3 ; make sure data count is positive STOR. T3,D6CNT ; set requested xfer size LOAD. (T1,C%LINE) STOR. T1,D6LIN ; set line number LOAD. (T1,C%DEV) STOR. T1,D6DEV ; set device number MOVEI T1,.BTD60 ; get boot fcn code for DN60 io BOOT ; do it ERJMP V5ERR JRST CL1S.2 ; go do clean up V5ERR: LOAD. T1,BT6ERR ; get the error status ; analyze version errors TXNE T1,D6.BDP JRST [MOVEI T1,C11OR% ; crufty byte ptr JRST ERRRET] TXNE T1,D6.TPO!D6.TRS!D6.TDT ; TRS observed when tgha run, assume ; TDT might also occur JRST [MOVEI T1,C11IU% ; waited too long for port JRST ERRRET] TXNE T1,D6.NT6 JRST [MOVEI T1,C11UF% ; not a DN60 front end JRST ERRRET] MOVEI T1,C11NA% ; bad things are happening JRST ERRRET ; and return it ; Here for read functions READ: SKIPE PVTYP ; determine protocol running JRST RD.PV5 ; DN60 read PUSHJ P,GETHDR ; Get the header LOAD. (T1,R%LEN) ; Get num of bytes returned in the HDR MOVEM T1,NBXFR ; Save no of bytes JUMPE T1,READFN ; If no bytes to follow don't read any PUSHJ P,MKPNT ; Make pointer to buffer in T2 LOAD. (T4,R%LEN) ; Get number of bytes again MOVNS T3 ; Length of user's buffer CAMLE T4,T3 ; Will message fit? PJRST ILLARG ; No, give error. MOVN T3,T4 ; Yes, read as many bytes told by HDR SKIPE KSFLG ; Check if working on a 2020 JRST [LOAD. (T1,C%PORT) ; Get the port number PUSHJ P,RD2020 ; Yes .. so read 2020 style JRST JSYER3 ; Error while reading from FE JRST READFN] ; Get result (don't need to break I/O) SIN ; Get the data portion ERJMP JSYER3 ; Input from FE device failed PUSHJ P,FLUSH ; Make sure TOPS20 doesn't hold back READFN: LOAD. (T1,R%RC) ; Get result code LOAD. (T2,R%LEN) ; Get number of bytes transferred JRST SRCBYT ; Exit RD.PV5: LOAD. T1,D6RSP ; get the response code LOAD. T2,D6CNT ; get bytes actually transferred JRST SRCBYT ; and return ; Here for write functions WRITE: SKIPE PVTYP ; determine protocol running JRST WR.PV5 ; DN60 write LOAD. (T1,C%NBYT) ; Save byte count specified MOVEM T1,TOTBYT ; for restoring at exit LOAD. (T1,C%PFB) ; Save position of first byte MOVEM T1,POSBYT ; for restoring later WRITEB: PUSHJ P,MKPNT ; Prepare for more, point to data SKIPE KSFLG ; Check for working on a 2020 JRST [LOAD. (T1,C%PORT) ; Get the port number PUSHJ P,WR2020 ; Yes .. so write 2020 style to FE JRST JSYER4 ; Error while writing JRST WRIT.5] ; Go get header (no I/O break needed) SOUT ; Send the data ERJMP JSYER4 ; Output to FE device failed PUSHJ P,FLUSH ; Make sure data is out of TOPS20 WRIT.5: PUSHJ P,GETHDR ; Get HDR with length and result code LOAD. (T2,R%LEN) ; Count of bytes returned JUMPE T2,FINISH ; all done one way or another ADDM T2,NBXFR ; Update # of bytes xferred LOAD. (T1,C%PFB) ; Update the position ADD T1,T2 ; of first byte in STOR. (T1,C%PFB) ; the CAL11. block LOAD. (T3,C%NBYT) ; Update the count SUB T3,T2 ; of bytes left to STOR. (T3,C%NBYT) ; transfer for next time JUMPE T3,FINISH ; Exit if nothing left LOAD. (T1,R%RC) ; Get result code CAXE T1,RC.SUC ; Successful? JRST FINIS2 ; No, tell the caller SKIPE KSFLG ; Check for 2020 JRST [CAXLE T3,MXB220 ; Check for max bytes for DDCMP MOVX T3,MXB220 ; Too many .. truncate JRST WRT.5] CAXLE T3,MAXBYT ; Larger than max allowed? MOVX T3,MAXBYT ; Set to max for DTE WRT.5: STOR. (T3,X%LEN) ; Put number of bytes in xmit header MOVE T1,JFN ; Prepare to send header MOVX T2,<POINT 8,XMTHDR> ; Point to xmit header MOVX T3,-6 ; Length of xmit header SKIPE KSFLG ; Check for a 2020 JRST [LOAD. (T1,C%PORT) ; Get the port number PUSHJ P,WR2020 ; Yes .. so write on DDCMP link JRST JSYER5 ; Error while sending header JRST WRITEB] ; Done sending header, go try again SOUT ; Output header ERJMP JSYER5 ; Output to FE device failed PUSHJ P,FLUSH ; Make sure header is out of TOPS20 JRST WRITEB ; Loop till all done FINISD: SKIPA T1,[EXP RC.DLY] ; Give delayed return FINISH: LOAD. (T1,R%RC) ; Get result code in T1 FINIS2: MOVE T2,TOTBYT ; Restore total byte count STOR. (T2,C%NBYT) ; in the CAL11. block MOVE T2,POSBYT ; Restore byte-position STOR. (T2,C%PFB) ; also MOVE T2,NBXFR ; Get count of bytes xferred SRCBYT: STOR. (T1,C%RC) ; Put where CAL11. UUO would STOR. (T2,C%BXFD) ; Put where CAL11. UUO would put count AOS (P) ; Give skip return MOVE 1,C11 ; Restore AC 1 PJRST RELDEV ; Deque device, restore AC'S WR.PV5: LOAD. T1,D6RSP ; get the response code LOAD. T2,D6CNT ; get bytes actually transferred JRST SRCBYT ; and return SUBTTL Routines ; Here to get the header ; ; CALL: PUSHJ P,GETHDR ; JFN contain JFN ; RETURN ; If SIN fails ; RETURN ; Success with header in "RCVHDR" GETHDR: MOVE T1,JFN ; JFN MOVX T2,<POINT 8,RCVHDR> ; Where to put the header MOVX T3,-6 ; 6 bytes of header SKIPE KSFLG ; Check for a 2020 JRST GH2020 ; Yes .. so read from DDCMP link SIN ; Get the header ERJMP JSYER6 ; Input from FE device failed PJRST FLUSH ; Return with header in "RCVHDR" GH2020: LOAD. (T1,C%PORT) ; Get the port number PUSHJ P,RD2020 ; Read header 2020 style JRST JSYER6 ; Error while reading header POPJ P, ; Return (I/O break not needed) ; Routine to make sure data gets out ; ; CALL: PUSHJ P,FLUSH ; RETURN FLUSH: MOVE T1,JFN ; JFN MOVX T2,.MOEOF ; Force output MOVX T3,1 ; Flush buffers w/o sending real EOF MTOPR ; Make sure all is output ERJMP JSYER7 ; Buffer flushing on FE device failed POPJ P, ; Return ; Routine to make a pointer to the buffer ; ; CALL: PUSHJ P,MKPNT ; RETURN ; T1 contains JFN ; ; T2 contains pointer ; ; T3 contains neg length MKPNT: LOAD. (T2,C%BPW) ; Get number of bytes per word CAXL T2,4 ; Can only have 4-6 CAXLE T2,6 ; bytes per word PJRST ILLARG ; Bytes per word out of range LOAD. (T3,C%BUFA) ; Get address of buffer LOAD. (T4,C%BUFS) ; Get size of buffer in words ADDI T4,-1(T3) ; Point to last address in the buffer. HLL T3,[POINT 8, ; 4 bytes per word POINT 7, ; 5 bytes per word POINT 6,]-4(T2) ; 6 bytes per word LOAD. (T2,C%PFB) ; Get number of bytes ADJBP T2,T3 ; Point to right place LOAD. (T1,C%NBYT) ; Get number of bytes ADJBP T1,T2 ; Figure last address in the buffer CAIGE T4,(T1) ; Exceeding buffer? PJRST ILLARG ; Yes, illegal arg in argument block LOAD. (T3,C%NBYT) ; Get number of bytes SKIPE PVTYP ; check protocol type JRST MKP.5 ; DN60 - no limit SKIPE KSFLG ; Check for 2020 JRST [CAXLE T3,MXB220 ; Check for max bytes for DDCMP MOVX T3,MXB220 ; Too many .. truncate JRST MKP.5] CAXLE T3,MAXBYT ; Larger than max allowed? MOVX T3,MAXBYT ; Set to max for DTE MKP.5: MOVNS T3 ; Make negative byte count MOVE T1,JFN ; Return JFN in T1 POPJ P, ; Return T2 contains pointer ; and T3 contains -length ; and T1 contains the JFN ; Here on various JSYS errors JSYER1: JSP T2,JSYERX ; Error 1 JSYER2: JSP T2,JSYERX ; Error 2 JSYER3: JSP T2,JSYERX ; Error 3 JSYER4: JSP T2,JSYERX ; Error 4 JSYER5: JSP T2,JSYERX ; Error 5 JSYER6: JSP T2,JSYERX ; Error 6 JSYER7: JSP T2,JSYERX ; Error 7 JSYER8: JSP T2,JSYERX ; Error 8 JSYERX: SUBX T2,JSYER1 ; Compute the HRRZS T2 ; error code (1-8) JSYERC: MOVEM T2,JSYERR ; Remember the error code MOVX T1,.FHSLF ; Get the JSYS GETER ; error code from the monitor HRRZ T1,T2 ; Get it in T1 for return from this JRST ERRRET ; Return from the CAL11. simulation ; Here if we timed out waiting for a response from the PDP11 TIMOUT: MOVX T1,C11NA% ; Timeout error code JRST ERRRET ; Give error return ; Here if a lock was already requested for the device C11E4: MOVX T1,C11IU% ; Device in use JRST ERRRET ; Give error return ; Here if a illegal argument discovered in the CAL11. function block ILLARG: MOVX T1,C11OR% ; Illegal arg return JRST ERRRET ; Give error return ; Here if the port number is out of range in the CAL11. function block ILLPRT: MOVX T1,C11ND% ; Illegal port number ERRRET: MOVE P,PDL ; Reset PDL pointer RELDEV: SKIPE PVTYP ; determine protocol running JRST RESEXT PUSH P,T1 ; Save this as it has user info in it PUSHJ P,DEQ$ ; Deq the device PJRST JSYER8 ; Deq didn't work POP P,T1 ; Restore this AC RESEXT: MOVE 5,[XWD SAVEAC,2] ; Restore AC'S BLT 5,5 ; 2-5 POPJ P, ; Return to caller SUBTTL Routines to read/write to a DN200 ; Routine - FLSHFE ; ; Function - This routine has two functions. First it insures that ; the processor type has been checked and second if it is a 2020 ; it will flush the DDCMP monitor Q's. ; ; Parameters - ; ; T1/ Line number for DN200 FLSHFE: SKIPN APRNUM ; Is the CPU serial number known PUSHJ P,PRCTYP ; No .. go check processor type SKIPN KSFLG ; Check for a 2020 JRST CPOPJ1 ; No .. so just return PUSH P,T2 ; Save a register MOVEI T2,BTARG ; Point to BOOT argument block MOVEM T1,.BTDTE(T2) ; Set the line number FLSH.1: MOVX T1,MXB220 ; Get maximum possible byte count MOVEM T1,.BTLEN(T2) ; Set number of bytes to read MOVE T1,[POINT 8,XMSG] ; Point to message area MOVEM T1,.BTMSG(T2) ; Set pointer to 8 bit byte area MOVX T1,.BTRDD ; Read DDCMP message function code BOOT ; Do the read ERJMP FLSH.6 ; Error while flushing SKIPE .BTLEN(T2) ; Check for no message returned JRST FLSH.1 ; Message there .. continue Q flush MOVE T1,.BTDTE(T2) ; Done flushing .. restore line number AOS -1(P) ; Success is a skip return FLSH.6: POP P,T2 ; Restore a register POPJ P, ; Return ; Routine - WR2020 ; ; Function - To simulate a SOUT JSYS to a FE device. Actually it ships the ; data over a DDCMP link on a 2020 to a DN200 (or equivalent). ; ; Parameters - ; ; T1/ Line number ; T2/ Byte pointer to string ; T3/ Negative byte count WR2020: PUSH P,T4 ; Save some registers MOVEM T1,.BTDTE+BTARG ; Set the line number MOVMM T3,.BTLEN+BTARG ; Set the byte count to transfer MOVEM T2,.BTMSG+BTARG ; Set pointer in BOOT block SKIPLE T3 ; Check for illegal byte count JRST WR2.F ; Yes .. error return MOVEI T2,BTARG ; Get pointer to BOOT arg block MOVX T1,.BTSDD ; Send DDCMP message to DN200 BOOT ERJMP WR2.F ; BOOT failed .. can't talk to FE MOVE T1,.BTDTE+BTARG ; On success .. get line number back SETZ T3, ; Say that all bytes were output AOS -1(P) ; Skip return (success) WR2.F: POP P,T4 ; Restore registers POPJ P, ; Return ; Routine - RD2020 ; ; Function - To simulate a SIN JSYS to a FE device on a 2020 DN200 DDCMP link. ; ; Parameters - ; ; T1/ Line number of DUP to DN200 ; T2/ Byte pointer to string destination ; T3/ Negative byte count to read in RD2020: PUSH P,T4 ; Save a register DMOVEM T1,RDSAVE ; Save the read arguments MOVEM T3,RDSLEN ; including the data string length MOVX T4,20 ; Set up the retry counter so that MOVEM T4,RETRY ; we try at least 5 seconds worth MOVEI T2,BTARG ; Get location of BOOT arg block MOVEM T1,.BTDTE(T2) ; Set the line number in BOOT block RD20ST: MOVMM T3,.BTLEN(T2) ; Set the byte count to transfer MOVE T1,RDSAVE+1 ; Point to message area MOVEM T1,.BTMSG(T2) ; Set pointer to 8 bit byte area MOVX T1,.BTRDD ; Read DDCMP message function BOOT ; Do the read ERJMP RD2.F ; BOOT failed .. can't listen to DN200 SKIPN T1,.BTLEN(T2) ; Get transfered length/error code JRST R20RTY ; If zero .. must try again TXNN T1,BT%CTL ; Check for control message flag JRST R20OK ; No .. so message was read ok CAXE T1,BT%CTL+.BTCMP ; Transmission complete? JRST RD2.F ; No .. line just glitched .. FE dead JRST R20AGN ; Try to read it again R20RTY: SOSGE T4,RETRY ; Have we already tried enough? JRST RD2.F ; Yes .. FE not answering because dead MOVE T1,[DEC 1000,1000,1000,1000,1000,100,100,100 DEC 100,100,100,100,100,100,100,100](T4) DISMS ; Increasing sleep increments R20AGN: MOVE T3,RDSLEN ; Get length to read back again JRST RD20ST ; Go try to read it again R20OK: ADDM T1,RDSLEN ; Make it minus the number yet to get MOVE T1,RDSAVE ; Restore line number on success MOVE T3,RDSLEN ; Get updated string length AOS -1(P) ; Skip return is success RD2.F: POP P,T4 ; Restore registers POPJ P, ; Return SUBTTL PRCTYP -- Routine to type the processor ; Routine - PRCTYP ; ; Function - ; ; This routine determines whether we are running on a KL or KS system. ; ; Parameters - none ; ; Returns - +1 always ; ; APRNUM/ Contains the processor serial number ; KSFLG/ 0 if KL, non-zero if KS PRCTYP: PUSH P,T1 ; Save some registers PUSH P,T2 MOVE T1,[SIXBIT \APRID\] ; Table in TOPS20 to check SYSGT ; for the processor serial number MOVEM T1,APRNUM ; Save the processor serial number SETZM KSFLG ; Default to KL CAIL T1,^d4096 ; Test for a KS serial number SETOM KSFLG ; Yes .. so set such an indicator POP P,T2 ; Restore the registers POP P,T1 POPJ P, ; Routine to get sole access of a FE device ; ; CALL: PUSHJ P,ENQ$ ; AC(1) points to the CAL11. block ; RETURN ; with JSYS error code in AC(1) ; RETURN ; If got device and "$ENQF" is ; ; set to -1. ENQ$:: SKIPE PVTYP ; determine protocol running JRST CPOPJ1 HLRZ T1,(1) ; Get the port number DPB T1,[POINT 3,ENQBUF+1,20] ; Put in low digit in ASCIZ string LSH T1,-3 ; Get next digit (should be 0 for now) DPB T1,[POINT 3,ENQBUF+1,13] ; Put in high digit in ASCIZ string MOVX T1,.ENQBL ; ENQ function code, blocking MOVEI T2,ENQBLK ; Point to the argument block ENQ ; Request access ERJMP CPOPJ ; Give non skip return SETOM $ENQF ; Flag we got the device CPOPJ1: AOS (P) ; Skip return CPOPJ: POPJ P, ; Return to caller ; Routine to release the device ; ; CALL: PUSHJ P,DEQ$ ; RETURN ; If DEQ fails ; RETURN ; Device dequeued and "$ENQF" = 0. DEQ$:: SKIPN $ENQF ; Do we have the device? JRST CPOPJ1 ; No, give skip return SETZM $ENQF ; Flag we let go MOVX T1,.DEQDR ; DEQ function code MOVEI T2,ENQBLK ; Point to the function block DEQ ; Let go of the device ERJMP CPOPJ ; Give nonskip return JRST CPOPJ1 ; and give skip return ; ENQ/DEQ argument block ENQBLK: XWD 1,5 ; 1 lock,,length is 5 XWD 0,0 ; CHN 0,,ID EXP EN%BLN+EN%LTL+<0,,-3> ; Long term,, OPERATOR only POINT 7,ENQBUF ; String pointer XWD 0,0 ; 1 resource,,Num of accesses ; Don't show listing of literals XLIST LIT LIST SUBTTL TOPS-20 DN60 CRUFT ;TOPS-20 version 5 DN60 protocol definitions PROTYP:: ; T1/port number PUSH P,T1 PUSHJ P,PRCTYP ; check processor type SKIPGE KSFLG JRST PRODFL ; on 2020 DDCMP protocol verison is 2 also MOVEI T2,PROARG ; determine protocol version running on dte ANDI T1,7 MOVEM T1,.BTDTE(T2) ; stuff dte number MOVEI T1,.BTSTS ; get dte status BOOT ; returns protocol version or -1 ERJMP PRODFL MOVE T1,PROARG+.BTCOD ; snatch the results CAIE T1,.VND60 ; skipe if version 5 protocol PRODFL: SETZ T1, ; no - set not version 5 MOVEM T1,PVTYP POP P,T1 POPJ P, SUBTTL Low segment storage RELOC ENQBUF: ASCIZ \DN60-P00\ ; Build the ENQ/DEQ string here JFN: BLOCK 1 ; Save the JFN here PDL: BLOCK 1 ; Save ACP here SAVEAC: BLOCK 4 ; Save AC'S 2-5 here APRNUM:: BLOCK 1 ; Proccessor serial number KSFLG:: BLOCK 1 ; Flag set for 2020 XMSG: BLOCK ^O275/4 ; Buffer for flushing DDCMP q's. BTARG: BLOCK 5 ; BOOT JSYS argument block RDSAVE: BLOCK 2 ; Temporary locals for RD2020 arg's RDSLEN: BLOCK 1 RETRY: BLOCK 1 ; BOOT JSYS retry counter PVTYP:: 0 ; dte protocol version type FIRZRO==. ; From FIRZRO thru LSTZRO get zero'd PROARG::BLOCK BT6SIZ ; arg block for .BTSTS call XMTHDR::BLOCK D6HWSZ ; Transmit header RCVHDR::BLOCK 2 ; Recieve header $ENQF:: BLOCK 1 ; If nonzero, we have a device enq'd. POSBYT: BLOCK 1 ; Position of first byte TOTBYT: BLOCK 1 ; Total byte count NBXFR: BLOCK 1 ; Bytes transferred JSYERR: BLOCK 1 ; JSYS error code (1-8) LSTZRO==.-1 ; Last location that gets zero'd END ; Local Modes: ; Comment Start:; ; Mode:MACRO ; Comment Column:40 ; Auto Save Mode:2 ; Word Abbrev Mode:1 ; End: