! ! RX02 FLOPPY DISC HANDLER ! ! THIS IS THE UNIT 2&3 VERSION ! ! %% LAST UPDATED 14TH MARCH 1980 FILE=RX021S ! ! USES SYSTEM SLOTS 8 AND 14. INT SLOT -8. ! ! CALLING PARAMETERS ARE AS FOLLOWS ! P_A1=MODE (0=READ,1=WRITE) ! P_A2=ADDRESS OF BUFFER IN MEMORY ! P_A3=BLOCK NUMBER ON DISC ! ! SINCE DEIMOS DEALS IN 512 BYTE BLOCKS ALL TRANSFERS ARE 2*256 !BYTE SECTORS. THE FIRST 77 BLOCKS ARE RESERVED FOR THE SYSTEM. !WITHIN EACH TRACK OF 26 SECTORS THE SECTORS ARE INTERLEAVED. ! ! ON EXIT P_A1=FAULT NO. (0=OK) ! ! ANY ERROR WILL RESULT IN UP TO 10 RETRIES. ! ! STACK=300 STREAMS=0 ! CONTROL K'101011' SYSTEMROUTINESPEC LINKIN(INTEGER SERVICE) SYSTEMROUTINESPEC MAPHWR(INTEGER SEG) SYSTEMINTEGERFNSPEC MAP ABS(INTEGER VAD,LEN,ID) PERMROUTINESPEC SVC(INTEGER EP,P1,P2) BEGIN RECORDFORMAT PF(BYTEINTEGER SERVICE,REPLY,INTEGER A1,A2,A3) RECORDFORMAT P2F(INTEGER D) RECORDFORMAT RXF(INTEGER CONTROL,DBREG) CONSTRECORD (RXF)NAME RX=K'117170'; !DEVICE ADDR ! VECTOR = 264 ! ! SYSTEM CONSTANTS ! CONSTBYTEINTEGERNAME KID=K'160030' CONSTINTEGER SYS1=8; !UNIT 2 CONSTINTEGER SYS2=14; !UNIT 3 CONSTINTEGER DINT=-8; !INT SLOT ! ! RX02 PARAMETERS ! CONSTINTEGER TRBIT=K'400'; !READY BIT CONSTINTEGERARRAY RXTOP(1:2)=K'1751',K'1751'; !TOP OF DISC OWNINTEGERARRAY RXBOT(1:2)=K'77',K'77'; !BOTTOM OF DISC CONSTINTEGER RETC=10; !RETRY COUNT CONSTINTEGER READ=0; !INPUT PARAMS CONSTINTEGER WRITE=1 CONSTINTEGER READFN=K'107'; !RX02 FUNCTIONS CONSTINTEGER WRITEFN=K'105' CONSTINTEGER EMPTYFN=K'103' CONSTINTEGER FILLFN=K'101' CONSTINTEGER TRDONE = K'200' CONSTBYTEINTEGERARRAY SECMAP(1:26)= C 1,3,5,7,9,11,13,15,17,19,21,23,25,2,4,6,8,10,12,14,16,18,20,22,24,26 ! ! GENERAL VARIABLS ! RECORD (PF) P,PX RECORD (P2F) NAME P2 OWNINTEGER SYS,FAULT,ID,CONT,SECTOR,TRACK,RETRIES,MAPIND,I,VADDR,PAR ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! INTEGERFNS START HERE ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! REPORT FAULT SEND A MESSAGE TO MOTHER ! INTEGERFN REPORT FAULT RECORD (PF) PX PX_SERVICE=7; PX_REPLY=KID PX_A1=SECTOR; PX_A2=TRACK; PX_A3=RX_DBREG PONOFF(P) RESULT = PX_A1 END ! ! MAPADDR MAPS BUS ADDRESS ! INTEGERFN MAPADDR(INTEGER VADDR) PAR=MAP ABS(VADDR,512,ID) RESULT =1 IF PAR=0 PAR=PAR+(VADDR&K'17777')>>6 IF PAR>=K'2000' START ; !SET 17TH&18TH BITS CONT=CONT!(PAR&K'6000')<<2 PAR=PAR&K'1777' FINISH RESULT =0 END ! ! SEEK DOES READ/WRITE ! ROUTINE SEEK(INTEGER FN) RETRIES=0 RD: RX_CONTROL=CONT!FN; !GO+INT ENABLE WHILE RX_CONTROL&TRDONE=0 CYCLE ; REPEAT RX_DBREG=SECTOR WHILE RX_CONTROL&TRDONE=0 CYCLE ; REPEAT RX_DBREG=TRACK P2_D=(-8)&X'FF' POFF(P2); !WAIT FOR INT IF RX_CONTROL<0 START ; !ERROR RETRIES=RETRIES+1 IF RETRIES#RETC THEN ->RD; !TRY AGAIN FAULT = REPORT FAULT IF FAULT = 0 THEN RETRIES=0 AND -> RD FINISH END ! ! BUFFER DOES FILL/EMPTY ! ROUTINE BUFFER(INTEGER FN) RETRIES=0 WD: RX_CONTROL=CONT!FN; !GO+INT ENABLE WHILE RX_CONTROL&TRDONE=0 CYCLE ; REPEAT RX_DBREG=128; !WORD COUNT WHILE RX_CONTROL&TRDONE=0 CYCLE ; REPEAT RX_DBREG=PAR<<6+VADDR&K'77'; !BUS ADDRESS P2_D=(DINT)&X'FF' POFF(P); !WAIT FOR INT IF RX_CONTROL<0 START ; !ERROR RETRIES=RETRIES+1 IF RETRIES#RETC THEN ->WD FAULT = REPORT FAULT IF FAULT = 0 THEN RETRIES = 0 AND ->WD FINISH END ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !** !***** CODE STARTS HERE !** ! LINKIN(DINT) P2==PX MAPHWR(4); !MAP TO DICS REGS LINKIN(SYS1); LINKIN(SYS2) ! ! MAIN LOOP-WAIT FOR DISC REQUEST ! CYCLE P_SERVICE=0 POFF(P) IF P_SERVICE=SYS2 START CONT=K'420'; !UNIT 3 SYS=2 FINISHELSESTART CONT=K'400' SYS=1 FINISH FAULT=0; ID=P_REPLY VADDR=P_A2 ! ! CHECK IF ACCESS TO RESEVED AREA ! IF VADDR=0 START RXBOT(SYS)=0; FAULT=9 ELSESTART IF P_A3<RXBOT(SYS) OR P_A3>RXTOP(SYS) C THEN FAULT=4 AND ->FIN FAULT=MAPADDR(VADDR) ->FIN IF FAULT#0 ! ! COMPUTE TRACK&SECTOR ! TRACK=P_A3//13 MAPIND=(P_A3-(TRACK*13))*2+1 ! ! DO DOUBLE TRANSFER ! CYCLE I=1, 1, 2 SECTOR=SECMAP(MAPIND) IF P_A1=READ START ; !READ SEQUENCE SEEK(READFN) BUFFER(EMPTYFN) IF FAULT = 0 ELSEIF P_A1=WRITE START ; !WRITE SEQUENCE BUFFER(FILLFN) SEEK(WRITEFN) FINISH EXIT IF FAULT # 0 MAPIND=MAPIND+1; !NEXT SECTOR VADDR=VADDR+256; !NEXT ADDRESS IF VADDR&K'17777'<256 START PAR=MAP ABS(VADDR,0,10); !NEW SEG-RELEASE OLD ONE FAULT=MAPADDR(VADDR) FINISH EXITIF FAULT#0 REPEAT PAR=MAP ABS(VADDR,0,10); !RELEASE USER SEG FINISH ! !RETURN MESSAGE TO USER ! FIN: P_A1=FAULT P_SERVICE=ID IF SYS=1 THEN P_REPLY=SYS1 ELSE P_REPLY=SYS2 PON(P) REPEAT ! ENDOFPROGRAM