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