! ! 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_A3RXTOP(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