! FILE 'RX022S' ! ! RX02 FLOPPY DISC HANDLER ! ! THIS IS THE UNIT 0&1 VERSION ! ! %% LAST UPDATED 2ND APRIL 1980 FILE=RX022S ! ! 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) %SYSTEMINTEGERFNSPEC GET 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 ! %OWNINTEGER KID %CONSTINTEGER SYS1=3; !UNIT 2 %CONSTINTEGER SYS2=14; !UNIT 3 %CONSTINTEGER DINT=-3; !INT SLOT ! ! RX02 PARAMETERS ! %CONSTINTEGER TRBIT=K'400'; !READY BIT %OWNINTEGER TOP=1000 %OWNINTEGER BOT=88 %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,FN ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! 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(PX) %RESULT = PX_A1 %END ! ! MAPADDR MAPS BUS ADDRESS ! %INTEGERFN MAPADDR(%INTEGER VADDR) PAR=MAP ABS(VADDR,256,ID) %RESULT=1 %IF PAR=0 PAR=PAR+(VADDR&K'17700')>>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=(DINT)&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(P2); !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 KID=GET ID ! REPORT DISC FIGURES TO DIRECTORY TASK P_SERVICE = 4; P_REPLY = 3; ! UNIT 0 P_A1 = 10; ! TOP BYTE = DRIVE = 0, BOTTOM DRIVE = HERE I AM P_A2 = 161; ! 1ST USER BLOCK P_A3 = 1000; ! LAST USER BLOCK PON(P) ! 2ND PART P_A1 = 11 P_A2 = 97; ! DIRECTORY BLOCK P_A3 = 88; ! BLOCK LIST START PON(P) ! NOW FOR UNIT 1 P_A1 = 10!1<<8; ! UNIT = 1 P_A2 = 161; P_A3 = 1000 PON(P) P_A1 = 11!1<<8 P_A2 = 97; P_A3 = 88 PON(P) ! REPORT IN FINISHED LINKIN(SYS1); LINKIN(SYS2) %WHILE RX_CONTROL&K'40' = 0 %CYCLE; %REPEAT ! ! MAIN LOOP-WAIT FOR DISC REQUEST ! %CYCLE P_SERVICE=0 POFF(P) %IF P_A3&K'020000'#0 %START P_A3 = P_A3&K'017777' CONT=K'420'; !UNIT 3 SYS=2 %FINISHELSESTART CONT=K'400' SYS=1 %FINISH FAULT=0; ID=P_REPLY FN = P_A1 VADDR=P_A2 ! ! CHECK IF ACCESS TO RESEVED AREA ! %IF VADDR=0 %START BOT=0; FAULT=9 %ELSESTART %IF P_A3TOP %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 FN=READ %START; !READ SEQUENCE SEEK(READFN) BUFFER(EMPTYFN) %IF FAULT = 0 %ELSEIF FN=WRITE %START; !WRITE SEQUENCE BUFFER(FILLFN) SEEK(WRITEFN) %FINISH %EXIT %IF FAULT # 0 MAPIND=MAPIND+1; !NEXT SECTOR VADDR=VADDR+256; !NEXT ADDRESS ! PAR = PAR+4; ! THIS REALLY SHIFTS IT ! ALLWAYS DO NEXT BIT FOR NOW, 2 PROBLEMS, NEW SEG & > 32K ! %IF VADDR&K'17777'<512 %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 P_REPLY = SYS1 PON(P) %REPEAT ! %ENDOFPROGRAM