! 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
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_A3<BOT OR P_A3>TOP 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