IMD 1.17: 11/11/2014 11:11:37 82VKXSVRDOS B* VERSADOS/RMS68K SRC/OBJ 4.4 (NOT BOOTABLE) SN=49367 11 0F 30  SR11q82VKXSVRDOS 0420¤h-qqROMIOI90AFqqROMIOI90SA¥qqSCTSASR AFqqSCTSASR SA((’qqSECURE AF99qqSECURE SABB;HqqSYSCNTRLAFƒƒqqSYSCNTRLSAŒŒpØqqUSM AFqqŠPAGEŠNOLISTŠINCLUDE�9995.&.IOE.EQŠINCLUDE�9995.&.EXE.EQŠINCLUDE�9995.&.NIO.EQŠINCLUDE�9995.&.TR1.EQŠINCLUDE�9995.&.TR1RTCD.EQŠINCLUDE�9995.&.FME.EQŠINCLUDE�9995.&.FMI.EQŠLIST*‰INCLUDE�9995.&.IOE.EQ*‰INCLUDE�9995.&.EXE.EQ*‰INCLUDE�9995.&.NIO.EQ*‰INCLUDE�9995.&.TR1.EQ*‰INCLUDE�9995.&.TR1RTCD.EQ*‰INCLUDE�9995.&.FME.EQ*‰INCLUDE�9995.&.FMI.EQ*ŠPAGE**FMS I/O MANAGEMENT* ŠSECTION�0* *04/05/84 SCBD*‚Corrected�bug�in�three�places�in�FIOM.‚At�labels�GPTSAT,�GPTDB�and@*‚GPTSDB�we�had�BSRs�to�DOIO.‚When�these�BSRs�were�executed,�theE*‚IOS�parameter�block�indicated�'I/O�wait'.‚DOIO,�however�was�turningC*‚on�the�proceed�bit,�making�an�'I/O�proceed'�out�the�call.‚At�eachC*‚of�these�points,�BSR�DOIO�was�replaced�by�BSR�DOIO2.‚A�change�wasF*‚made�in�the�FUTY�module�(added�DOIO2�entry�point)�which�would�handleF*‚the�I/O�as�an�'I/O�wait'�as�originally�intended.‚The�symptom�of�thisE*‚bug�was�a�system�hang�up�whenever�many�tasks�were�terminated�at�the9*‚same�time�and�each�on�required�the�loading�of�TASKDUMP. *12/28/83 SCBC*‚Corrected�bug�which�caused�extra�FAB�to�be�created�when�splittingC*‚FAB�and�data�block�on�a�fully�packed�file.‚Correction�in�the�area *‚of�CMBF10. ŠDC.Bƒ'FIOM'ŠDC.Lƒ'040584�4'IOM‡IDNTƒ4,2�FHS�I/O�MANAGE. ŠXDEFƒDIRDEL ŠXDEFƒDIRINS ŠXDEFƒDIRNME ŠXDEFƒDSNME ŠXDEFƒDSNXT ŠXDEFƒGETVIDŠXDEFƒGPTSEC�6/24/83�MLBŠXDEFƒISTAIERR ŠXDEFƒPUTALL ŠXDEFƒPUTALL2 ŠXREFƒC7ADDR ŠXREFƒCEADDR ŠXREFƒCHKAP ŠXREFƒCHKMA ŠXREFƒDOIO ŠXREFƒDOIO2 ŠXREFƒFATEND ŠXREFƒFATSTR ŠXREFƒFMSSTR ŠXREFƒFTL.EQ ŠXREFƒFTL.HI ŠXREFƒFTL.NE ŠXREFƒFTL.T ŠXREFƒSEGBLKO ŠXREFƒSEGBLKS ŠXREFƒSMOVE4 ŠXREFƒTDBLK ŠXREFƒVDTEND ŠXREFƒVDTSTRŠIFGTƒFMSLEVEL-1 �XDEFƒDBCHG �XDEFƒFABCHG �XDEFƒFSALLC �XDEFƒFSDEAL �XDEFƒGETFDB �XDEFƒPUTDAT �XDEFƒRLNFAT �XDEFƒRLNFT3 �XDEFƒUPCFAB �XREFƒATTIOBO �XREFƒCALSEC �XREFƒGETIOB �XREFƒUPDEOFŠENDCŠIFEQƒFMSLEVEL-3 �XDEFƒCMPRDB �XDEFƒEXPNDB �XDEFƒFNDKEY �XDEFƒPUTKEYŠENDCŠPAGE](O0N8N@GHKPJX>`RhHpAx9€BˆA�B˜E :¨M°R¸TÀ6È=ÐCØNàLèEðLø>FM !*CALBIT 1.00 6/18/79 L. STEINHOFF*B*CALBIT CALCULATES THS SAT SECTOR, MEMORY ADDR. AND BIT NO. IN THE+*…SAT�MEMORY�BLOCK�FOR�THE�REQUESTED�SECTOR**<*MEMORY ADDR. IS ON LONG WORD BOUNDARY TO ALLOW USE OF 'BIT'**…INSTRUCTIONS�ON�REGISETERS�USING�32�BITS* *ON CALL:*…A6=VDT�ADDRESS*†A1=SECTOR�ADDRESS�REQUESTED *…BSR�CALBIT* *ON RETURN:*…A6=UNCHANGED*…A1=UNCHANGED'*…A2=MEMORY�ADDRESS�CONTAING�SECTOR�BIT*…A3=A1*†D0.L=0�IF�NO�ERROR,*…D0.B=ISTAAL�IF�NO�SAT�FOR�REQUESTED�SECTOR*‰=80+�IF�I/O�ERROR*ˆMEMORY�BUFFER,*†D2.B=BIT�NO�(0-31)�CORRESPONDING�TO�SECTOR0*…D6=LONG�WORD�FROM�MEMORY�CONTAINING�SECTOR�BIT*…Z=1�IF�NO�ERROR *†=0�IF�ERROR** CALBIT„EQU„*<*GET SECTOR IN MEMORY THAT CONTAINS BIT FOR REQUESTED SECTOR ŠMOVE.L�A1,A3 ŠMOVE.L�A1,D2ŠDIVUƒ#2048,D25*D2.W=RELATIVE SECTOR IN SAT. MAKE SURE NOT TOO LARGEŠCMP.W‚VDTVID+VIDSAL(A6),D2ŠBCS.S‚CALB10�SECTOR�IN�RANGE0ŠMOVE.L�#NL+ISTAAL,D0†FILE�SPACE�ALLOC.�CONFLICT CALBRT„RTSCALB10„MOVE.L�A1,-(A7)*ŠMOVE.L�VDTVID+VIDSAT(A6),A1�GET�SAT�START"ŠADD.W‚D2,A1ŽGET�PSN�OF�SAT�SECTOR ŠBSR„GETSAT"ŠMOVE.L�(A7)+,A1‹RESTORE�A1�SECTOR#ŠBNE.S‚CALBRT�MAKE�I/O�ERROR�RETURN8*USE REMAINDER (0-2047) OF PREVIOUS DIVISON TO DETERMINE*…MEMORY�ADDR. ŠCLR.W‚D2ŠSWAPƒD2‘D2.L=REMAINDER ŠMOVE.L�D2,D0'ŠLSR.L‚#5,D0ŽDIVIDE�BY�32�TO�GET�OFFSETŠLSL.L‚#2,D0ŽMULTIPLY�BY�4,ŠMOVE.L�VDTSMA(A6),A2†GET�START�OF�SAT�IN�A2ŠADD.L‚D0,A2ŽADD�OFFSET*NOW CALCULTE BIT WITHIN WORDŠMOVE.L�#$1F,D0&ŠAND.L‚D0,D2ŽSAVE�LOW�4�BITS�AS�MOD�32)ŠSUB.B‚D0,D2ŽFORCE�MSB�TO�BE�BIT�COUNT�15 ŠNEG.B‚D2ŠMOVE.L�(A2),D6ŒGET�DATA�IN�REG ŠCLR.L‚D0ŠRTSŠPAGE!*DSALLC 1.00 6/18/79 L. STEINHOFF*.*DSALLC ALLOCATES THE REQUESTED NO. OF SECTORS* *ON CALL:*…A6=VDT�ADDRESS*…A4=FAT�ADDR.�(=0�IF�NONE)*…D1=NO.�OF�SECTORS *†BSR�DSALLC* *ON RETURN:*…A6=UNCHANGED"*…A1=STARTING�SECTOR�FOR�ALLOCATED*†D0.L=�0�IF�NO�ERROR)*ˆD0.B=ISTAIDS�IF�INSUFFICIENT�DISK�SPACE *‰=ISTAAL�IF�0�SECTORS�REQUESTED*ˆ=8O+�IF�I/O�ERROR*…D1=NO�OF�SECTORS�ALLOCATED*…Z=0�IF�NO�ERROR *†=1�IF�ERROR***INDENTED LIST9* DSALLC ALLOCATES REQUESTED NUMBER OF SEQUENTIAL SECTORS!*DSALLC PASS-PSN AND-SECTOR COUNT* FIND AND-MARK SECTORS' BITS!*‚CALL�$CALBIT,�$CHKBITS,�$NXTBIT* SPACE FOUND? *‚NO,�RETURN�INSUFFIC�DISK-SPACE!*‚YES,RETURN�PSN-AND�SECTOR�COUNT*INDENTED LIST END* DSALLC„EQU„* ŠTST.L‚D1 ŠBNE.S‚DSAL05ŠMOVE.L�#NL+ISTAAL,D0ŠRTS DSAL05„EQU„*ŠMOVEM.L�A2-A3/A5/D2-D6,-(A7)ŠMOVE.L�D1,D5ŽSAVE�SECTOR�COUNT*.*ˆTRY�TO�ALLOCATE�SPACE�IN�SAT�BLOCK�IN�MEMORY8*ˆ1ST,�THEN�CONTINUE�TO�END�AND�WRAP�AROUND�IF�NECESSARY+ŠMOVE.L�VDTSMB(A6),D0†SAT�SECTOR�IN�MEMORY?ŠBNE.S‚DSAL80�YES***NO - START AT BEGINNING**SET A5=END OF SAT+1ŠMOVE.L�VDTVID+VIDSAT(A6),A5ŠADD.W‚VDTVID+VIDSAL(A6),A5 DSAL41„EQU„*ŠSUB.L‚A1,A1ŽSET�A1�=�0"ŠBSR„CALBIT�GET�CORRECT�SAT�SECTOR&DSAL42„CLR.L‚D3‘0�COUNT�FOR�THIS�BLOCK7*IF SAT SECTOR IS BEYOND WHERE 1ST SEARCH STARTED, STOPŠCMP.L‚VDTSMB(A6),A5ŠBLS.S‚DSAL72�ALL�DONE-NOSPACE,ŠMOVE.L�A3,A1ŽSAVE�POTENTIAL�START�OF�AVAIL.&ŠBSR„CHKBITSŒSTART�OF�AVAILABLE�BLOCK?'ŠBCS.S‚DSAL60�NO�SEARCH�FOR�AVAIL�BLOCKDSAL44„CMP.L‚D3,D5ŠBLS.S‚DSAL25�SPACE�FOUND!ŠBSR.S‚NXTBIT�GET�NEXT�SECTOR�BIT ŠBNE.S‚DSAL50 ŠBSR„CHKBITS ŠBCS.S‚DSAL50 ŠBRA.S‚DSAL44*2*ˆAVAILABLE�SPACE�EXISTS�WHERE�REQUESTED�MARK�BITS *ˆALLOCATED*ˆA1�=�STARTING�ADDR.*ˆD5�=�NO.�OF�BITS�TO�ALLOCATE* DSAL25„EQU„*!ŠMOVE.L�D5,D1ŽSAVE�NO.�OF�SECTORS+ŠBSR„CALBIT�CALCULATE�BIT/OFFSET�FOR�SECTORŠBNE.S‚DSALRT�RETURN�ERROR%DSAL28„BSETƒD2,D6ŽSET�APPROPRIATE�BIT.ŠBSETW‚#VDFLSB,VDTFLG(A6)�SET�SAT�CHANGED�FLAGŠSUB.L‚#1,D5ŽDONE?ŠBEQ.S‚DSAL30�YESŠBSR.S‚NXTBIT�NO�-�GET�NEXT�BITŠBRA.S‚DSAL28�CONTINUEDSAL30„MOVE.L�D6,(A2)ŠCLR.L‚D0‘SET�GOOD�RETURN�FLAGSŠBRA.S‚DSALRT�RETURN*,*DON'T GO ON IF AT END OF BLOCK OR I/O ERRORDSAL50„CMP.B‚#ISTAAL,D0ŠBEQ.S‚DSAL72�DONE ŠTST.B‚D0ŠBNE.S‚DSALRT�I/O�ERROR DSAL60„BSR.S‚NXTBIT�GET�NEXT�BITŠBEQ.S‚DSAL42�GET�NEXT�BIT ŠCMP.B‚#ISTAAL,D0ŠBNE.S‚DSALRT�I/O�ERROR$*MAKE INSUFFICIENT DISK SPACE RETURNDSAL72„MOVE.L�#NL+ISTAIDS,D01DSALRT„MOVEM.L�(A7)+,D2-D6/A2-A3/A5�RESTORE�REGS.ŠRTS DSAL80„EQU„*&ŠMOVE.L�D0,A5ŽSAVE�STARTING�SAT�SECTORŠSUB.L‚VDTVID+VIDSAT(A6),D0ŠMULUƒ#2048,D04*A1=1ST SECTOR CORRESPONDING TO SAT SECTOR IN MEMORY ŠMOVE.L�D0,A1 ŠBSR„CALBIT&DSAL82„CLR.L‚D3‘0�COUNT�FOR�THIS�BLOCK2ŠMOVE.L�A3,A1ŽSAVE�POTENTIAL�START�OF�AVAIL.�BLOCKŠBSR.S‚CHKBITS$ŠBCS.S‚DSAL90�NOT�START�OF�NEW�BLOCKDSAL84„CMP.L‚D3,D5ŠBLS„DSAL25�SPACE�FOUND!ŠBSR.S‚NXTBIT�GET�NEXT�SECTOR�BIT ŠBNE.S‚DSAL86ŠBSR.S‚CHKBITS ŠBCS.S‚DSAL86 ŠBRA.S‚DSAL84,*DON'T GO ON IF AT END OF BLOCK OR I/O ERRORDSAL86„TST.B‚D0*ŠBNE„DSAL41�GO�LOOK�FOR�SPACE�AT�BEGINNINGDSAL90„BSR.S‚NXTBIT ŠBEQ.S‚DSAL82*ŠBRA„DSAL41�GO�LOOK�FOR�SPACE�AT�BEGINNINGŠPAGE!*NXTBIT 1.00 6/18/78 L. STEINHOFF*+*NXTBIT SETS SECTOR BIT POINTER TO NEXT BIT* *ON CALL:*…A6=VDT�ADDRESS"*…A2=MEMORY�ADDRESS�OF�CURRENT�BIT%*…A3=SECTOR�ADDR�CORRESPONDING�TO�BIT*†D2.L=BIT�NO�FOR�SECTOR-*…D6=LONG�WORD�CORRESPOTODING�IN�MEMORY�ADDR. *…BSR�NXTBIT* *ON RETURN:*…Z=1�IF�NO�ERROR *†=0�IF�ERROR*…D0.B=0�IF�NO�ERROR*‰=ISTAAL�IF�AT�END�OF�SAT*‰=80+�IF�I/O�ERROR*…A6-UNCHANGED,*…A2=A2+4�ONLY�IF�D2.B�WAS�0,�ELSE�UNCHANGED *…A3=A3+1&*…D2.L=31�IF�PASSED�VALUD=0,�ELSE=D2-1:*…D6=LONG�WORD�CORRESPONDING�TO�MEMORY�ADDR.�IF�A2�CHANGED'*…CARRY=0�IF�NOT�AT�END�OF�MEMORY�BLOCK*ˆ=1�IF�NO�MORE�BITS�TO�CHECK* NXTBIT„EQU„*!ŠADD.L‚#1,A3ŽINCREMENT�SECTOR�NO.ŠTST.B‚D2‘BIT�NO.=0?ŠBNE.S‚NXTB20�NOŠMOVE.L�D6,(A2)ŒSAVE�LONG�WORDŠTST.L‚(A2)+ŽPOINT�TO�NEXT�WORD*ŠCMP.L‚VDTSMD(A6),A2†BEYOND�END�OF�MEMORY?ŠBLS.S‚NXTB10�NO(*YES-SEE IF ANOTHER SECTOR IN SAT EXISTSŠMOVE.L�A1,-(A7)‹SAVE�A1!ŠMOVE.L�A3,A1ŽA1=REQUESTED�SECTOR ŠBSR„CALBITŠMOVE.L�(A7)+,A1ŠRTSNXTB10„MOVE.L�#31,D2�BIT�NO=31 ŠMOVE.L�(A2),D6ŒGET�DATA�IN�REG.NXTB15„CLR.L‚D0ŠRTS#NXTB20„SUB.B‚#1,D2ŽBIT�NO=�BIT�NO-1 ŠBRA.S‚NXTB15ŠPAGE3*CHKBITS�CHECKS�FOR�AVAILABLE�BIT�IN�SAT.‚IF�BIT�ISA*…ON�LONG�WORD�BOUNDARY�AND�32�BITS�ARE�0,�THEY�ARE�ALL�RETURNED.*…SAME�IF�WORD�OR�BYTE�BOUNADRY6*A NOT FOUND RETURN CAN BE MADE FOR MULITPLE BITS ALSO* *ON CALL: *…A2=MEMORY�ADDR.�OF�CURRENT�BIT-*…A3=PSN�CORRESPOONDING�TO�BIT�(NOT�IF�CALLED-*ˆFROM�ATTEMPT�TO�ALLOOATE�AT�SPECIFI�ADDR.))*…A6=VDT�ADDR.!*†D2=BIT�NO.�CORRESPONDING�TO�PSN(*…D3=NO.�OF�CONTIGUOUS�AVAILABLE�SECTORS.*…D6=LONG�WORD�AT�MEMORY�LOC.�POINTED�TO�BY�A2* *ON RETURN:%*…CARRY=0�IF�BIT=0�(SECTOR�AVAILABLE) *…CARRY=1�IF�BIT=1�(UNAVAILABLE)*†A2=UNCHANGED8*…A3=PSN�CORRESPONDING�TO�LAST�BIT�OF�GROUP(32,16,�OR�8)*…A6=UNCHANGED+*…D2=BIT�CORRESPONDING�TO�LAST�BIT�OF�GROUP&*…D3=D3+NO.�OF�AVAILABLE�SECTORS�FOUND*…D6=UNCHANGED CHKBITSƒEQU„*(ŠCMP.B‚#31,D2�AT�BEGINNING�OF�LONG�WORD?ŠBNE.S‚CHKB30�NO *YES-SEE IF 32 SECTORS AVAILABLE ŠTST.L‚D6 ŠBEQ.S‚CHKB108*IF ENTIRE 32 BITS IS UNAVAILABLE, MAKE NOT FOUND RETURN*…BPUT�POINT�TO�BIT�0ŠCMP.L‚#$FFFFFFFF,D6ŠBNE.S‚CHKB50�NOT�ALL�UNAVIL.*32, 16, OR 8 BITS UNAVAIL.#CHKB05„ADD.L‚D2,A3ŽSET�TO�BIT�0�PSNŠCLR.L‚D2‘SET�FOR�BIT�0ŠBRA.S‚CHKBER�MAKE�ERROR1*YES-UPDATE COUNTS BASED ON 32 OR 16 OR 8 SECTORSCHKB10„ADD.L‚D2,D3+ŠADD.L‚D2,A3ŽSET�A3�TO�CORRESPOIND�TO�BIT�0ŠCLR.L‚D2‘SET�BIT�NO.�TO0#CHKBRT„ADD.L‚#1,D3ŽD3=D3+32�(OR�16)ŠAND.B‚#$FE,SRŒMAKE�GOOD�RETURNŠRTS*SEE IF AT BEGGINING OF WORDCHKB30„CMP.B‚#15,D2"ŠBNE.S‚CHKB40�NOT�ON�WORD�BOUNDARYŠTST.W‚D6‘16�SECTORS�AVAILABLE?ŠBEQ.S‚CHKB10�YES%ŠCMP.W‚#$FFFF,D6ŠALL�16�BITS�UNAVAIL?ŠBEQ.S‚CHKB05�YES ŠBRA.S‚CHKB50*SEE IF AT BEGINNING OF BYTECHKB40„CMP.B‚#7,D2ŠBNE.S‚CHKB50�NOŠTST.B‚D6‘8�SECTORS�AVAILABLE?ŠBEQ.S‚CHKB10�YESŠCMP.B‚#$FF,D6Œ8�BITS�UNAVAIL.?ŠBEQ.S‚CHKB05�YES-*NOT ON LONG WORD, WORD, OR LOW BYTE BOUNADRY*…MUST�CHECK�BITCHKB50„BTSTW‚D2,D6 ŠBEQ.S‚CHKBRTCHKBER„OR.Bƒ#1,SRŠRTSŠPAGE!*DSDEAL 1.00 6/19/79 L. STEINHOFF*.*DSDEAL DEALLOCATES THE REQUESTED SECTOR BLOCK* *ON CALL: *…A6=VDT�ADDRESS&*„A1=SECTOR�STARTING�ADDRESS�FOR�BLOCK*…A4=FAT�ADDR.�(=0�IF�NONE)*…D1=LENGTH�OF�SEGMENT *…BSR�DSDEAL* *ON RETURN:*…A6=UNCHANGED*…A1,D1=ALTERED*…D0.L=0�IF�NO�ERROR-*‰=ISTAAL�IF�FILE�SPACE�DEALLOCATION�CONFLICT3*Œ(D1=0�OR�SECTORS�BEING�DE-ALLOCATED�NOT�IN�RANGE)*ˆ=80+�IF�I/O�ERROR*/*DSDEAL MAKES SURE SECTOR BLOCK PASSED IS VALID9*…FOR�DISK�(BASED�ON�DCB�INFO.).‚IF�NO�ERROR�IS�DETECTED,B*†THE�CORRESPONDING�BITS�ARE�CLEARED�AND�THE�SAT�MARKED�AS�CHANGED0*‡IF�THE�SECTOR�RANGE�IS�INVALID,�THE�SAT�IS�NOT *…EFFECTED**INITIALLY SAT IS ONLY 1 SECTOR**INDENTED LIST;* DSDEAL DEALLOCATES REQUESTED NUMBER OF SEQUENTIAL SECTORS!*DSDEAL PASS-PSN AND-SECTOR COUNT* FIND AND-MARK SECTORS' BITS*‚CALL�$CALBIT,�$NXTBIT* RETURN*INDENTED LIST END* DSDEAL„EQU„*ŠMOVEM.L�D2/D6/A2-A3,-(A7)+*MAKE SURE SECTOR RANGE IS VALID FOR DEVICE#ŠMOVE.L�VDTDCB(A6),A2†GET�DCB�ADDR.ŠCMP.L‚DCBSEC(A2),A1!ŠBCS.S‚DSDE08�STARTING�ADDR.�OKAY5DSDE05„MOVE.L�#NL+ISTAAL,D0†MAKE�INVALID�SECTOR�RANGEŠBRA.S‚DSDERT�RETURNDSDE08„MOVE.L�A1,A3 ŠADD.L‚D1,A3ŽGET�ENDING�SECTOR+1'ŠCMP.L‚DCBSEC(A2),A3†MAKE�SURE�IN�RANGEŠBHI.S‚DSDE05�ERROR ŠTST.L‚D1ŠBEQ.S‚DSDE05�ERROR-LENGTH=0E*CONVERT SECTOR ADDRESS TO OFFSET/BIT AND READ SAT SECTOR INTO MEMORY ŠBSR„CALBIT ŠBEQ.S‚DSDE152DSDERT„MOVEM.L�(A7)+,A2-A3/D2/D6�MAKE�ERROR�RETURNŠRTS#*NOW CLEAR BITS FOR BLOCK SPECIFIEDDSDE15„BCLRƒD2,D6.ŠBSETW‚#VDFLSB,VDTFLG(A6)�INDICATE�SAT�CHANGED ŠSUB.L‚#1,D1ŠBEQ.S‚DSDE25�ALL�DONEŠBSR„NXTBIT�POINT�TO�NEXT�BIT ŠBNE.S‚DSDERT ŠBRA.S‚DSDE15DSDE25„MOVE.L�D6,(A2)ŠCLR.L‚D0‘INDICATE�NO�ERRORŠBRA.S‚DSDERT�AND�RETURNŠPAGE!*GETSAT 1.00 6/15/79 L. STEINHOFF*+*GETSAT READS THE REQUESTED SAT INTO MEMORY*IF REQUESTED BLOCK IS'*ALREADY IN MEMORY, NO I/O IS PERFORMED1*IF I/O ERROR OCCURS, BLOCK IN MEMORY IS SET TO 0 *ON CALL:*…A6=ADDRESS�OF�VDT�ENTRY#*…A1=ADDRESS�OF�REQUESTED�SAT�BLOCK *…BSR�GETSAT* *ON RETURN:*…A6=UNCHANGED*…A1=UNCHANGED*…D0.L=0�IF�NO�ERROR*‡DO.B=80+�IF�I/O�ERROR*…Z=1�IF�NO�ERROR *†=0�IF�ERROR* GETSAT„EQU„*ŠMOVE.L�A0,-(A7)‹SAVE�REGISTER(ŠCMP.L‚VDTSMB(A6),A1†IS�BLOCK�IN�MEMORY?ŠBEQ.S‚GETS20�YES&*READ REQUESTED SAT INTO MEMORY BUFFER9ŠBSR.S‚PUTSATŒUPDATE�CURRENT�SAT�ON�DISK�FIRST�IF�CHANGEDŠBNE.S‚GETS30�IO�ERRORŠMOVE.L�A1,D0ŽSET�UP�PSN4ŠCLR.L‚VDTSMB(A6)‰0�BLOCK�IN�MEMORY�UNTIL�AFTER�READBŠSETFO‚IOREAD,IOPRAN+IOPIMG+IOPWAT,VDTIOS(A6)�SET�FUNCTION,OPTIONSŠBSR.S‚GPTSAT�READ�BLOCK�IN ŠBNE.S‚GETS30�DISK�ERROR�ON�READ&ŠMOVE.L�A1,VDTSMB(A6)†SAVE�SAT�ADDRESS&GETS20„CLR.L‚D0‘RESTORE�CONDITION�CODE'GETS30„MOVE.L�(A7)+,A0‹RESTORE�REGISTERŠRTS**GPTSAT„MOVE.L�D0,VDTIOS+IOSRRN(A6)�SET�PSN5ŠMOVE.L�VDTSMA(A6),VDTIOS+IOSSAD(A6)�STARTING�ADDRESS3ŠMOVE.L�VDTSME(A6),VDTIOS+IOSEAD(A6)�ENDING�ADDRESS ŠBSR„DOIO2ŠRTSŠPAGE!*PUTSAT 1.00 6/15/79 L. STEINHOFF*2*PUTSAT WRITES THE SAT CURRENTLY IN MEMORY TO DISKA*IF NO BLOCK IN MEMORY OR CHANGE FLAG NOT SET, REQUEST IS IGNORED* *ON CALL:*…A6=ADDRESS�OF�VDT�ENTRY *…BSR�PUTSAT* *ON RETURN:*…A6=UNCHANGED*…D0.L=0�IF�NO�ERROR*ˆD0.B=8O+�IF�I/O�ERROR3*ˆ=ISTAIE�IF�CHANGE�FLAG�SET�BUT�NO�BLOCK�IN�MEMORY*ˆZ=1�IF�NO�ERROR *ˆ=0�IF�ERROR* *REGISTERS USED: 0 1 2 3 4 5 6 7*ŠD*ŠA…P*&*PUTSAT USES INFORMATION IN VDT PASSED*G*COMMENTS INITIALLY SAT IS ONLY 1 SECTOR SO PUTSAT DOESNT HAVE TO WORRY$*…ABOUT�VARIABLE�SECTOR�BLOCK�UPDATE* PUTSAT„EQU„*ŠMOVE.L�A0,-(A7)‹SAVE�REGISTER$ŠCLR.L‚D0‘CLEAR�IN�CASE�CALL�IGNORED*ŠBTSTW‚#VDFLSB,VDTFLG(A6)�CHANGE�FLAG�SET?ŠBEQ.S‚PUTS20�NO,�IGNORE�CALL$ŠMOVE.L�VDTSMB(A6),D0†SAT�IN�MEMORY?ŠBNE.S‚PUTSIE.1‹YES,�OKŠBSR„ISTAIERR‹NO,�ERRORŠBRA.S‚PUTS20�ERROR�RETURN*SET UP TO WRITE SAT TO DISK%*DO WRITE WITH WAIT FOR RANDOM, IMAGE5PUTSIE.1‚SETFO‚IOWRIT,IOPRAN+IOPIMG+IOPWAT,VDTIOS(A6)ŠBSR.S‚GPTSAT�WRITE�SAT!ŠBNE.S‚PUTS20�ERROR�FROM�I/O�CALL+ŠBCLRW‚#VDFLSB,VDTFLG(A6)�CLEAR�CHANGE�FLAG ŠTST.L‚D0PUTS20„MOVE.L�(A7)+,A0ŠRTSŠPAGE* !*GETVID 1.00 6/28/79 L. STEINHOFF*,*GETVID READS VID FROM DISK AND MOVES TO VDT* *ON CALL:*…A6=ADDRESS�OF�VDT�ENTRY *…BSR�GETVID* *ON RETURN:*…Z=1�IF�NO�ERROR *†=0�IF�ERROR*…A6=UNCHANGED*…D0.L=0�IF�NO�ERROR*…D0.B=80+�IF�I/O�ERROR/*‰=FSTAVOL�IF�FOREIGN�DISK�OR�DUPLICATE�OR�0�OR!*�SPACES�VOLUME�ID�(VOLUME�ERROR)*0*GETVID READS VID INTO FMS BUFFER AND THEN MOVES*…DATA�TO�VDT�UNLESS�ERROR(*…IF�ERROR,�VOLUME�ID�IN�VDT�IS�SET�TO�0* GETVID„EQU„*&ŠMOVEM.L�D1/A0-A2,-(A7)„SAVE�REGISTERS.*SET UP TO DO READ WITH WAIT FOR RANDOM, IMAGE ŠMOVE.L�#VIDDA,D0ŠSECTOR�TO�READŠMOVE.L�#IOREAD,D1‰READ4ŠBSR.S‚GPTSEC�READ�IN�SECTOR�TO�TEMPORARY�VIB�BUFFERA*�Note�the�following�clear�instruction�must�follow�the�BSR‚GPTSECC*ƒin�order�to�avoid�clearing�the�VID�and�then�responding�to�anotherD*ƒevent�prior�to�coming�back�from�GPTSEC.‚This�instruction�was�movedB*ƒon�10/11/83�by�SCB.‚to�solve�a�problem�of�mounting�two�diskettesE*ƒwith�the�same�volume�ID�and�having�the�1st�one�mounted�becoming�the.*ƒforeign�disk�instead�of�the�2nd�one�mounted.5ŠCLR.L‚VDTVID+VIDVOL(A6)‚0�VOLUME�ID�IN�CASE�OF�ERROR"* A1 POINTS TO SECTOR JUST READ IN.ŠTST.B‚D0‘Test�I/O�return�status�10/11/83�SCB.!ŠBNE.S‚GETVRT�RETURN�IF�I/O�ERROR1*DETERMINE IF VOLUME ID CONTAINS MACSS INIT. DATAŠCMP.L‚#MACSCDE1,VIDMAC(A1)ŠBNE.S‚GETV20�FOREIGN�DISKŠCMP.L‚#MACSCDE2,VIDMAC+4(A1)ŠBNE.S‚GETV20�FOREIGN�DISK*SEE IF VOLUME ID IS VALID#ŠMOVE.L�VIDVOL(A1),D0†GET�VOLUME�IDŠBEQ.S‚GETV20�ERROR�SINCE�ID=0ŠCMP.L‚#'„',D0#ŠBEQ.S‚GETV20�ERROR�SINCE�ID=SPACES%*ERROR IF VOLUME ID=ANOTHER VOLUME ID$*…OR�=�RANDOM�ACCESS�DEVICE�MNEMONICŠMOVE.L�VDTSTR,A0!GETV05„CMP.L‚VDTVID+VIDVOL(A0),D0ŠBEQ.S‚GETV20�DUPLICATE-ERROR#ŠMOVE.L�VDTDCB(A6),A2†GET�DCB�ADDR.)ŠCMP.L‚DCBAID(A2),D0†DEVICE�ID=VOLUME�ID?ŠBEQ.S‚GETV20�YES-ERROR!ŠLEA„VDTLEN(A0),A0†GET�NEXT�ENTRYŠCMP.L‚VDTEND,A0ŠDONE?ŠBLS.S‚GETV05�NO*VOLUME ID LOOKS GOOD*MOVE VID TO VDTŠLEA„VDTVID(A6),A0)ŠMOVE.L�#VIDEOD/2,D0‡NO.�OF�BYTES�TO�MOVEGETV10„MOVE.W�(A1)+,(A0)+ŠDCNTƒD0,GETV10ŠCLR.L‚D0‘SET�GOOD�RETURN�FLAGS/GETVRT„MOVEM.L�(A7)+,D1/A0-A2„RESTORE�REGISTERSŠRTS$GETV20„MOVE.L�#FSTAVOL,D0ˆVOL.�ERROR ŠBRA.S‚GETVRTŠPAGE*&*ˆ**************************************ŒGPTSEC‚1.00‚10/15/79‚HBN6*&*ˆ*************************************?*‚GPTSEC�READS/WRITES�ONE�SECTOR�FROM/TO�DISK�FOR�TEMPORARY�USE%*ˆTEMPORARY�VIB-SECTOR-BUFFER�IS�USED* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆD0�=�PSN�OF�SECTOR�TO�BE�READ'*ˆD1�=�IOS�COMMAND�CODE�(READ�OR�WRITE)* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD1�-�UNKNOWN*ˆA1�=�TEMPORARY�BUFFER�ADDR.*ˆD0.L�=�0�IF�NO�ERROR"*ˆD0.B�=�80+�IF�ERROR�FROM�IO�CALL*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR4*VDTFLG-VDFLTB SET TO INDICATE TEMPORARY BUFFER USED* GPTSEC„EQU„**ŠMOVE.L�A0,-(A7)‹SAVE�REGISTERS4ŠBSETW‚#VDFLTB,VDTFLG(A6)�SET�TEMP.�BUFFER�USED�FLAGŠMOVE.L�VDTTMA(A6),A0ŠMOVE.L�VDTTME(A6),A19ŠSETRFO�D1,IOPIMG+IOPRAN,VDTIOS(A6)�SET�FUNCTION,�OPTIONS4ŠSETSBA�D0,A0,A1,VDTIOS(A6)�PSN,BUFFER�START�AND�ENDŠMOVE.L�A0,A1ŽRETURN�A1 ŠBSR„DOIO"ŠMOVE.L�(A7)+,A0‹RESTORE�REGISTERSŠRTSŠPAGE!*PUTVID 1.00 6/28/79 L. STEINHOFF**PUTVID UPDATES VID ON DISK* *ON CALL:*…A6=ADDRESS�OF�VDT�ENTRY *…BSR�PUTVID* *ON RETURN:*…Z=1�IF�NO�ERROR *†=0�IF�ERROR*…A6=UNCHANGED*…D0.L=0�IF�NO�ERROR*ˆD0.B=80+�IF�I/O�ERROR*D*PUTVID READS VID INTO TEMP BUFFER AND THEN MOVES FMS DATA TO BUFFER*…AND�WRITES�TO�DISK* PUTVID„EQU„*&ŠMOVEM.L�A0-A1/D1,-(A7)„SAVE�REGISTERS>*READ VID INTO TEMPORARY BUFFER AND THEN OVERLAY WITH FMS DATAŠMOVE.L�#VIDDA,D0ŠMOVE.L�#IOREAD,D13ŠBSR„GPTSEC�A1�RETURNS�POINTING�TO�SECTOR�JUST�READ ŠBNE.S‚PUTV20ŠLEA„VDTVID(A6),A1ŠMOVE.L�VDTTMA(A6),A0)ŠMOVE.L�#VIDEOD/2,D0‡NO.�OF�BYTES�TO�MOVEPUTV10„MOVE.W�(A1)+,(A0)+ˆSAVEŠDCNTƒD0,PUTV10*MUST CALCULATE CHECKSUM"ŠMOVE.L�VDTTMA(A6),A0†START�OF�VIDŠMOVE.L�VDTTME(A6),A1†ENDŠCLR.W‚VIDCHK(A0)‰ZERO�CHECKSUMŠMOVE.L�#$FFFFFFFF,D0PUTV15„MOVE.B�(A0)+,D1  ŠEOR.B‚D1,D0ŠSWAPƒD0ŠMOVE.B�(A0)+,D1 ŠEOR.B‚D1,D0ŠSWAPƒD0ŠCMP.L‚A1,A0ŽDONE�ALL�BYTES?ŠBLS.S‚PUTV15�NO'ŠMOVE.L�VDTTMA(A6),A0†YES-SAVE�CHECKSUMŠMOVE.B�D0,VIDCHK(A0)ŠSWAPƒD0ŠMOVE.B�D0,VIDCHK+1(A0)A*DATA IS NOW IN VID BUFFER WITH UNUSED PORTION ZERO-WRITE TO DISK"ŠMOVE.L�#VIDDA,D0ŠWRITE�VID�SECTOR%*DO WRITE WITH WAIT FOR RANDOM, IMAGEŠMOVE.L�#IOWRIT,D1‰WRITEŠBSR.S‚GPTSEC�WRITE/PUTV20„MOVEM.L�(A7)+,A0-A1/D1„RESTORE�REGISTERSŠRTSŠPAGE* *DSNME 1.00 6/25/79 L. STEINHOFF*?*DSNME SEARCHES THE DIRECTORIES FOR THE REQUESTED FILE NAME; IF4*FOUND ITS DIRECTORY ENTRY INFO. IS RETURNED ELSE AN *ERROR OCCURS* *ON CALL:*„A6=�VDT�ADDRESS*„A2=�ADDRESS�OF�FCB-LIKE�BLOCK*…A4=FAT�ADDR.�(=0�IF�NONE) *„BSR�DSNME* *ON RETURN:*„Z=1�IF�NO�ERROR *…=0�IF�ERROR*„D0.L=0�IF�NAME�FOUND(*ˆD0.B=FSTANNM�IF�NON-EXISTENT�FILE�NAME*ˆ=80+�IF�IO�ERROR7*ALL�OTHER�REGISTERS�ARE�PRESERVED�UNLESS�A�"NOT‚FOUND"D*RETURN IS MADE; IN THAT CASE, THE FOLLOWING REGISTERS ARE RETURNED:*D*„D6=PSN�OF�FIRST�PRIMARY�DIRECTORY�BLOCK�WITH�EMPTY�SLOT�IF�CATALOG@*†=PSN�OF�1ST�SECONDARY�DIR.�BLOCK�WITH�EMPTY�SLOT�IF�NO�CATALOG*†=0�IF�NONE�OF�THE�ABOVE:*„D7=PSN�OF�LAST�PRIMARY�DIRECTORY�BLOCK�IF�CATALOG�EXISTS7*†=PSN�OF�LAST�SECONDARY�DIR�BLOCK�IF�NO�CATALOG�EXISTS*†=0�IF�NONE�OF�THE�ABOVE*„D1.W=OFFSET�OF�EMPTY�SLOTB*„D1�BITS�31-16�=�0�IF�CATALOG�FOUND�BUT�FILE�NAME�NOT(D0=FSTANNM)-*�=�-1�IF�NO�CATALOG�ENTRY�EXISTS(D0=FSTANNM)*0*THE FOLLOWING INFORMATION IS PASSED IN THE FCB:*„VDT�ENTRY�ADDRESS *„USER�NO.*„CATALOG�NAME *„FILE�NAME *„EXTENSION1*THE FOLLOWING INFORMATION IS RETURNED IN THE FCB*„ALL�DIRECTORY�INFO.*„SECONDARY�DIR.�DISK�ADDRESS*„SECONDARY�DIR.�BLOCK�OFFSET*„DIR�BLOCK�DISK�ADDRESS*„DIR.�BLOCK�OFFSET**INDENTED LIST(* DSNME SEARCHES FOR REQUESTED FILE NAME*DSNME PASS-FILE NAME-IN FCB* FIND CATALOG#*‚SECONDARY�DIR-SEARCH�CALL�$GETSDB* FIND FILE NAME *‚PRIMARY�DIR-SEARCH�CALL�$GETDB * FILE FOUND?!*‚NO,�RETURN-1ST�EMPTY-SLOT�FOUND*‚YES,�RETURN�DIRECTORY�ENTRY*INDENTED LIST END* DSNME…EQU„**/ŠMOVEM.L�A0/A1/A3/A5/D2-D5,-(A7)�SAVE�REGISTERSŠMOVEM.L�D6-D7/D1,-(A7)*'*ˆINITIALIZE�NOT�FOUND�RETURN�REGISTERS* ŠCLR.L‚D1 ŠCLR.L‚D6 ŠCLR.L‚D77ŠMOVE.L�VDTVID+VIDSDS(A6),D0�ARE�THERE�ANY�DIR.�BLOCKS?ŠBNE.S‚DSNM10�YES*;*ˆNO�SECONDARY�DIRECTORY�BLOCKS�EXIST-MAKE�NOT�FOUND�RETURN*DDSNMNC„MOVE.W�D1,D0ˆSET�D1�=�'-1,�OFFSET'�FOR�NO�CATALOG�ENTRY�FOUND ŠCLR.L‚D1‘.ŠSUB.L‚#1,D1Ž.ŠMOVE.W�D0,D1Ž.5DSNMNF„LEA„12(A7),A7ŠREMOVE�SAVED�D6,D7+D1�FROM�STACKŠMOVE.L�#FSTANNM,D04DSNMRT„MOVEM.L�(A7)+,D2-D5/A1/A3/A5/A0�RESTORE�REGS.ŠRTS*-*ˆSEARCH�FOR�USER�#/CATALOG�NAME�IN�SDB�CHAIN*DSNM10„CLR.L‚D4‘CLEAR�FLAGS ŠCLR.L‚D5$ŠMOVE.L�VDTSDA(A6),A0†SDB�BUFFER�FWA&ŠMOVE.L�VDTSDB(A6),D2†A�SDB�IN�MEMORY?%ŠBEQ.S‚DSNM20�NO,�GO�GET�FIRST�ONE�IN(ŠCMP.L‚D2,D0ŽIS�CURRENT�SDB�THE�1ST�ONE?@ŠBEQ.S‚DSNM25…YES,�D4=0�AS�A�FLAG�FOR�SEARCH�BEGINS�FROM�1ST�SDBBŠMOVE.L�D2,D5„SAVE�CURRENT�SBD'S�PSN�TO�SKIP�IT�LATER�IF�NECESSARY$ŠMOVE.L�(A0),A3ŒAND�SAVE�IT�(SDBFPT)CŠSUB.L‚#1,D4‚SET�FLAG�FOR�SEARCH�STARTS�IN�THE�MIDDLE�OF�THE�CHAINN ŠBRA.S‚DSNM255DSNM20„MOVE.L�D0,A1ŽGET�THE�REQUESTED�SDB�INTO�MEMORYDSNM21„BSR„GETSDBŠBNE„DSNMER�IO�ERROR1DSNM25„MOVE.L�#SDBSTR-SDBLEN,D0‚INITIALIZE�OFFSET)DSNM30„ADD.W‚#SDBLEN,D0‰NEXT�ENTRY�OFFSET%ŠLEA„0(A0,D0),A1ˆA1�->�NEXT�SDB�ENTRY%ŠCMP.L‚VDTSDE(A6),A1†END�OF�THIS�SDB?ŠBCC.S‚DSNM40�YESŠTST.L‚SDBPDP(A1)‰EMPTY�ENTRY?ŠBEQ.S‚DSNM55�YES�-�SKIP1ŠMOVE.L�#(USNLEN+CLGLEN)/2,D2�WORD�COUNT�TO�MATCH?ŠLEA„FCBSDB+SDBUSN(A2),A5�A5�->�USER�#/CATALOG�NAME�TO�BE�FOUND ŠIFNEƒSDBUSN:ŠADD.L‚#SDBUSN,A1‰A1->USER�#/CATALOG�NAME�IN�CURRENT�ENTRYŠENDC DSNM35„CMPM.W�(A1)+,(A5)+ˆMATCH?ŠBNE.S‚DSNM30�NOŠDCNTƒD2,DSNM35**ˆFOUND�CATALOG�ENTRY�FOR�FILE*5ŠMOVE.L�VDTSDB(A6),FCBSDBP(A2)�SAVE�CATALOG'S�SDB�PSN9ŠMOVE.W�D0,FCBSDBO(A2)…SAVE�OFFSET�OF�CATALOG�ENTRY�FOUNDAŠCLR.L‚D1„RESET�NOT�FOUND�REGISTERS�FOR�NO-FILE-NAME-FOUND�RETURN  ŠCLR.L‚D6 ŠCLR.L‚D73ŠBRA.S‚DSNM60�GO�SEARCH�PDB�CHAIN�FOR�THE�FILE�NAME**ˆSET�UP�TO�SEARCH�NEXT�SDB*:DSNM40„TST.L‚D4‘SEARCH�STARTED�IN�MIDDLE�OF�THE�SDB�CHAIN?ŠBNE.S‚DSNM45�YES4DSNM41„MOVE.L�(A0),D0ŒNO,�END�OF�SDB�CHAIN?�(SDBFPT))ŠBEQ.S‚DSNM48�YES,�NO�CATALOG�ENTRY�FOUND ŠBRA.S‚DSNM20�GO�SEARCH�NEXT�SDB*…IF�REQUESTED�BLOCK�IS�ALREADY�IN�MEMORY,�NO�I/O�IS�PERFORMED8*…UPDATE�DIR�BLOCK�CURRENTLY�IN�MEMORY�IF�IT�HAS�CHANGED2*…IF�I/O�ERROR�OCCURS,�BLOCK�IN�MEMORY�IS�SET�TO�0* *ON CALL:*…A6=ADDRESS�OF�VDT�ENTRY$*…A1=ADDRESS�OF�REQUESTED�DIR.�BLOCK *…BSR�GETDB* *ON RETURN:*…A6=UNCHANGED*…A1=UNCHANGED*…D0.L=0�IF�NO�ERROR*ˆD0.B=80+�IF�I/O�ERROR*…Z=1�IF�NO�ERROR *†=0�IF�ERROR** GETDB USES VDT* GETDB…EQU„*ŠMOVE.L�A0,-(A7)‹SAVE�REGISTER(ŠCMP.L‚VDTDMB(A6),A1†IS�BLOCK�IN�MEMORY?ŠBEQ.S‚GETD20�YES&*READ REQUESTED DIR INTO MEMORY BUFFER*,*UPDATE BLOCK IN MEMORY ON DISK IF NECESSARY ŠBSR.S‚PUTDB ŠBNE.S‚GETD30ŠMOVE.L�A1,D0ŽSET�UP�PSN+*SET UP TO DO READ WITH WAIT, RANDOM, IMAGE-ŠSETFO‚IOREAD,IOPRAN+IOPIMG+IOPWAT,VDTIOS(A6)4ŠCLR.L‚VDTDMB(A6)‰0�BLOCK�IN�MEMORY�UNTIL�AFTER�READŠBSR.S‚GPTDBŽREAD ŠBNE.S‚GETD30�DISK�ERROR�ON�READ'ŠMOVE.L�A1,VDTDMB(A6)†SAVE�DIR.�ADDRESS%GETD20„CLR.L‚D0‘RESTORE�CONDITON�CODE'GETD30„MOVE.L�(A7)+,A0‹RESTORE�REGISTERŠRTS*%GPTDB…MOVE.L�D0,VDTIOS+IOSRRN(A6)�PSN5ŠMOVE.L�VDTDMA(A6),VDTIOS+IOSSAD(A6)�STARTING�ADDRESS3ŠMOVE.L�VDTDME(A6),VDTIOS+IOSEAD(A6)�ENDING�ADDRESS ŠBSR„DOIO2ŠRTSŠPAGE *PUTDB 1.00 6/25/79 L. STEINHOFF*8*PUTDB WRITES THE DIR. BLOCK CURRENTLY IN MEMORY TO DISK'*…CALL�IGNORED�IF�BLOCK�HAS�NOT�CHANGED* *ON CALL:*…A6=ADDRESS�OF�VDT�ENTRY *…BSR�PUTDB* *ON RETURN:*…A6=UNCHANGED*…D0.L=0�IF�NO�ERROR6*…D0.B=ISTAIE�IF�NO�BLOCK�IN�MEMORY�BUT�MARKED�CHANGED*ˆ=80+IF�I/O�ERROR*…Z=1�IF�NO�ERROR *†=0�IF�ERROR*%*PUTDB USES INFORMATION IN VDT PASSED* PUTDB…EQU„*ŠMOVE.L�A0,-(A7)‹SAVE�REGISTER!ŠCLR.L‚D0‘CLEAR�IN�CASE�SKIP�CALL/ŠBTSTW‚#VDFLDB,VDTFLG(A6)�DB�IN�MEMORY�CHANGED?ŠBEQ.S‚PUTDRT�NO,ŠMOVE.L�VDTDMB(A6),D0†IS�A�SECTOR�IN�MEMORY?ŠBNE.S‚PUTDB.1ŒYES,�OK!ŠBSR„ISTAIERR‹NO�-�INTERNAL�ERROR ŠBRA.S‚PUTDRT%*DO WRITE WITH WAIT FOR RANDOM, IMAGE4PUTDB.1ƒSETFO‚IOWRIT,IOPIMG+IOPWAT+IOPRAN,VDTIOS(A6)ŠBSR.S‚GPTDBŽWRITE!ŠBNE.S‚PUTDRT�ERROR�FROM�I/O�CALL+ŠBCLRW‚#VDFLDB,VDTFLG(A6)�CLEAR�CHANGE�FLAG ŠTST.L‚D0PUTDRT„MOVE.L�(A7)+,A0ŠRTSŠPAGE*"*ˆ**********************************ŒGETSDB�1.00�8/21/79�HBN6*"*ˆ*********************************<*‚GETSDB�READS�THE�REQUESTED�SECONDARY�DIR�BLOCK�INTO�MEMORY>*ˆIF�REQUESTED�BLOCK�IS�ALREADY�IN�MEMORY,�NO�I/O�IS�PERFORMED>*ˆIF�CURRENT�SDB�MUST�BE�OVERWRITTEN,�IT�IS�UPDATED�ON�DISK�IF *ˆCHANGED9*ˆIF�I/O�ERROR�OCCURS,�PSN�OF�BLOCK�IN�MEMORY�IS�SET�TO�0* *‚ON�CALL:*ˆA6�=�ADDRESS�OF�VDT�ENTRY0*ˆA1�=�ADDRESS�OF�REQUESTED�SECONDARY�DIR.�BLOCK *ˆBSR�GETSDB* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR*ˆD0.B�=�80+�IF�I/O�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR*#*‚GETSDB�REFERENCES�AND�UPDATES�VDT* GETSDB„EQU„**-*ˆRETURN�IF�REQUESTED�BLOCK�ALREADY�IN�MEMORY*ŠMOVE.L�A0,-(A7)‹SAVE�REGISTER(ŠCMP.L‚VDTSDB(A6),A1†IS�BLOCK�IN�MEMORY?ŠBEQ.S‚GTSD10�YES*.*ˆWRITE�PREVIOUS�SDB�TO�DISK�IF�IT�HAS�CHANGED*'ŠBSR.S‚PUTSDB�UPDATE�SDB�AND�ASSOCIATESŠBNE.S‚GTSDRT�ERROR*6*ˆREAD�REQUESTED�SECONDARY�DIRECTORY�BLOCK�INTO�MEMORY*ŠMOVE.L�A1,D0ŽPSN�TO�READ<ŠSETFO‚IOREAD,IOPRAN+IOPIMG+IOPWAT,VDTIOS(A6)�READ�WITH�WAIT$ŠCLR.L‚VDTSDB(A6)‰0�IN�CASE�OF�ERRORŠBSR.S‚GPTSDB�DO�IO�CALL ŠBNE.S‚GTSDRT�DISK�ERROR�ON�READ-ŠMOVE.L�A1,VDTSDB(A6)†SAVE�SECONDARY�DIR.�PSN>SD10„CLR.L‚D0‘RESTORE�CONDITION�CODE'GTSDRT„MOVE.L�(A7)+,A0‹RESTORE�REGISTERŠRTS*1*ˆCOMMON�IO�CALL�SUBROUTINE�FOR�GETSDB�AND�PUTSDB*&GPTSDB„MOVE.L�D0,VDTIOS+IOSRRN(A6)�PSN5ŠMOVE.L�VDTSDA(A6),VDTIOS+IOSSAD(A6)�STARTING�ADDRESS3ŠMOVE.L�VDTSDE(A6),VDTIOS+IOSEAD(A6)�ENDING�ADDRESS ŠBSR„DOIO2ŠRTSŠPAGE*"*ˆ**********************************ŒPUTSDB�1.00�8/21/79�HBN6*"*ˆ*********************************D*‚PUTSDB�WRITES�THE�SECONDARY�DIR.�BLOCK�CURRENTLY�IN�MEMORY�TO�DISK/*ˆCALL�IS�IGNORED�IF�BLOCK�HAS�NOT�BEEN�CHANGED* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS *ˆBSR�PUTSDB* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR 9*ˆD0.B�=�ISTAIE�IF�BLOCK�NOT�IN�MEMORY�BUT�MARKED�CHANGED*�80+IF�I/O�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR*#*‚PUTSDB�REFERENCES�AND�UPDATES�VDT* PUTSDB„EQU„**+*ˆIGNORE�CALL�IF�BLOCK�HAS�NOT�BEEN�CHANGED*ŠMOVE.L�A0,-(A7)‹SAVE�REGISTERS!ŠCLR.L‚D0‘CLEAR�IN�CASE�SKIP�CALLŠBTSTW‚#VDFLCB,VDTFLG(A6)ŠBEQ.S‚PTSDRT�CHANGED?.ŠMOVE.L�VDTSDB(A6),D0†YES,�IS�A�SDB�IN�MEMORY?ŠBNE.S‚PTSD05�YES,�OK!ŠBSR„ISTAIERR‹NO�-�INTERNAL�ERROR ŠBRA.S‚PTSDRT**ˆUPDATE�SDB�ON�DISK*CPTSD05„SETFO‚IOWRIT,IOPIMG+IOPRAN+IOPWAT,VDTIOS(A6)�WRITE�WITH�WAITŠBSR.S‚GPTSDB�WRITE!ŠBNE.S‚PTSDRT�ERROR�FROM�I/O�CALLŠBCLRW‚#VDFLCB,VDTFLG(A6) ŠTST.L‚D0(PTSDRT„MOVE.L�(A7)+,A0‹RESTORE�REGISTERSŠRTSŠPAGE** *ˆ********************************ŒDSNXT�1.00�8/3/79�HBN6* *ˆ********************************0*‚DSNXT�RETRIEVES�THE�NEXT,�OR�FIRST,�ACCESSIBLE/*ˆDIRECTORY�ENTRY.‚AN�END�OF�DIRECTORY‚ERROR�IS+*ˆGIVEN�IF�END�OF�DIRECTORY�IS�ENCOUNTERED.* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA2�=�FCB�ADDRESS*…A4=FAT�ADDR.�(=0�IF�NONE)*ˆD1.W�=�TASK�USER�NUMBER* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR4*ˆD0.B�=�FSTAEOD�IF�END�OF�DIRECTORY�OR�NO�DIRECTORY*�80+�IF�IO�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR***‚DSNXT�REFERENCES�AND�UPDATES�FCB�AND�VDT**INDENTED LIST/* DSNXT RETRIEVES FIRST OR NEXT DIRECTORY ENTRY)*DSNXT-PASS DIR-ENTRY IN-FCB-IF WANT-NEXT* SEARCH FOR CATALOG*‚CALL�$GETSDB,�$MATCH* SEARCH FOR FILE NAME*‚CALL�$GETDB,�$MATCH * FILE FOUND?*‚YES,�RETURN�DIRECTORY�ENTRY*‚NO,�RETURN�END-OF�DIRECTORY*INDENTED LIST END** DSNXT…EQU„***=*ˆSET�FLAGS�FOR�WHICH�USER�NUMBERS�AND�READ�CODES�ARE�ALLOWED*/ŠMOVEM.L�D2-D5/A0/A1/A3/A5,-(A7)�SAVE�REGISTERS6ŠMOVE.W�FCBSDB+SDBUSN(A2),D0�GET�REQUESTED�USER�NUMBERŠCLR.L‚D4‘CLEAR�FLAGŠMOVE.W�D1,D4ŽSAVE�TASK�USER�#$ŠMOVE.L�D4,D1ŽD1.L�=�USER�#�FOR�TASKŠSWAPƒD4%ŠBEQ.S‚DSNX00�SUPERVISOR�-�TASK�#�=�0>ŠCMP.W‚VDTVID+VIDUSN(A6),D1�TASK�USER�#�SAME�AS�VOLUME�USER�#?;ŠBEQ.S‚DSNX00ŠYES,�RETURN�FILES�WITH�USER�#�0�AND�OWN�FILES-ŠMOVE.W�#1,D4ŽTASK�LOOKING�FOR‚ITS�OWN�FILES?ŠCMP.W‚D0,D1Ž.%ŠBEQ.S‚DSNX10�YES,�D4�=�TASK�USER�#,1@ŠMOVE.W�#2,D4†NO,�RETURN�ALL�OWN�FILES�OR�THOSE�WITH�READCODE=0?ŠCMP.W‚#-2,D0�.&ŠBEQ.S‚DSNX10�YES,�D4�=�TASK�USER�#,�2>ŠMOVE.W�#3,D4ˆNO,�ONLY�THOSE�WITH�REQ.�USER�#�AND�READ�CODE�=0 ŠBRA.S‚DSNX05*!DSNX00„EQU„*’CALLER�IS�SUPERVISOR!ŠCMP.W‚#-2,D0�REQUESTS�ANY�FILES?ŠBEQ.S‚DSNX10�YES,�D4=01ŠMOVE.W�#1,D4ŽNO,�ONLY�FILES�FOR�REQ.�USER�NUMBERBDSNX05„SWAPƒD4ˆSET�REQ.�USER�NUMBER�IN�FLAG�INSTEAD�OF�TASK�USER�#ŠMOVE.W�D0,D4Ž.ŠSWAPƒD4*DSNX10„SWAPƒD4‘SWITCH�ORDER�TO�FLAG,USER�#*9*ˆD4�=�0�IF�TO�RETURN�FILES�MATCHING�CATALOG/FILENAME/EXT1*Š0,USER�#�IF�MUST�MATCH�GIVEN�USER�#�OR�USER�#�0**Š1,USER�#�IF�MUST‚MATCH�GIVEN�USER�NUMBER7*Š2,USER�#�IF�MUST‚MATCH�USER�#�OR�FILE'S�READ�CODE�=�07*Š3,USER�#�IF�MUST‚MATCH�USER�#�AND�READ�CODE�MUST�BE�0***ˆFIND�APPROPRIATE�ENTRY�IN�SDB�FOR�USER�#*-ŠMOVE.L�FCBDBP(A2),D0†DIRECTORY�ENTRY�IN�FCB?0ŠBNE.S‚DSNX45�YES,�GO�SEARCH�CATALOG'S�PDB�CHAIN6ŠMOVE.L�VIDSDS+VDTVID(A6),D0�START�SEARCH�FROM�1ST�SDB ŠBEQ„DSNX60�ERROR�-�NO�DIRECTORY�SDB�BUFFER$ŠMOVE.L�VDTSDE(A6),D3†SDB�BUFFER�ENDŠMOVE.L�#2,D5ŽSET�TEST�FLAG ŠSWAPƒD5‘.ŠMOVE.W�D4,D5ŽD5�=�2,USER�#+DSNX25„ADD.W‚#SDBLEN,D2‰NEXT�ENTRY'S�OFFSET%ŠLEA„0(A1,D2),A5ˆA5�->�NEXT�SDB�ENTRYŠCMP.L‚A5,D3ŽEND�OF�SDB? ŠBLS„DSNX95�YES,�GO�TRY�NEXT�SDBŠTST.L‚SDBPDP(A5)‰EMPTY�ENTRY?!ŠBEQ.S‚DSNX25�YES,�TRY�NEXT�ENTRYŠTST.L‚D4‘MATCH�USER�?!ŠBEQ.S‚DSNX35�NO,�RETURN�ANY�FILE+ŠCMP.W‚(A5),D4ŒUSER�NUMBERS�MATCH?�(SDBUSN)ŠBEQ.S‚DSNX35�YES-ŠCMP.L‚D1,D4ŽRETURN�ALSO�FILES�WITH�USER�#�0?ŠBNE.S‚DSNX30�NO %ŠTST.W‚(A5)�YES,�USER�#�=�0?�(SDBUSN)ŠBNE.S‚DSNX25�NOŠBRA.S‚DSNX35�YES,�USER�#�IS�OK*1DSNX30„CMP.L‚D4,D5ŽRETURN�FILES�IF�READ�CODE�=�0?(ŠBNE.S‚DSNX25�NO,�MUST�MATCH�USER�NUMBER*#*ˆUSER�#�IS�OK,�MATCH�CATALOG�NAMES*@DSNX35„LEA„SDBCLG(A1,D2),A5ƒA5�->�SDB�ENTRY'S�CATALOG�NAME�FIELDDŠLEAƒFCBSDB+SDBCLG(A2),A0�RESTORE�A0�TO�POINT�TO�CATALOG�NAME�WANTEDŠMOVE.L�#CLGLEN,D0‰BCT�TO�MATCH ŠBSR„MATCH'ŠBNE.S‚DSNX25�CATALOG�NAMES�DON'T�MATCH8ŠMOVE.L�SDBPDP(A1,D2),D0ƒD0�=�PSN�OF�1ST�PDB�FOR�CATALOG?ŠMOVE.W�D2,FCBSDBO(A2)…SAVE�SDB�BUFFER�OFFSET�FOR�CATALOG�ENTRY***ˆSEARCH�PDB�CHAIN�FOR�FILE�NAME/EXTENSION*>DSNX40„MOVE.W�#DIRSTR-DIRLEN,FCBDBO(A2)�INIT�PDB�BUFFER�OFFSET3DSNX45„MOVE.W�FCBSDBO(A2),D2…CATALOG�ENTRY'S�OFFSET$ŠMOVE.L�VDTSDA(A6),A1†SDB�BUFFER�FWA4ŠMOVE.W�SDBUSN(A1,D2),D5ƒGET�USER�#�FOR�THIS�CATALOG,ŠMOVE.L�D0,A1ŽA1�=�PSN�OF�PDB�TO�SEARCH�NEXTŠBSR„GETDBŽGET�IT�INTO�MEMORYŠBNE„DSNXRT�IO�ERROR*MAKE SURE SDB IS IN MEMORYŠMOVE.L�A1,-(A7)ŠMOVE.L�FCBSDBP(A2),A1 ŠBSR„GETSDBŠMOVE.L�(A7)+,A1 ŠBNE„DSNXRT'ŠMOVE.W�FCBDBO(A2),D2†GET�OFFSET�IN�PDB!ŠMOVE.L�VDTDMA(A6),A3†GET�PDB�FWA-DSNX50„MOVE.L�VDTDME(A6),D3†END�OF‚PDB�BUFFER*!*ˆFIND�NEXT�VALID�DIRECTORY�ENTRY*)ŠADD.W‚#DIRLEN,D2‰D2=OFFSET�TO�NEXT�ENTRY(ŠLEA„0(A3,D2),A5ˆEND�OF�THIS�DB�REACHED?ŠCMP.L‚A5,D3Ž.ŠBHI.S‚DSNX70�NO$ŠMOVE.L�(A3),D0ŒYES,�NEXT�DB�EXISTS?)ŠBNE.S‚DSNX40�YES�-�GO�GET�IT�INTO�MEMORY*&*ˆEND�OF‚PDB�CHAIN�FOR�CURRENT�CATALOG0*ˆSEARCH�FOR�NEXT�USER�NO./CATALOG�IF�APPLICABLE*0*A -2 UER NO. MEANS ANOTHER SDB ENTRY MAY APPLEYŠCMP.W‚#-2,FCBSDB+SDBUSN(A2) ŠBEQ.S‚DSNX65@ŠLEA„FCBSDB+SDBCLG(A2),A1�AN�'*'�MEANS�ANOTHER�CATALOG�MAY�APPLYŠMOVE.L�#CLGLEN,D0,DSNX55„CMP.B‚#'*',(A1)+‰ANY�WILD�CHARACTERS?7ŠBEQ.S‚DSNX65�YES,�GO�SEARCH�SDB�CHAIN�FOR�NEXT�CATALOGŠDCNTƒD0,DSNX552DSNX60„CLR.L‚FCBDBP(A2)‰NO,�END�OF�DIRECTORY�ERROR/ŠCLR.W‚FCBDBO(A2)‰CLEAR�DB�PSN�AND�ENTRY�OFFSET/ŠCLR.L‚FCBSDBP(A2)ˆAND�CLEAR�SDB�PSN�AND�OFFSETŠCLR.W‚FCBSDBO(A2)ˆ."ŠMOVE.L�#FSTAEOD,D0ˆSET�ERROR�CODEŠBRA„DSNXRT�RETURN*9DSNX65„MOVE.W�FCBSDBO(A2),D2…GET�CURRENT�CATALOG'S�OFFSET"ŠMOVE.L�FCBSDBP(A2),D0…AND�ITS�PSN/ŠBRA„DSNX20�GO�LOOK�FOR�NEXT�APPLICABLE�CATALOG*2DSNX70„LEA„DIRFIL(A3,D2),A5ƒVALID�DIRECTORY�ENTRY? ŠTST.B‚(A5)#ŠBEQ.S‚DSNX50�NO,�GO�TRY�NEXT�ENTRY**ˆTEST�FILE�NAME�IS�OK*,ŠLEA„FCBDIR+DIRFIL(A2),A0�A0->REQUESTED�FILE8ŠMOVE.L�#FILLEN,D0‰FILE�NAME�FIELD�LENGTH�TO�BE�SEARCHED ŠBSR.S‚MATCHŠBNE.S‚DSNX50�NO�MATCH**ˆTEST�EXTENSION�IS�OK**ŠMOVE.L�#EXTLEN,D0‰CHECK�EXTENSION�MATCHESŠLEA„FCBDIR+DIREXT(A2),A0ŠLEA„DIREXT(A3,D2),A5 ŠBSR.S‚MATCHDSNX72„BNE.S‚DSNX50�NO�MATCH*#*ˆTEST�FILE�IS�ACCESSIBLE�TO�CALLER*8ŠMOVE.L�D4,D3ŽRETURN�DIR.�ENTRY�REGARDLESS�OF�READ�CODE? ŠSWAPƒD3‘.ŠCMP.W‚#2,D3Ž.ŠBLT.S‚DSNX75�YES,ŠMOVE.B�DIRRCD(A3,D2),D0ƒNO,�IS�READ�CODE�0?$ŠBEQ.S‚DSNX75�YES,�RETURN�DIR.�ENTRY7ŠCMP.W‚#3,D3ŽDID�YOU�HAVE�TO�HAVE�READ�CODE�EQUAL�TO�0?,ŠBEQ„DSNX50�YES,�THEN�THIS�ENTRY�WILL�NOT�DO*ŠCMP.W‚D5,D4ŽRETURN�ALL�CALLER'S�OWN�FILES(ŠBNE„DSNX72�NO�GOOD,�TRY�NEXT�DIR.�ENTRYŠPAGE*(*ˆRETURN�DIRECTORY�ENTRY�TO�CALLER'S�FCB*:DSNX75„MOVE.W�D2,FCBDBO(A2)†SAVE�OFFSET�TO�DIRECTORY�ENTRY!ŠMOVE.L�A1,FCBDBP(A2)†SAVE�DB�PSN0ŠLEA„0(A3,D2),A3ˆA3->DIRECTORY�ENTRY�FOUND�IN‚DB%ŠMOVE.L�#DIRLEN/2,D0‡MOVE�IT�INTO�FCBŠLEA„FCBDIR(A2),A0DSNX80„MOVE.W�(A3)+,(A0)+ŠDCNTƒD0,DSNX80FŠCMP.W�D4,D1�LEAVE�WRITE�CODE�ONLY�FOR�FILE/VOLUME�OWNER�OR�SUPERVISOR ŠBEQ.S‚DSNX85ŠTST.W‚D1‘SUPERVISOR?ŠBEQ.S‚DSNX85�YES1ŠMOVE.B�#-1,FCBDIR+DIRWCD(A2)�MASK�OFF�WRITE�CODE=DSNX85„MOVE.L�VDTSDA(A6),A1†ALSO�RETURN�USER�#�&�CATALOG�NAMEŠMOVE.W�FCBSDBO(A2),D06ŠLEA„SDBUSN(A1,D0),A1ƒA1�->�USER�#,�CATALOG�NAME�FIELD)ŠMOVE.L�#(SDBFLN)/2,D0…WORD�COUNT�TO�MOVEŠLEA„FCBSDB(A2),A3†MOVE-TO�ADRDSNX90„MOVE.W�(A1)+,(A3)+ŠDCNTƒD0,DSNX90ŠCLR.L‚D0‘SET�GOOD�RETURN�FLAGS8DSNXRT„MOVEM.L�(A7)+,D2-D5/A0/A1/A3/A5�RESTORE�REGISTERSŠRTS/DSNX95„MOVE.L�(A1),D0ŒNEXT�SBD�EXISTS?�(SDBFPT)ŠBNE„DSNX15�YES,�GO�GET�IT(ŠBRA„DSNX60�NO,�END�OF�DIRECTORY�REACHED* * DSNXT SUBROUTINE*<* MATCH - STRING MATCH SUBROUTINE WITH '*' MATCHING ANYTHING** ENT: D0 = BCT TO MATCH?*†A0�->�FIELD�TO�BE�MATCHED,�AN�'*'�=>�ANY�CHARACTER�WILL�MATCH*†A5�->�2ND�FIELD�FOR�MATCH** RET: D0,A0,A5 UNKNOWN*†Z�=�1�IF�MATCH*Š0�IF�NO�MATCH* MATCH…EQU„*ŠCMPM.B�(A0)+,(A5)+ ŠBEQ.S‚MATCH1"ŠCMP.B‚#'*',-1(A0)ˆMATCH�ANYTHING?ŠBNE.S‚MATCH2�NO,�NO�MATCHMATCH1„DCNTƒD0,MATCHŠCLR.L‚D0‘SET�EQUAL�FLAGS MATCH2„RTS*ŠPAGE*!*ˆ*********************************ŒDIRDEL�1.00�8/6/79�HBN6*!*ˆ********************************@*‚DIRDEL�DELETES�A�DIRECTORY�ENTRY�AND�OPTIONALLY�ALL�FILE�SPACE*‰ALLOCATED�TO�THE�FILE. *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS-*ˆD0�=�0�IF�FILE�SPACE�DEALLOCATION�REQUESTED5*�1�IF�DELETE�DIRECTORY�ENTRY�ONLY�(DIR�ENTRY�IN�FCB)8*�-1�IF�FILE�SPACE�DEALLO.�BUT�DIR.�ENTRY�ALREADY�IN�FCB* *‚ON�RETURN:%*ˆALL�REGISTERS�ARE�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR**ˆD0.B�=�FSTANNM�IF�NON-EXISTENT�FILE�NAME%*�FSTASS�IF�INSUFFICIENT�SYSTEM�SPACE*�FSTAIE�IF�DELETE�BUFFER�ERROR!*�FSTAPC�IF�DELETE�PROTECTED�FILE"*–OR�READ/WRITE�CODES�DO�NOT�MATCH*�80+�IF�I/O�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR*0*‚DIRDEL�REFERENCES�AND�UPDATES�FCB,�FAT�AND�VDT**INDENTED LISTE* DIRDEL DELETES FILE'S DIRECTORY ENTRY AND OPTIONALLY ITS FILE SPACE*DIRDEL PASS-FILE ENTRY-IN FCB* FIND DIRECTORY ENTRY FOR-FILE *‚CALL�$DSNME* ENTRY FOUND? *‚NO,�RETURN�FILE-NAME�NOT-FOUND* YES, DEALLOCATE FILE SPACE?*‚YES,-CALL�$DSDEAL�OR�$FSDEAL* NO,-ZERO OUT DIRECTORY ENTRY *‚CALL�$GETDB* RETURN*INDENTED LIST END* DIRDEL„EQU„**6*ˆFIND�FILE�NAME�IN�DIRECTORY,�CHECK�ACCESS�PROTECTION*DŠMOVEM.L�D1-D2/A1/D6-D7,-(A7)�SAVE�REGISTERS�(D1,D6,D7�MAY�BE�CHGED) ŠTST.L‚D0 ŠBEQ.S‚DRDL05�LOOK�UP�DIR.�ENTRY?ŠSUB.L‚#1,D0†DIR.�ENTRY�ALREADY�IN�FCB-FILE�SPACE�DEALLOCATION?ŠBEQ.S‚DRDL20�NOŠBRA.S‚DRDL00�YES9DRDL05„MOVE.B�FCBDIR+DIRWCD(A2),D1�SAVE�WRITE�ACCESS�CODE,ŠBSR„DSNMEŽSEARCH�FOR�FILE�NAME�IN�DIRECTORYŠBNE.S‚DRDLRT�ERROR6ŠMOVE.B�FCBDIR+DIRWCD(A2),D0�IS�FILE�DELETE�PROTECTED?ŠBEQ.S‚DRDL00�NO ŠCMP.B‚#-1,D0 ŠBEQ.S‚DRDL07�PROTECT�CODE�ERROR&ŠCMP.B‚D1,D0ŽNO,�DO�WRITE�CODES�MATCH?ŠBEQ.S‚DRDL00�YES/DRDL07„MOVE.L�#FSTAPC,D0‰NO,�PROTECT�CODE�ERROR ŠBRA.S‚DRDLRT**ˆDEALLOCATE�FILE�SPACE*)DRDL00„MOVE.L�#-1,D0�SET�DELETE�FILE�FLAG0ŠMOVE.B�FCBDIR+DIRATT(A2),D1�GET�FILE�ATTRIBUTESŠAND.B‚#DFTBIT,D1"ŠCMP.B‚#DATCON,D1‰CONTIGUOUS�FILE?ŠIFGTƒFMSLEVEL-1ŠBNE.S‚DRDL10�NOŠENDCŠIFEQƒFMSLEVEL-1 ŠBEQ.S‚DRDL02DRDL01„MOVE.L�#FSTAFT,D0 ŠBRA.S‚DRDLRT DRDL02„EQU„*ŠENDC/ŠMOVE.L�FCBDIR+DIRFE(A2),D1�YES,�GET�ITS�SIZE-1,ŠMOVE.L�FCBDIR+DIRFS(A2),A1�AND�STARTING�PSN/ŠCLR.L‚FCBDIR+DIRFS(A2)ƒCLEAR�FILE�STARTING�PSN5ŠMOVE.L�D0,FCBDIR+DIRFE(A2)�CLEAR�PHSYCIAL�ENDING�LSN:ŠMOVE.L�D0,FCBDIR+DIREOF(A2)�CLEAR�LOGICAL�END�OF�FILE�LSN(ŠADD.L‚#1,D1ŽD1�=�#�OF�SECTORS�TO�DELETE!ŠBSR„DSDEAL�DEALLOCATE�FILE�SPACEŠIFGTƒFMSLEVEL-1'ŠBRA.S‚DRDL20�GO�DELETE�DIRECTORY�ENTRY DRDL10„EQU„*ŠIFEQƒFMSLEVEL-2ŠCMP.B‚#DATSEQ,D1 ŠBEQ.S‚DRDL11ŠMOVE.L�#FSTAFT,D0 ŠBRA.S‚DRDLRT DRDL11„EQU„*ŠENDC-ŠBSR„FSDEAL�DEALLOCATE�FABS�AND�FILE�SEGMENTS?*CLEAR FCB CHANGED FLAG-DON'T WANT INFO. MOVED FROM FCB TO DIR. *…BLOCK�SINCE�DB�IS�BEING�ZEROEDŠBCLRW‚#FCFLDB,FCBFLG(A2)ŠENDC*5*ˆDELETE�DIRECTORY�ENTRY�FROM�PRIMARY�DIRECTORY�BLOCK*%DRDL20„MOVE.L�D0,D2ŽSAVE�RETURN�FLAGS ŠMOVE.L�FCBDBP(A2),A1†GET�DB�PSNŠBSR„GETDBŽGET�DB�INTO�MEMORYŠBNE.S‚DRDLRT�ERROR;ŠMOVE.L�VDTDMA(A6),A1†CLEAR�FILE�ENTRY�IN�DB�TO�DELETE�FILEŠMOVE.W�FCBDBO(A2),D1"ŠCLR.B‚0(A1,D1)‹ONLY�0�1ST�4�BYTESŠBSR„SETVFDBŒFLAG�TO�UPDATE�PDBŠMOVE.L�D2,D0ŽRESTORE�RET�FLAG5DRDLRT„MOVEM.L�(A7)+,D1-D2/D6-D7/A1�RESTORE�REGISTERSŠRTSŠPAGE**%*ˆ*************************************ŒDIRNME‚1.00‚9/18/79‚HBN6*%*ˆ*************************************4*‚DIRNME�CHANGES�THE�NAME�OF�A�FILE�IN�THE�DIRECTORY* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS *ˆA2�=�OLD�FILE�FCB�ADDRESS*ˆA3�=�NEW�FILE�FCB�ADDRESS*…A4=FAT�ADDR.�(=0�IF�NONE)* *‚ON�RETURN: *ˆALL�REGISTERS�UNCHANGED�EXCEPT*ˆD0.L�=�0�IF�NAME�CHANGED�OK0*ˆD0.B�=�FSTADNM�IF�NEW�FILE�NAME�ALREADY�EXISTS*�80+�IF�IO�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR**INDENTED LIST* DIRNME CHANGES FILE NAME"*DIRNME PASS-OLD AND-NEW FILE-FCBS#* CALL-DSNME, NEW FILE-NAME EXISTS?*‚YES,�RETURN�WITH�ERROR* NO,-CHANGE DIR.-ENTRY ONLY?*‚YES,�CALL�$UPTDIR,�RETURN* NO, CHANGE CATALOGS*‚CALL�$DIRDEL,�$DIRINS* RETURN*INDENTED LIST END* DIRNME„EQU„**,*ˆCHECK�NEW�NAME�IS�NOT�ALREADY�IN�DIRECTORY*ŠMOVEM.L�D1/D6-D7/A0-A1,-(A7)+ŠEXG„A2,A3ŽSEARCH�FOR�NEW�NAME�IN�DIRECTORY ŠBSR„DSNMEŠEXG„A2,A3ŽRESTORE�FCB�POINTERS2ŠBEQ.S‚DIRN30�ERROR,�DUPLICATE�FILE�NAME�ATTEMPTEDŠCMP.B‚#FSTANNM,D0ˆIO�ERROR?ŠBNE.S‚DIRNRT�YES*>*ˆCHANGE�PRIMARY�DIRECTORY�ENTRY�ONLY:�USER#/CATALOG�NAME�SAME*6ŠLEA„FCBSDB+SDBUSN(A2),A0�USER�#/CATALOG�NAME�CHANGED?ŠLEA„FCBSDB+SDBUSN(A3),A1ŠMOVE.L�#(USNLEN+CLGLEN)/2,D0DIRN10„CMPM.W�(A0)+,(A1)+*ŠBNE.S‚DIRN20�YES,�HAVE�TO�CHANGE�CATALOGSŠDCNTƒD0,DIRN10@ŠLEA„FCBDIR+DIRFIL(A3),A0�PUT�NEW�FILE�NAME�INTO�DIRECTORY�ENTRYŠLEA„FCBDIR+DIRFIL(A2),A1ŠMOVE.L�#(FILLEN+EXTLEN)/2,D0DIRN15„MOVE.W�(A0)+,(A1)+ŠDCNTƒD0,DIRN154ŠBSR„UPTDIR�UPDATE�DIRECTORY�BLOCK�WITH�ENTRY�IN�FCB#DIRNRT„MOVEM.L�(A7)+,D1/D6-D7/A0-A1ŠRTS**ˆCATALOG�OR�USER�#�CHANGED9*ˆDELETE�FILE�NAME�FROM�THIS�CATALOG�AND�PUT�INTO�NEW�ONE*GDIRN20„MOVE.L�#1,D0…DELETE�PRIMARY�DIRECTORY�ENTRY,�NO�SPACE�DEALLOCATI ŠBSR„DIRDELŠBNE.S‚DIRNRT�IO�ERRORŠLEA„FCBSDB+SDBUSN(A2),A0ŠLEA„FCBSDB+SDBUSN(A3),A1BŠMOVE.L�#(USNLEN+CLGLEN+FILLEN+EXTLEN)/2,D0�NEW�FILE�NAME�INTO�FCBDIRN25„MOVE.W�(A1)+,(A0)+ŠDCNTƒD0,DIRN25FŠMOVE.W�FCBSDBO(A3),FCBSDBO(A2)�SET�PDB�AND�SDB�INFO�FOR�NEW�FILE�NAME!ŠMOVE.L�FCBSDBP(A3),FCBSDBP(A2)�.ŠMOVE.W�FCBDBO(A3),FCBDBO(A2)�.ŠMOVE.L�FCBDBP(A3),FCBDBP(A2)�.BŠMOVE.L�#1,D0„INSERT�FILE�NAME�INTO�DIRECTORY,�NO�SPACE�ALLOCATION?ŠBSR„DIRINS„DON'T�SEARCH�FOR�FILE�NAME�-�JUST�PUT�FILE�INTO�NEWŠBRA.S‚DIRNRT�.�CATALOG*6DIRN30„MOVE.L�#FSTADNM,D0ˆNEW�FILE�NAME�EXISTS�ALREADY ŠBRA.S‚DIRNRTŠPAGEŠIFGTƒFMSLEVEL-1**"*ˆ**********************************ŒFSALLC�1.00�7/24/79�HBN6*"*ˆ**********************************<*‚FSALLC�ALLOCATES�SPACE�TO�A�FILE�(WITH�FAB'S)�BY�EXTENDING*ˆSPACE�AT�THE�END�OF�A�FILE�.9*ˆ(#�OF�SECTORS�REQUESTED�IS�IN�DATA�BLOCK�SIZE�'DIRDAT')* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR+*ˆD0.B�=�ISTAIDS�IF�INSUFFICIENT�DISK�SPACE!*�ISTAAL�IF�INTERNAL�SYSTEM�ERROR*�80+�IF�IO�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR**INDENTED LIST>* FSALLC EXTENDS FILE SPACE AT THE END OF A NONCONTIGUOUS FILE*FSALLC* GET-LAST FAB-INTO MEMORY*‚CALL�$GETFDB,�FAB�FOUND?"*ƒNO,ALLOC�FIRST-FAB:�CALL�$FBALLC* ALLOCATE NEW DATA BLOCK*‚CALL�$PUTDAT,�$DSALLC* GET NEW FAB ENTRY *‚FAB-FULL?*ƒYES,�CALL�$FBALLC* RETURN EMPTY DATA BLOCK*INDENTED LIST END** FSALLC„EQU„**4*ˆGET�LAST�FAB�INTO�MEMORY�OR�GET-ALLOCATE�FIRST�FAB*,ŠMOVEM.L�D1-D6/A0-A1/A3,-(A7)�SAVE�REGISTERSEŠGET2‚FCBDIR+DIREOF(A2),D5,D6�GET�STARTING�LSN/LRN�FOR�NEW�DATA�BLOCKŠADD.L‚#1,D6Ž.ŠMOVE.L�D5,D0Ž.�GET�LAST�FAB�INŠADD.L‚#1,D5Ž.ŠMOVE.L�#LSNFDB,D1‰. ŠBSR„GETFDB�.<ŠBEQ.S‚FSAL15‰ERROR?�-�NO�=�FILE�HAS�AT�LEAST�ONE�DATA�BLOCK#ŠCMP.B‚#ISTAEOF,D0ˆYES,�EMPTY�FILE?FSAL10„BNE„FSALRT�ERROR.ŠBRA.S‚FSAL20�GO�ALLOCATE�1ST�SEGMENT�FOR�FILE*/*ˆWRITE�OUT�CURRENT�DATA�BLOCK�IF�NECESSARY�AND2*ˆTRY�TO�ALLOCATE�DISK�SPACE�CLOSE�TO�LAST�SEGMENT*"FSAL15„CLR.L‚D0‘NO�KEY�UPDATE�FLAG2ŠBSR„PUTDAT�UPDATE�CURRENT�DATA�BLOCK�IF�NECESSARYŠBNE.S‚FSAL10�ERROR$ŠCLR.L‚D0‘GET�NEXT�FAB�ENTRY�POINTER%ŠMOVE.B�FABKEY(A0),D0†.�KEY�FIELD�BCT@ŠLEA„FABSSL(A0,D0),A0‚.�A0�->‚FAB�ENTRY�LOCATION�FOR�NEW�SEGMENT/FSAL20„MOVE.L�FATFAE(A4),D4†GET�FAB�END�ADDRESSŠCLR.L‚D1‘GET�DATA�BLOCK�SIZE ŠMOVE.B�FCBDIR+DIRDAT(A2),D1�.?ŠBSR„DSALLC„ALLOCATE�SPACE�(RET:�A1�=�PSN�OF�SEGMENT�ALLOCATED)ŠBNE.S‚FSALRT�ERROR?*&*ˆALLOCATE�NEW�FAB�IF�CURRENT�FAB�FULL*ŠCLR.L‚D2‘GET�KEY�LENGTHŠMOVE.B�FCBDIR+DIRKEY(A2),D2�.6ŠTST.L‚D5�D5�=�STARTING�LSN�OF�DATA�BLOCK,�0=1ST�BLOCK!ŠBEQ.S‚FSAL28�1ST�SEGMENT�OF�FILEAŠLEA„FABSSL(A0,D2),A3‚ANY�ROOM�TO�ADD�NEW�ENTRY�INTO�CURRENT�FAB?ŠADD.L‚#1,D4Ž. ŠCMP.L‚D4,A3ŠBLS.S‚FSAL35�YES,�FORM�NEW�SD FSAL28„EQU„*:ŠBSR„FBALLC‰NO,�ALLOCATE�AND�LINK�NEW�FAB�TO�THE�FAB�CHAINŠBEQ.S‚FSAL30�ERROR?%ŠMOVE.L�D0,-(A7)‹YES,�SAVE�ERROR�CODEŠBSR„DSDEAL�DEALLOCATE�SEGMENT,ŠMOVE.L�(A7)+,D0‹RESTORE�ORIGINAL�ERROR‚CODEŠBRA.S‚FSALRT�ERROR�EXIT**ˆUPDATE�FAT,�FAB*:FSAL30„SAVE2‚D5,D6,FATFLS(A4)ƒSET�FAB�STARTING�LSN/LRN�=�0=FSAL35„MOVE.L�A1,(A0)ŒSET�STARTING�PSN�OF�SEGMENT�INTO�FABPSNFŠMOVE.B�FCBDIR+DIRKEY(A2),FABKEY(A0)�FIELD�LENGTH=KEY�SIZE�FOR�LAST�FA@ŠMOVE.L�DIREOF+FCBDIR(A2),FATLLS(A4)�UPDATE�FAB�ENDING�LSN(=EOF)7ŠMOVE.L�FCBDIR+DIREOR(A2),FATLLR(A4)�FAB�ENDING�LRN=EOR+ŠLEA„FABKEY(A0),A1†SET�LAST�FAB�KEY�POINTER:ŠSAVE2‚A0,A1,FATCFP(A4)ƒSAVE�CURRENT�ENTRY�&�LAST�KEY�PNTR%ŠMOVE.B�D2,(A1)+‹SET�KEY�FIELD�LENGTHŠBEQ.S‚FSAL41�.�NULL�OR�NO�KEYSFSAL40„CLR.B‚(A1)+ŽAND!ŠDCNTƒD2,FSAL40Š.�CLEAR�KEY�FIELD@FSAL41„SUB.L‚#4,D4‹CLEAR�LONG�WORD�AT�END�OF�NEW�ENTRY�IF�NOT�ATŠCMP.L‚D4,A1Ž.�END�OF�FABŠBHI.S‚FSAL45�OK*ŠCLR.L‚(A1)�CLEAR�FOR�END�OF�FAB�INDICATOR0FSAL45„CLR.W‚FABREC(A0)‰CLEAR�RECORD�COUNT�FIELD*ŠCLR.B‚FABSGS(A0)‰CLEAR�SECTOR�COUNT�FIELD7ŠSAVE2‚D5,D6,FATSLS(A4)ƒSEGMENT'S�1ST�AVAILABLE�LSN/LRN ŠBSR„FABCHG�SET�FAB�CHANGED�FLAG ŠCLR.L‚D05FSALRT„MOVEM.L�(A7)+,D1-D6/A0-A1/A3�RESTORE�REGISTERSŠRTSŠPAGE**#*ˆ***********************************ŒFSDEAL�1.00�7/25/79‚HBN6*#*ˆ***********************************(*‚FSDEAL�DEALLOCATES�ALL�SPACE�IN�A�FILEC*…FSDEAL�ALLOCATES�AND�ATTACHES�TO�SEGMENT�FOR�FAB�IF�ANY�FILE�SPAC:*…EXISTS�AND�SEGMENT�NOT�ALREADY�ALLOCATED.‚SEGMENT�IS�NOT*…RELEASED�WHEN�FSDEAL�IS�DONE* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR*�80+�IF�IO�ERROR%*�FSTASS�IF�INSUFFICIENT�SYSTEM�SPACE*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR**INDENTED LIST6* FSDEAL DEALLOCATES ALL SPACE IN A NONCONTIGUOUS FILE*FSDEAL"* FIND-FIRST DATA-BLOCK FOR-DELETE*‚CALL�$GETIOB,�$GETFDB* DEALLOCATE ALL BLOCKS IN-FAB*‚CALL�$DSDEAL* DEALLOCATE FAB WHEN EMPTY*‚CALL�$FBDEAL* RETURN EMPTY FILE*INDENTED LIST END** FSDEAL„EQU„**"*ˆFIND�FIRST�SEGMENT�TO�BE�DELETED*/ŠMOVEM.L�D1-D4/A0-A1/A3/A5,-(A7)�SAVE�REGISTERS0ŠCLR.L‚D0‘SET�FOR�GOOD�RETURN�AND�TO�GET�1ST�FAB#ŠTST.L‚FCBDIR+DIRFS(A2)ƒEMPTY�FILE?-ŠBEQ.S‚FSDEER�YES,�RETURN�SINCE�NOTHING�TO�DO,ŠTST.L‚FATBSN(A4)‰SEGMENT�ALREADY�ALLOCATED?ŠBNE.S‚FSDE10�YESŠMOVE.B�#$80,D0ŠBSR„GETIOB�ALLOCATE�FAB�BUFFER'ŠBNE.S‚FSDEER�INSUFFICIENT�SYSTEM�SPACE.FSDE10„MOVE.L�#LSNFDB,D1‰.�IGNORE�LSN�CONFLICT6ŠBSR„GETFDB�GET�1ST�FAB�WHERE�DEALLOCATION�IS�TO�START8ŠBNE.S‚FSDE55�ERROR�-�GO�SET�DIR.�ENTRY�FOR�EMPTY�STATUS*+ŠMOVE.L�A0,A3ŽA3�->�FAB�ENTRY�TO�BE�DELETED$ŠMOVE.L�FATFAE(A4),D4†FAB�BUFFER�END(ŠSUB.L‚#3,D4ŽD4�->�LAST�LONG�WORD�IN�FAB!ŠBRA.S‚FSDE30�DELETE�ALL�SEGMENTS FSDEER„BRA.S‚FSDERT�ERROR�RETURN!FSDE25„CMP.L‚D4,A3ŽNEED�NEXT�FAB?ŠBCC.S‚FSDE50�YES* *ˆDELETE�ALL�SUBSEQUENT�SEGMENTS*/FSDE30„MOVE.L�(A3),A1ŒDATA�SEGMENT�PSN�(FABPSN)&ŠCLR.L‚D2‘GET�FAB�ENTRY�LENTGH�INTO�D2(ŠMOVE.B�FABKEY(A3),D2†.�KEY�FIELD�LENGTHŠADD.L‚#FABSSL,D2‰.-ŠLEA„0(A3,D2),A5ˆA5�->�NEXT‚FAB�ENTRY�POINTER+ŠCLR.B‚D3‘CLEAR�FLAG�FOR�NOT�LAST�FAB�ENTRY2ŠCMP.L‚D4,A5ŽTO�DEALLOCATE�FILE'S�LAST�DATA�BLOCK?'ŠBCC.S‚FSDE35�.�YES�IF�THIS�IS�LAST�FAB.ŠTST.L‚(A5)�.�AT�END�OF�FAB�IF�NEXT�FABPSN�=�0$ŠBNE.S‚FSDE40�.�NOT�LAST�FAB�SEGMENT@FSDE35„MOVE.L�#1,D3Œ.�SET�FLAG�FOR�LAST�FAB�ENTRY�IN�FAB�DELETEDFSDE40„BSR„DEALDBŠBNE.S‚FSDE55�ERROR*%*ˆCLEAR�FAB�ENTRY�FOR�DELETED�SEGMENT*$ŠLSR„#1,D2ŽD2�=�FAB�ENTRY�WORD�COUNTFSDE45„CLR.W‚(A3)+ ŠDCNTƒD2,FSDE45.ŠTST.B‚D3‘DELETED�LAST�FAB�ENTRY�=>�DELETE�FAB#ŠBEQ.S‚FSDE25�DELETE�NEXT�FAB�ENTRY**ˆDELETE�CURRENT�FAB*#FSDE50„MOVE.L�FATFAA(A4),A5†FAB�FWA5ŠMOVE.L�(A5),D3ŒGET�FORWARD�LINK�(FABFLK)�TO�NEXT�FABŠBSR„FBDEAL�DEALLOCATE�FABŠBNE.S‚FSDE55�ERROR ŠMOVE.L�#-1,D2�LAST�FAB�DELETED?ŠMOVE.L�FATLLS(A4),D0†.ŠADD.L‚#1,D0Ž.ŠTST.L‚D3‘.�FORWARD�LINK�=�0?3ŠBNE„FSDE10�NO,�GO�DELETE�ALL�SEGMENTS�IN�NEXT�FABSŠCLR.L‚D0‘SET�GOOD�RETURN�FLAGS*FSDE55„MOVE.L�D0,D1ŽSAVE�RETURN�CONDITIONS ŠBSR.S‚RLNFT3�RESET�FAB�FAT�INFO&ŠMOVE.L�D0,FCBDIR+DIREOF(A2)�RESET�EOF$ŠMOVE.L�D0,FCBDIR+DIREOR(A2)�AND�EOR0ŠCLR.L‚DIRFS+FCBDIR(A2)ƒDELETE�FILE�STARTING�PSN&ŠCLR.L‚DIRFE+FCBDIR(A2)ƒAND�ENDING�PSN@ŠBSETW‚#FCFLDB,FCBFLG(A2)�FLAG�FCB�FOR�UPDATE�IN�DIRECTORY�BLOCK+ŠCLR.L‚FATCFP(A4)‰INDICATE�NO�FAB�IN�MEMORY.ŠMOVE.L�D1,D0ŽNO,�RESTORE�PREVIOUS�RETURN�CODE8FSDERT„MOVEM.L�(A7)+,D1-D4/A0-A1/A3/A5�RESTORE�REGISTERSŠRTSŠPAGE*$*ˆ************************************ŒRLNFAT�1.00�11/4/79�HBN6*$*ˆ***********************************=*‚RLNFAT�SETS�FAT�LSN�AND�LRN�FIELDS�TO�-1�TO�INDICATE�NO�FAB#*ˆRLNFT3�ALSO�CLEARS�FATFAB/CFP/KEY*ˆRLNFT2�CLEARS�FATCFP/KEY* *‚ON�ENTRY:*ˆA4�=�FAT�ADDRESS* *‚ON�RETURN:$*ˆD0�=�-1,�OTHER�REGISTERS�UNCHANGED* RLNFT3„EQU„*"ŠCLR.L‚FATFAB(A4)‰NO�FAB�IN�MEMORY RLNFT2„EQU„*&ŠCLR.L‚FATCFP(A4)‰NO�CURRENT�FAB�ENTRY!ŠCLR.L‚FATKEY(A4)‰NO�LAST�FAB�KEY RLNFAT„EQU„*!ŠMOVE.L�#-1,D0�SET�NO�LSN�FOR�FABŠMOVE.L�D0,FATFLS(A4)†.ŠMOVE.L�D0,FATLLS(A4)†.ŠMOVE.L�D0,FATFLR(A4)†.ŠMOVE.L�D0,FATLLR(A4)†.CŠBSR.S‚SETFSL‚SET�FAB�STARTING�LSN/LRN�FOR�SEGMENT�STARTING�LSN/LRNŠRTS**$*ˆ************************************ŒSETFSL�1.00�1/30/80�HBN6*$*ˆ***********************************@*‚SETFSL�SETS�SEGMENT�STARTING�LSN�AND�LRN�EQUAL�TO�FAB�STARTING *‰LSN�AND�LRN**‚ON�ENTRY:�A4�=�FAT�ADDRESS*$*‚ON�RETURN:�ALL�REGISTERS�UNCHANGED*'SETFSL„MOVE.L�FATFLS(A4),FATSLS(A4)�LSN!ŠMOVE.L�FATFLR(A4),FATSLR(A4)�LRNŠRTSŠPAGE*%*ˆ*************************************ŒFBALLC‚1.00‚7/23/79‚HBN6*%*ˆ*************************************E*‚FBALLC�ALLOCATES�AND�LINKS�A�NEW�FAB�TO�END�OF�FAB�CHAIN.‚THE�PRIOR?*ˆFAB�IS�UPDATED�ON�DISK.‚THE�NEW�FAB�IS�INITIALIZED�IN�MEMORY.6*ˆEITHER�THE�LAST�FAB�IS�IN�MEMORY�OR�FILE�HAS�NO�FABS%*ˆFAB�BUFFER�MUST�HAVE�BEEN�ALLOCATED* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS* *‚ON�RETURN:%*ˆALL�REGISTERS�ARE�UNCHANGED�EXCEPT:"*ˆA0�->�FIRST�FAB�ENTRY�IN�NEW�FAB*ˆD0.L�=�0�IF�NO�ERROR+*ˆD0.B�=�ISTAIDS�IF�INSUFFICIENT�DISK�SPACE3*�FSTAIE�IF�INTERNAL�SYSTEM�ERROR�-�LAST�FAB�NOT�IN*�80+�IF�IO�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR**INDENTED LIST:* FBALLC ALLOCATES AND LINKS A NEW FAB TO END OF FAB CHAIN*FBALLC PASS LAST-FAB IF-ANY* ALLOCATE DISK-SPACE FOR-FAB*‚CALL�$DSALLC* SET FORWARD LINK-IN CURR.-FAB#*‚CALL�$PUTFAB�(LAST-FAB�IN-MEMORY)* SET-UP-FOR NEW-FAB IN-MEMORY*‚CALL�$RLNFT2,�CLEAR�FAB* UPDATE FILE-END IN-FCB* RETURN*INDENTED LIST END* FBALLC„EQU„**)ŠMOVEM.L�D1-D5/A1/A3,-(A7)�SAVE�REGISTERS*ŠMOVE.L�FATFAA(A4),A3†GET�FAB�BUFFER�START$ŠMOVE.L�FATFAE(A4),D5†FAB�BUFFER�ENDŠMOVE.L�FATFAB(A4),D4†FAB�PSNŠBEQ.S‚FBAL00�NO*ŠMOVE.L�(A3),D2ŒYES,�LAST�FAB?�(FABFLK=0?)ŠBEQ.S‚FBAL05�YES=FBAL00„MOVE.L�FCBDIR+DIRFS(A2),D2�ELSE�TO�ALLOCATE�FIRST�FAB?ŠBEQ.S‚FBAL10�."FBALIE„MOVE.L�#FSTAIE,D0‰NO,�ERRORFBALER„BRA.S‚FBALRT**ˆALLOCATE�FAB�SPACE�ON�DISK*5FBAL05„ADD.L‚#1,D2ŽSET�FLAG�FOR�LAST�FAB�IN�(D2�<>0�)FBAL10„BSR„ALLOFB�ALLOCATE�FABŠBNE.S‚FBALER�ERROR**ˆLINK�FAB�TO�FAB�CHAIN*ŠTST.L‚D2‘WAS�THIS�FIRST�FAB?6ŠBNE.S‚FBAL15�NO,�NEW�FAB�TO�BE�LINKED�TO�END�OF�CHAINCŠMOVE.L�A1,FCBDIR+DIRFS(A2)�YES,�SET�FILE�STARTING�PSN�IN�DIRECTORY ŠCLR.L‚D4‘SET�BACKWARD�LINK�TO�0 ŠBRA.S‚FBAL20*>FBAL15„MOVE.L�A1,(A3)ŒSET�FORWARD�LINK�'FABFLK'�IN�CURRENT�FABŠBSR„FABCHG�SET�FLAG�TO&ŠBSR„PUTFAB�UPDATE�CURRENT�FAB�ON�DISKŠBNE.S‚FBALRT�ERROR*!*ˆSET�UP�NEW�FAB�BUFFER�IN�MEMORY   'KK!K)L1K9EAFI?Q;YAa;i8q8yQ�@‰B‘H™I¡N©L±F¹BÁ:É6Ñ^ÙLá5é?ñKù7*AFBAL20„MOVE.L�A1,FCBDIR+DIRFE(A2)�LAST�FAB�POINTER�INTO�DIRECTORY=ŠBSETW‚#FCFLDB,FCBFLG(A2)�FLAG�FCB�TO�BE�CHANGED�IN�DIRECTORY(ŠCLR.L‚(A3)+ŽCLEAR�FORWARD�LINK�'FABFLK'+ŠMOVE.L�D4,(A3)+‹SET�BACKWARD�LINK�'FABBLK'!ŠCLR.B‚(A3)+ŽCLEAR�'FABRES'�FIELD)ŠMOVE.L�A1,FATFAB(A4)†SET�CURRENT�FAB�PSN!ŠCLR.W‚D0‘SET�FABPKY�FIELD�LENGTHŠMOVE.B�FCBDIR+DIRKEY(A2),D0�.8ŠMOVE.B�D0,(A3)+‹.�FULL�KEYS�ONLY�TO�SIMPLIFY�EVERYTHING ŠBEQ.S‚FBAL30�.�NULL�OR�NO�KEYS?ŠMOVE.L�FATKEY(A4),A1†.ŠTST.L‚D2‘.�FIRST�FAB?*ŠBEQ.S‚FBAL40�.�YES,�GO�SET�HEADER�KEY�=�09ŠCMP.B‚(A1)+,D0‹MOVE�PREVIOUS�FAB'S�LAST�KEY�INTO�NEW�FAB8ŠBNE.S‚FBALIE�.�LAST�KEY�SHOULD�BE�FULL�LENGTH�FOR�NOW�*FBAL25„MOVE.B�(A1)+,(A3)+ˆ.ŠDCNTƒD0,FBAL25Š.&FBAL30„BSR„RLNFT2�RESET�LSN/LRN�IN�FATDŠMOVE.L�A3,A0‚CLEAR�DATA�PORTION�OF�FABRETURN�FIRST�SD�POINTER�IN�A0'ŠSUB.L‚A3,D5Ž.�GET�FAB�DATA�PORTION�BCTŠADD.L‚#1,D5Ž.#ŠLSR.L‚#1,D5Ž.�D0�=�LONG�WORD�COUNTFBAL35„CLR.W‚(A3)+ŽCLEARŠDCNTƒD5,FBAL35Š.&ŠBSR„FABCHG�SET�FLAG�TO�UPDATE�NEW�FABŠCLR.L‚D0‘FLAG�GOOD�RETURN2FBALRT„MOVEM.L�(A7)+,D1-D5/A1/A3�RESTORE�REGISTERSŠRTS*@FBAL40„LSR.W‚#1,D0‹SET�KEY�=�0�FOR�1ST�FAB�TO�MAKE�THINGS�EASIERFBAL45„CLR.W‚(A3)+Ž.ŠDCNTƒD0,FBAL45Š.ŠBRA„FBAL30�CONTINUEŠPAGE**%*ˆ*************************************ŒFBDEAL‚1.00‚7/25/79‚HBN6*%*ˆ*************************************5*‚FBDEAL�DEALLOCATES�DISK�SPACE�FOR�THE�FAB�IN�MEMORY* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS* *‚ON�RETURN:%*ˆALL�REGISTERS�ARE�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR *ˆD0.B�=�ISTAFAB�IF�NO-FAB�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR**‚FBDEAL�CALLS�DSDEAL*ˆREFERENCES�FCB�AND�FAT** FBDEAL„EQU„*#ŠMOVEM.L�D1/A1,-(A7)‡SAVE�REGISTERS(ŠMOVE.L�FATFAB(A4),D1†ANY�FAB�IN�MEMORY?ŠBNE.S‚FBDE00�YES ŠMOVE.L�#NL+ISTAFAB,D0…NO,�ERROR ŠBRA.S‚FBDERT*0FBDE00„MOVE.L�D1,A1ŽPSN�OF�FAB�TO�BE�DEALLOCATED'ŠBSR„DEALFB�DEALLOCATE�FAB'S�DISK�SPACE,FBDERT„MOVEM.L�(A7)+,D1/A1‡RESTORE�REGISTERSŠRTSŠPAGE*$*ˆ************************************ŒDELFAB�1.00�11/6/79�HBN6*$*ˆ***********************************<*‚DELFAB�DEALLOCATES�CURRENT�FAB,�FORWARD�AND�BACKWARD�LINKS1*ˆARE�UPDATED�IN�PRIOR�AND�NEXT�FAB�OR�DIRECTORY."*ˆNO�CURRENT�FAB�EXISTS�ON�RETURN.* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR*ˆD0.B�=�ERROR�CODE*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR**INDENTED LIST;* DELFAB DEALLOCATES AND REMOVES CURRENT FAB FROM FAB CHAIN*DELFAB PASS CURRENT FAB* UPDATE NEXT FAB HEADER*‚CALL�$NXTFHD* UPDATE PREVIOUS FAB-HEADER*‚CALL�$PRVFHD* FIRST-OR LAST-FAB DELETED?*‚YES�UPDATE�FCB* DEALLOCATE FAB'S DISK SPACE*‚CALL�$FBDEAL* RETURN*INDENTED LIST END* DELFAB„EQU„**&*ˆUPDATE�NEXT�FAB�HEADER�IF�ONE�EXISTS*,ŠMOVEM.L�A0-A1/A3/D1-D5,-(A7)�SAVE�REGISTERS!ŠMOVE.L�FATFAB(A4),D2†CURRENT�FABŠBNE.S‚DELF00�A�FAB�IN�MEMORY? ŠBSR„ISTAIERR‹NO,�INTERNAL�ERROR ŠBRA.S‚DELFRT,DELF00„MOVE.L�FATFAA(A4),A0†FAB�BUFFER�START2ŠLEA„FABPKY(A0),A1†ADDR�OF�PREV�FAB�LAST�KEY�VALUE)ŠMOVE.L�A1,FATKEY(A4)†DUMMY�UP�FOR�NXTFHD)ŠMOVE.L�FABBLK(A0),D4†BACKWARD�LINK�VALUE0ŠMOVE.L�#2,D0ŽTELL�NXTFHD�TO�UPDATE�KEY�AND�LINKŠMOVE.L�(A0),D3ŒNEXT�FABŠBSR.S‚NXTFHD�.ŠBNE.S‚DELFRT�ERROR?*)*ˆSET�FORWARD�LINK�IN�PREVIOUS�FAB�IF�ANY$*ˆUPDATE�DIR�ENTRY�IF�DELETE�1ST�FAB*,ŠBSR„PRVFHD�UPDATE�FORWARD�LINK�IN�PRIOR�FABŠBNE.S‚DELFRT�ERROR?*5*ˆUPDATE�DIRECTORY�ENTRY�IF�DELETED‚LAST�OR�FIRST�FAB*ŠTST.L‚D3‘ANY�NEXT�FAB?ŠBNE.S‚DELF30�YESAŠMOVE.L�D4,FCBDIR+DIRFE(A2)�NO,�PREVIOUS�FAB�IS�NOW�LAST�IN�CHAIN=ŠBSETW‚#FCFLDB,FCBFLG(A2)�SET�FLAG�THAT�DIR�ENTRY�GOT�CHANGEDDELF30„TST.L‚D4‘ANY�PRIOR�FAB?ŠBNE.S‚DELF35�YESBŠMOVE.  L�D3,FCBDIR+DIRFS(A2)�NO,�NEXT�FAB�IS�NOW�FIRST�IN�FAB�CHAIN0ŠBSETW‚#FCFLDB,FCBFLG(A2)�FLAG�DIR�ENTRY�CHANGED**ˆDEALLOCATE�FAB'S�DISK�SPACE*-DELF35„BSR„FBDEAL�DEALLOCATE�FAB'S�DISK�SPACE+ŠCLR.L‚FATFAB(A4)‰NO�FAB�IN�MEMORY�ANY�MORE0ŠBCLRW‚#FAFLFB,FATFLG(A4)�CLEAR�FAB�CHANGED�FLAG5DELFRT„MOVEM.L�(A7)+,A0-A1/A3/D1-D5�RESTORE�REGISTERSŠTST.B‚D0‘RESET�COND.�CODEŠRTSŠPAGE#*ˆ***********************************ŒNXTFHD�1.00�11/27/79�HBN6*#*ˆ**********************************>*‚NXTFHD�UPDATES�NEXT�FAB'S�HEADER:�BACKWARD�LINK�AND�LAST�KEY* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS*ˆD3�=�PSN�OF�NEXT�FAB*ˆD4�=�BACKWARD�LINK�TO�BE�USED*ˆD0�=�0�IF�LINK�ONLY*�-1�IF�KEY�ONLY-*�1�IF�UPDATE�LINK�AND�ZERO�OUT�KEY�IN�HEADER*�2�IF�UPDATE�LINK�AND�KEY<*ˆFATKEY(A4)�-‚ADDRESS�OF�KEY�LENGTH�(0�IF�NONE)�FOLLOWED�BY *–KEY�VALUE* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR*ˆD0.B�=�80+�IF�IO�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR* NXTFHD„EQU„**:*ˆREAD�1ST�SECTOR�OF�NEXT�FAB�INTO�TEMPORARY�SECTOR�BUFFER*,ŠMOVEM.L�D1-D2/A1/A3/A5,-(A7)�SAVE�REGISTERSŠMOVE.L�D0,D2ŽSAVE�FLAGBŠMOVE.L�D3,D0„READ�IN�1ST�SECTOR�OF�NEXT�FAB�TO�UPDATE�LINKS�&�KEY&ŠBEQ.S‚NXTFRT�SKIP�CALL�IF�NO�NEXT�FABŠMOVE.L�#IOREAD,D1‰READ3ŠBSR„GPTSEC�A1�RETURNS�POINTING�TO�SECTOR�JUST�READŠBNE.S‚NXTFRT�ERROR?**ˆUPDATE�HEADER�INFO�(D0�=�0)*-ŠLEA„FABPKY(A1),A5†MOVE�TO�ADR�FOR�HEADER�KEYŠCMP.B‚#2,D2ŽKEY�AND�LINK?ŠBEQ.S‚NXTF05�YES*ŠTST.L‚D2‘SKIP�KEY�UPDATE�IF�NOT�REQUESTEDŠBPL.S‚NXTF20�NOT�REQUESTED-NXTF05„MOVE.L�FATKEY(A4),A3†GET�MOVE�FROM�ADR!ŠMOVE.B�(A3)+,D0‹GET�FIELD�LENGTH(ŠMOVE.B�D0,(A5)+‹SAME�LENGTH�IN�NEXT�FABŠLSR.W‚#1,D0ŽANY�KEY�THERE?ŠBEQ.S‚NXTF15�NO&NXTF10„MOVE.W�(A3)+,(A5)+ˆYES,�SAVE�ITŠDCNTƒD0,NXTF10Š. NXTF15„SUB.L‚#2,D2ŽKEY�AND�LINK?ŠBEQ.S‚NXTF25�YESŠBRA.S‚NXTF30�NO,�KEY�ONLY NXTF20„SUB.L‚#1,D2ŽZERO�OUT�KEY?ŠBEQ.S‚NXTF35�YES1NXTF25„MOVE.L�D4,FABBLK(A1)†NO,�SET�BACKWARD�LINK**ˆWRITE�THE�SECTOR�BACK�TO�DISK* NXTF30„MOVE.L�D3,D0ŽWRITE�IT�OUTŠMOVE.L�#IOWRIT,D1‰WRITE3ŠBSR„GPTSEC�A1�RETURNS�POINTING�TO�SECTOR�JUST�READ5NXTFRT„MOVEM.L�(A7)+,D1-D2/A1/A3/A5�RESTORE�REGISTERSŠRTS**ˆCLEAR�KEY�(D2�=�0)*'NXTF35„MOVE.B�(A5)+,D2‹GET�BCT�TO�CLEARŠBEQ.S‚NXTF25�SKIP�IF�NULL�KEYSNXTF40„CLR.B‚(A5)+ŠDCNTƒD2,NXTF40ŠBRA„NXTF25�GO�UPDATE�LINKŠPAGE*#*ˆ***********************************ŒPRVFHD�1.00�11/27/79�HBN6*#*ˆ**********************************4*‚PRVFHD�UPDATES�FORWARD�LINK�IN�PREVIOUS�FAB�HEADER* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS*ˆD4�=�PSN�OF�PREVIOUS�FAB*ˆD3�=�FORWARD�LINK�TO�BE�USED* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR*ˆD0.B�=�80+�IF�IO�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR* PRVFHD„EQU„**!*ˆREAD�IN�1ST�SECTOR�OF�PRIOR�FAB*#ŠMOVEM.L�D1/A1,-(A7)‡SAVE�REGISTERSŠMOVE.L�D4,D0ŽANY�PREVIOUS�FAB?ŠBEQ.S‚PRVF00�NO,�JUST�RETURNŠMOVE.L�#IOREAD,D1‰READ3ŠBSR„GPTSEC�A1�RETURNS�POINTING�TO�SECTOR�JUST�READŠBNE.S‚PRVFRT�ERROR?**ˆUPDATE�FAB�HEADER�INFORMATION*)ŠMOVE.L�D3,(A1)ŒSET�FORWARD�LINK�(FABFLK)**ˆWRITE�THE�SECTOR�BACK�TO�DISK*+ŠMOVE.L�D4,D0ŽRESTORE�SECTOR'S�PSN�FOR�CALLŠMOVE.L�#IOWRIT,D1‰WRITE ŠBSR„GPTSEC�. ŠBRA.S‚PRVFRT>PRVF00„MOVE.L�D3,FCBDIR+DIRFS(A2)�SET�NEW�1ST�FAB�IN�DIRECTORY4ŠBSETW‚#FCFLDB,FCBFLG(A2)�SET�DIR�ENTRY�CHANGED�FLAGŠTST.B‚D0‘SET�GOOD�RETURN�FLAGS,PRVFRT„MOVEM.L�(A7)+,D1/A1‡RESTORE�REGISTERSŠRTSŠPAGE*%*ˆ*************************************ŒGETFDB‚1.00‚7/25/79‚HBN6*%*ˆ*************************************1*‚GETFDB�FINDS�THE�SEGMENT�CORRESPONDING�TO�GIVEN:*ˆLSN,�LRN,�OR�KEY.‚THE�NEW�CURRENT�SEGMENT�IS�ESTABLISHED?*ˆAND�IF�READ�IS�REQUESTED,�THE�NEW�SEGMENT�IS�READ�INTO�MEMORY=*ˆIF�THE�CURRENT�SEGMENT�IS�SWITCHED�CURRENT�BLOCK�IS�UPDATED!*ˆON�DISK�IF�IT�HAS�BEEN�CHANGED.=*ˆNOTHING�ACTUALLY�HAPPENS�IF�CURRENT�BLOCK�SATISFIES�REQUEST.*ˆIF�A  �FAB�HAS�TO�BE�REPLACED�ALL�CHANGED�DISK*ˆBLOCKS�ARE�WRITTEN�TO�DISK�.=*ˆON�RETURN,�FOR�LSN�AND�LRN�THE�CURRENT�SEGMENT�CONTAINS�THE7*ˆREQUESTED�SECTOR�OR�RECORD.‚FOR�KEYS,�THE�RECORD�WITH:*ˆTHE�GIVEN�KEY�MUST�BE�IN�CURRENT�SEGMENT�OR�ELSE�IT�DOES.*ˆNOT�EXIST�(THIS�CHECK�IS�NOT�MADE�BY�GETFDB);*ˆNOTE:�D1�MUST�BE�ON�TOP�OF�STACK�WHEN�REGISTERS�ARE�SAVED* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS2*ˆD0.L�=�LSN,�LRN,�OR�KEY�POINTER�WHERE�APPLICABLE?*ˆD1.L�=�GETFDB�DIRECTIVE�AND�READ&IGNORE�LSN-EOF�CONFLICT�FLAG$*ˆD2.L�=�KEY�LENGTH�WHERE�APPLICABLE* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:#*ˆA0�=�ADDRESS�OF�CURRENT�FAB�ENTRY*ˆD0.L�=�0�IF�NO�ERROR>*ˆD0.B�=�ISTAIE�IF�LSNFDB/LRNFDB�AND�LSN/LRN�=�-1�OR�DIRECTIVE *’TOO�LARGE/*�ISTAEOF�IF�LSNFDB/LRNFDB‚AND�LSN/LRN�PAST�EOF*’OR�KEYFDB�AND�EMPTY�FILE#*�ISTAFD�IF�FAB-DATA�BLOCK�CONFLICT*�80+�IF�IO�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR**INDENTED LIST7* GETFDB FINDS DATA BLOCK FOR SPECIFIED LSN, LRN OR KEY*GETFDB PASS-LSN, LRN-OR KEY* LSN-OR-LRN OUT-OF RANGE?*‚YES,RETURN�END-OF�FILE-ERROR * NO,-RECORD IN CURRENT SEGMENT?(*‚YES,RETURN�(READ-DB�IF-USER�SHARES-DB)* NO,FIND FAB-AND SEGMENT"*‚SAVE-CURR.�DATA-BLK�CALL�$PUTDAT*ƒDATA�BLOCK�WITHIN�CURR.-FAB?*„NO,-FIND�PROPER�FAB�CALL$*…$GTFNSR,�$GTFPSR,�$GTFLSR,�$GTFFSR%*…ALSO-CALL�$CHKKEY,�$DPLKEY,�$LASTSG* DB READ REQUESTED?"*‚YES,DB�IN-MEMORY�FOR-OTHER�USER?*ƒYES,MOVE�DB-IN�MEMORY*„ADJUST�FATSBL*ƒNO,REQD�BLOCK�FROM-DISK�$DOIO*„ADJUST�FATSBL** IF-GOT-NEW FAB-OR-DB TRY-MERGE WITH-NEXT*‚CALL�$CMBNDB,�$CMBNFB* RETURN SEGMENT FOUND*INDENTED LIST END* GETFDB„EQU„***ˆGET�DIRECTIVE�BRANCH�ADDRESS*AŠMOVEM.L�D1-D7/A3/A1/A5,-(A7)�SAVE�REGISTERS�(D1�AT�TOP�OF�STACK)9ŠAND.W‚#$3F,D1ŒAND�OFF�FLAG�BITS�(LEAVE�DIRECTIVE�NUMBER)%ŠCMP.B‚#NODIR,D1ŠDIRECTIVE�TOO�LARGE?!ŠBLT.S‚GTFBIE.1‹BRANCH�IF�NO�-�OKŠBSR„ISTAIERR‹YES�-�ERROR ŠBRA.S‚GTFBEX7GTFBIE.1‚MOVE.L�D0,D3ŽSAVE�LSN,�LRN�OR�KEY�POINTER�INFO$ŠMOVE.L�D2,D4ŽSAVE�KEY�LENGTH�IF�ANY&ŠCLR.L‚D0‘GET�DIRECTIVE�BRANCH�ADDRESSŠLEA„GTFBAD,A0Š.ŠLSL.W‚#1,D1Ž.�D1*2ŠMOVE.W�0(A0,D1),D0ˆ.-ŠADD.L‚#FMSSTR,D0‰MAKE�INTO�PHYSICAL�ADDRESS. ŠMOVE.L�D0,A1ŠPAGE*(*ˆDO�COMMON�REGISTER�SETUP�FOR�ALL�CASES*.ŠBCLRW‚#FAFLIB,FATFLG(A4)�CLEAR�FAB�INPUT�FLAG&ŠMOVE.L�FATFAA(A4),A3†FAB�BUFFER�START ŠMOVE.L�FATFAE(A4),A5†BUFFER�ENDŠMOVE.L�FATFAB(A4),D1†FAB�PSN/ŠMOVE.L�FATCFP(A4),A0†CURRENT�FAB�ENTRY�POINTERŠCLR.L‚D0‘CLEAR�RETURN�FLAG'ŠCLR.L‚D5‘CLEAR�REGISTER�FOR�BYTE�MOVES$ŠJMP„(A1)�BRANCH�TO�HANDLE�DIRECTIVE**ˆGETFDB�DIRECTIVE�JUMP�TABLE*�NO�CURRENT�FAB�ENTRY ŠTST.L‚D0 ŠBRA.S‚GTFBRTŠPAGE**7*ˆGET�FAB/SEGMENT�CORRESPONDING�TO�LRN�IN‚D3‚**LRNFDB****GTFR00„EQU„*’LRNFDB*$ŠMOVE.L�FCBDIR+DIREOR(A2),D2�EOF�LRN:ŠMOVE.L�#FATFLR+(FATSLR*$10000),D6�1ST�LRN�FOR�CURRENT�FAB6ŠMOVE.L�#FATLLR+(0*$10000),D7�LAST�LRN�FOR�CURRENT�FAB7ŠBRA.S‚GTFSRC�GO�DO�COMMON�PROCESSING�FOR�LRNFAB/LSNFAB**;*ˆGET�FAB�AND�SEGMENT�CORRESPONDING�TO�LSN�IN�D3‚**LSNFDB***  *GTFS00„EQU„*’LSNFDB*=ŠMOVE.L�FCBDIR+DIREOF(A2),D2�SETUP�CALL�PARAMETERS�FOR�LSNFDB$ŠMOVE.L�#FATFLS+(FATSLS*$10000),D6�. ŠMOVE.L�#FATLLS+(-1*$10000),D7�.9ŠMOVE.L�(A7),D0ŒCHECK�IF�EOF/LSN�RANGE�TEST�TO�BE�IGNOREDŠBTSTW‚#EOFFLGB,D0ˆ.ŠBNE.S‚GTFC00�YES*;GTFSRC„EQU„*ŽCOMMON�CODE�TO�FIND�FAB/SEGMENT�FOR�LSN�OR�LRN*%*ˆCHECK�LSN/LRN�FOR�ERROR�OR�PAST�EOF*ŠMOVE.L�#-1,D0ŠCMP.L‚D0,D3ŽLSN/LRN�=�-1?ŠBEQ„GTFBEF�YES,�NO�FABS�EXISTŠADD.L‚#1,D2ŽEMPTY�FILE?(ŠBEQ„GTFBEF�YES,�LSN/LRN�IS�OUT�OF�RANGE ŠSUB.L‚#1,D2"ŠCMP.L‚D2,D3ŽLSN/LRN�OUT�OF�RANGE?ŠBHI„GTFBEF�YES,�ERROR*>*ˆJUST�RETURN�IF�CURRENT�SEGMENT�SATISFIES�REQUEST�AND�FMS�HAS@*ˆBUFFER,�IF�NOT�MUST�READ�DATA�BLOCK�TO�MAKE�SURE�USER�BUFFER�O* GTFC00„EQU„*ŠTST.L‚D1‘A�FAB�IN�MEMORY?FŠBEQ.S�GTFC40�NO�-�START�SEARCH�FROM�1ST�FAB�UNLESS�LAST�LSN/LRN�WANTE8ŠCMP.L‚A0,D5�YES,�ANY�CURRENT�SEGMENT?�(A0�=�FATCFP�=�0)ŠBEQ.S‚GTFC20�NO<ŠMOVE.L�FATSLS(A4),D0†YES,�COMPARE�LSN/LRN�TO�SEGMENT�BOUNDS8ŠMOVE.B�FABSGS(A0),D5†#�OF�SECTORS�IN�CURRENT�DATA�BLOCKŠTST.L‚D7‘LSNFDB?ŠBMI.S‚GTFC10�YES ŠMOVE.L�FATSLR(A4),D0†NO,�LSRFDB1ŠMOVE.W�FABREC(A0),D5†GET�#�OF�RECORDS�IN�SEGMENTGTFC10„ADD.L‚D0,D5ŽUPPER�BOUND ŠCMP.L‚D3,D0$ŠBHI.S‚GTFC15�NOT�IN�CURRENT�SEGMENTŠCMP.L‚D5,D3ŽLOWER�BOUND$ŠBCC.S‚GTFC15�NOT�IN�CURRENT�SEGMENTEŠBTSTW‚#FAFLSB,FATFLG(A4)�JUST�RETURN�UNLESS�FMS�DOES�NOT�HAVE�BUFFER ŠBNE„GTFBGR�FMS�OWNS�BUFFER-DONE3ŠBRA„GTFBR0�MUST�READ�SINCE�USER�CAN�SWITCH�BUFFERS*#*ˆFIND�FAB�CORRESPONDING�TO�LSN/LRN*"GTFC15„CLR.L‚D0‘NO�KEY�UPDATE�FLAG;ŠBSR„PUTDATˆSWITCH�BLOCKS,�WRITE�OUT�CURRENT�ONE�IF�CHANGEDŠBNE„GTFBRT�ERROR5ŠCLR.L‚FATCFP(A4)‰SET�NO�CURRENT�SEGMENT�TILL�FIND�ITŠCLR.L‚D5‘D5.L�=�0�AGAIN!GTFC20„TST.L‚D3‘FIRST�FAB�WANTED?ŠBEQ.S‚GTFC25�YESŠCMP.L‚D2,D3ŽLAST�FAB�WANTED?ŠBEQ.S‚GTFC30�YES3ŠBRA.S‚GTFC45�NO,�GO�CHECK�CURRENT�FAB�FOR�/LSN/LRN*-GTFC25„BSR„GTFFSR�GET�FIRST�FAB/FIRST�SEGMENT ŠBRA.S‚GTFC35>FC30„BSR„GTFLSR�GET�LAST�FAB/SEGMENT1GTFC35„BEQ„GTFBR0�GO�READ�DATA�BLOCK�IF�REQUESTEDŠBRA.S‚GTFCER�ERROR�OR�NO�FAB!GTFC40„CMP.L‚D2,D3ŽWANT�LAST�FAB?ŠBEQ.S‚GTFC30�YESAŠBSR„GTFFSR‚NO,�START�SEARCH�WITH�FIRST�FAB�WHEN�NO�FAB�IN�MEMORYŠBNE.S‚GTFCER�ERROR?*%*ˆCHECK�CURRENT�FAB�FOR�LSN/LRN�RANGE*2GTFC45„EQU„*’START�LOOKING�FROM�1ST�SEGMENT�IN�FABŠMOVE.B�FABPKY(A3),D5†.ŠLEA„FABSEG(A3,D5),A0ƒ./GTFC50„MOVE.L�FATFAB(A4),D1†GET�CURRENT�FAB�PSN?ŠCMP.L‚0(A4,D6),D3†CHECK�LOWER�BOUND�FOR�LSN/LRN�-�IN�THIS�FAB?8ŠBCS.S‚GTFC55�.�NO,�GO�GET�PREVIOUS�FAB�-BACKWARD�SEARCH3ŠCMP.L‚0(A4,D7),D3ˆCHECK�UPPER�BOUND�-�IN�THIS�FAB?ŠBLS.S‚GTFC65�.�YES,�FOUND�FAB/ŠBSR„GTFNSR�.�NO,�GET�NEXT�FAB�-�FORWARD�SEARCH ŠBRA.S‚GTFC60GTFC55„BSR„GTFPSR�PREVIOUS�FAB4GTFC60„BEQ.S‚GTFC50�GO�SEE�IF�LSN/LRN�IS�IN�THIS�FABGTFCER„BRA„GTFBER�ERROR*5*ˆFAB�FOUND�-FIND�SEGMENT�CORRESPONDING�TO�LSN�OR�LRN*5GTFC65„MOVE.L�0(A4,D6),D0ˆGET�STARTING�LSN/LRN�OF�FAB?ŠBSR„SETFSL„INITIALIZE�FOR�SEGMENT�STARTING�LSN/LRN�CALCULATION&ŠCLR.L‚D1‘CLEAR�D1�FOR�BYTE/WORD�MOVES&ŠCLR.L‚D4‘CLEAR�D4�FOR�BYTE/WORD�MOVESŠSWAPƒD6‘SWITCH�OFFSETS ŠSWAPƒD7‘.AGTFC70„MOVE.B�FABKEY(A0),D5†KEY�FIELD�LENGTH�OF�CURRENT�FAB�ENTRY=ŠLEA„FABSSL(A0,D5),A5ƒA5�->�NEXT�FAB�ENTRY,�A0�->�CURRENT�ONEŠCMP.L‚D0,D3ŽEQUAL?!ŠBEQ.S‚GTFBRD�YES,�THIS�IS�THE�SDŠBCC.S‚GTFCIE.1‹BRANCH�IF�OK.ŠBSR„ISTAUFRR‹.LT.�=>�UNRECOVERABLE�FILE�ERRORGTFBEX.1‚BRA„GTFBEXGTFCIE.1‚EQU„****ˆGET�LSN/LRN�UPPER�BOUND�FOR�THIS�SEGMENT*.ŠMOVE.B�FABSGS(A0),D4†GET�SECTOR�COUNT�INTO�D4.ŠMOVE.W�FABREC(A0),D1†AND�RECORD�COUNT�INTO�D1ŠTST.W‚D7‘D7.W�=�0�IF�LRNFDBŠBEQ.S‚GTFC75�LRNFDB!ŠADD.L‚D4,D0ŽLSNFDB:�COMPARE�LSNS ŠBRA.S‚GTFC80'GTFC75„ADD.L‚D1,D0ŽLRNFDB:�COMPARE�LRNS.GTFC80„CMP.L‚D3,D0ŽIS�LSN/LRN�IN�THIS�SEGMENT?ŠBHI.S‚GTFBRD�YESFŠADD.L�D4,FATSLS(A4)�NO,�TRY�NEXT�SEGMENT�-�UPDATE�SEGMENT�LSN�AND�LRNŠADD.L‚D1,FATSLR(A4)†./ŠMOVE.L�A5,A0Ž.�A0�->�NEXT�SEGMENT�TO�BE�TESTED.ŠMOVE.L�FATFAE(A4),A5†PAST�END�OF�FAB�ENTRIES?ŠSUB.L‚#3,A5Ž.ŠCMP.L‚A5,A0Ž.ŠBCS.S‚GTFCIE.2‹BRANCH�IF�NOT,ŠBSR„ISTAUFRR‹YES�  -�UNRECOVERABLE�FILE�ERRORGTFBEX.2‚BRA.S‚GTFBEX.1+GTFCIE.2‚TST.L‚(A0)�OR�NO�MORE�FAB�ENTRIES?ŠBNE„GTFC70�YES ŠBSR„ISTAUFRR‹NO,�INTERNAL�ERRORGTFBEX.3‚BRA.S‚GTFBEX.2ŠPAGE*!*ˆREAD�IN�DATA�BLOCK�IF�REQUESTED*AGTFBRD„MOVE.L�A0,FATCFP(A4)†SET�CURRENT�SEGMENT�FAB�ENTRY�POINTER*GTFBR0„MOVE.L�(A7),D0ŒGET�READ�FLAG�STATUSŠBTSTW‚#RDBFLGB,D0ˆ.ŠBEQ„GTFBGR�NO�READ�REQUESTED#ŠCLR.L‚D5‘D5�CLEARED�FOR�BYTY�MOVES7ŠMOVE.L�(A0),D0ŒGET�FABPSN=PSN�OF�DATA�BLOCK�TO�BE�READ-ŠMOVE.L�FATSBS(A4),A3†BUFFER�STARTING�ADDRESS(ŠMOVE.B�FABSGS(A0),D5†GET�ENDING�ADDRESSŠMULUƒ#SECSZE,D5‰.ŠSUB.L‚#1,D5Ž.*ŠADD.L‚A3,D5ŽGET�ENDING�ADDRESS�FOR�BUFFER,ŠMOVE.L�D5,FATSBL(A4)†AND�SET�AS�LOGICAL�END&ŠMOVE.L�A3,D1Ž(GET�REG�ODER�FOR�MACRO)@ŠSETSBA�D0,D1,D5,VDTIOS(A6)�SET�PSN,BUFFER�START�AND�END�ADDRESS>ŠSETFO‚IOREAD,IOPRAN+IOPIMG,VDTIOS(A6)�SET�COMMAND�AND�OPTIONS7*FIRST CHECK TO SEE IF DATA BLOCK IS IN ANOTHER SEGMENT ŠBSR„CHKMA!ŠBEQ„GTFBR0LŒNO�OTHER�ASSIGNMENTS ŠMOVE.L�A0,D0%ŠSUB.L‚FATFAA(A4),D0†D0=OFFSET�TO�CFP*GO THROUHG OTHER FATSŠMOVE.L�FATSTR,A1GTFBR0BƒCMP.L‚A4,A1&ŠBEQ.S‚GTFBR0CŒSKIP�OVER�CURRENT�ENTRY*DOES FMS OWN DB FOR THIS USER?ŠBTSTW‚#FAFLSB,FATFLG(A1)ŠBEQ.S‚GTFBR0CŒNO-SKIP*FAT'S MUST HAVE SAME FCBŠMOVE.L�FATFCB(A1),D1ŠCMP.L‚FATFCB(A4),D1ŠBNE.S‚GTFBR0CŠMOVE.L�FATFAB(A1),D1ŠCMP.L‚FATFAB(A4),D1ŠBNE.S‚GTFBR0CŒNOT�RIGHT�FABŠMOVE.L�FATCFP(A1),D1ŠSUB.L‚FATFAA(A1),D1ŠCMP.L‚D0,D1ŽSAME�CFP?ŠBEQ.S‚GTFBR0EŒYES-USEGTFBR0CƒLEA„FATLEN(A1),A1ŠCMP.L‚FATEND,A1ŠBLS.S‚GTFBR0BŒCHECK�NEXT�FATŠBRA.S‚GTFBR0LŒDB�NOT�IN�MEMORY&*DB IS IN MEMORY-TRANSFER TO THIS USERGTFBR0EƒMOVE.L�A0,-(A7)‹SAVE�A0/ŠMOVE.L�VDTIOS+IOSSAD(A6),D1�D1=START�OF�BUFFER#ŠBSR„GETOSG�ATTACH�TO�OTHER�SEGMENT-*IF DB IS IN FMS SEGMENT, MOVE BYTES DIRECTLYŠBTSTW‚#FAFLSB,FATFLG(A4) ŠBEQ.S‚GTFBR0HŒNOT�IN�FMS�BUFFERŠMOVE.L�D1,A0ŽSTART�OF�THIS�DB'ŠMOVE.L�FATSBS(A1),A1†START�OF�OTHER�DBGTFBR0GƒMOVE.L�(A1)+,(A0)+ŠCMP.L‚D5,A0ŽAT�END?ŠBLS.S‚GTFBR0GŒNOŠBRA.S‚GTFBR0K*MUST DO L-L MOVEGTFBR0HƒBSR„SMOVE41ŠMOVE.L�FATSBS(A1),MVSADD(A0)�SET�UP�SOURCE�ZDDR.ŠMOVE.L�D1,MVDADD(A0) ŠMOVE.L�D5,D0 ŠSUB.L‚D1,D0 ŠADD.L‚#1,D0ŠMOVE.L�D0,MVLENG(A0)ŠERQ.MOVELL�(A0) ŠBSR„FTL.NE;*DATA HAS BEEN TRANSFERRED-RE-ATTACH TO COMMON DATA SEGMENT+GTFBR0KƒBSR„GETCSG�ATTACH�TO�COMMON�SEGMENTŠMOVE.L�(A7)+,A0‹RESTORE�A0ŠBRA.S‚GTFBR1A0GTFBR0LƒBTSTW‚#FAFLSB,FATFLG(A4)�FMS�HAS�BUFFER?ŠBNE.S‚GTFBR1�YESCŠMOVE.L�FATTSK(A4),VDTIOS+IOSTSK(A6)�NO,�DO�TRANSFER�TO�USER�BUFFERCŠMOVE.L�FATSES(A4),VDTIOS+IOSSES(A6)�SET�USER�TASK�ID�AND�SESSION�#?ŠBSETW‚#IOPTSKB,VDTIOS+IOSOPT(A6)�SET�FLAG�FOR�TASK�ID�SUPPLIEDGTFBR1„MOVE.L�A0,-(A7)‹SAVE ŠBSR„DOIOŠMOVE.L�(A7)+,A0 ŠBNE.S‚GTFBR9 GTFBR1AƒEQU„**5*ˆADJUST�LOCICAL�END�POINTER�IF�FRL�OR�FMS�HAS�BUFFER*.ŠMOVE.W�FCBDIR+DIRLRL(A2),D0�GET�RECORD�LENGTH%ŠBEQ.S‚GTFBR4�VARIABLE�RECORD�LENGTH?,ŠMULUƒFABREC(A0),D0†NO,�FRL�-�GET�BUFFER�BCT+ŠADD.L‚D0,A3ŽGET�END�OF�LAST�RECORD�POINTERGTFBR2„SUB.L‚#1,A3Ž.4GTFBR3„MOVE.L�A3,FATSBL(A4)†IT�IS�BUFFER�LOGICAL�END GTFBR3AƒEQU„*ŠIFEQƒFMSLEVEL-35ŠBSR„CMBNDB�TRY�TO�COMBINE�BLOCK�WITH�NEXT�DATA�BLOCK ŠBEQ„GTFBGRŠBRA.S‚GTFBR9�ERRORŠENDCŠIFEQƒFMSLEVEL-2 ŠBRA„GTFBGRŠENDC*/GTFBR4„BTSTW‚#FAFLSB,FATFLG(A4)�FMS�HAS�BUFFER?4ŠBEQ.S‚GTFBR3AŒNO,�LOGICAL�END�AT�END�OF�LAST�SECTOR;ŠCMP.L‚FATSBE(A4),D5†YES,�JUST�READ�IN�LAST�PAGE�OF�BUFFER?ŠBEQ.S‚GTFBR4AŒYES:ŠMOVE.L�D5,A1ŒNO,�SET�NEXT�WORD�AFTER�LAST�SECTOR�READ�=�0DŠADD.L‚#1,A1�.�SO�SHARED�BUFFER�USERS�KNOW�WHERE�BUFFER�ENDS�WITHOUT"ŠCLR.W‚(A1)�.�PROBLEMS�IF�VRL�FILE1GTFBR4AƒCLR.L‚D1‘COUNT�RECORDS�-�INITIALIZE�COUNT ŠCLR.L‚D0‘.,GTFBR5„CMP.L‚FATSBL(A4),A3†AT�END�OF�BUFFER?ŠBHI.S‚GTFBR2�YES$ŠMOVE.W�(A3)+,D0‹GET�NEXT�RECORD�BCTŠBEQ.S‚GTFBR8�END�OF�RECORDS?ŠBTSTW‚#0,D0ŽODD�LENGTH�RECORDŠBEQ.S‚GTFBR6�NO"ŠADD.L‚#1,D0ŽYES,�SKIP�FILLER�BYTE-GTFBR6„ADD.W‚#1,D1ŽNO,�INCREMENT�RECORD�COUNTŠADD.L‚D0,A3ŽGET�NEXT�RECORDŠBRA.S‚GTFBR5�SKIP�NEXT�RECORD*AGTFBR8„SUB.L‚#3,  A3ŠGET�A3�->ING�TO�END�OF�LAST�RECORD�(LAST�BYTE)6ŠCMP.W‚FABREC(A0),D1†FAB�INFO�MATCHES�WITH�DATA�BLOCK?ŠBEQ.S‚GTFBR3�YES/ŠMOVE.L�#NL+ISTAFD,D0†NO,�RECORD�COUNT�CONFLICTGTFBEX.4‚EQU„*�NEXT�FAB�ENTRY-ŠCMP.L‚FATFAE(A4),A1†PAST�THE�END�OF�THE�FAB?ŠBLO.S‚GTFK16�BRANCH�IF�NO�-�OKŠBSR„ISTAUFRR‹HANDLE�CE�ERRORGTFBEX.7‚BRA.S‚GTFBEX.66GTFK17„BSR„CHKKEY�NOW�COMPARE�WITH�PRIOR�DB'S�LAST�KEYFŠBEQ.S�GTFK25�EQUAL�KEYS�=>�WANTED�KEY�IN�PRIOR�DB�UNLESS�CURR.�DB�=�1<ŠBRA.S‚GTFK20‰KEYS�NOT�EQUAL,�1ST�RECORD�OF�CURRENT�DB�IS�ITGGTFK19„MOVE.L�D1,A0…LOWER�BOUND�OK,�TEST�UPPER�BOUND�FOR�KEYS�IN�SEGMENAŠADD.L‚#FABKEY,A0„.�A0->LAST�KEY�IN�SEGMENT�AS�SAVED�IN�FAB�ENTRY ŠBSR„CHKKEY�.4ŠBLS.S‚GTFK20�KEY�IS�IN�CURRENT�SEGMENT,�JUST�RETURN4ŠBSR„LASTSG�IS�CURRENT�SEGMENT�THE�LAST�ONE�IN�FILE?"ŠBNE.S‚GTFK30�NO,�GO�SWITCH�BLOCKS=GTFK20„BRA„GTFBGRŒYES,�KEY�INSERT�POSITION�IS�AT�END�OF�BLOCK=GTFK25„TST.L‚FATSLS(A4)‰INSERT�1ST�KEY�IF�CURRENT�SEG�IS�1ST?ŠBEQ.S‚GTFK20�YES,�JUST�RETURN*!*ˆKEY�IN�CURRENT�FAB'S�KEY�RANGE?*"GTFK30„CLR.L‚D0‘NO�KEY�UPDATE�FLAG3ŠBSR„PUTDAT�WRITE�OUT�CURRENT�DATA�BLOCK�IF�CHANGEDŠBNE„GTFBRT�ERROR5ŠCLR.L‚FATCFP(A4)‰SET�NO�CURRENT�SEGMENT�TILL�FIND�IT5GTFK35„LEA„FABPKY(A3),A0†SET�A0->1ST�KEY�FIELD�OF�FAB ŠBSR„CHKKEY�.3ŠBLS„GTFK70�KEY�IS�IN�A�PRIOR�FAB�-�BACKWARD�SEARCH&ŠMOVE.L�FATKEY(A4),A0†TEST�UPPER�BOUND ŠBSR„CHKKEY�.6ŠBHI„GTFK75�KEY�IN�SOME�FAB�AFTER�THIS,�FORWARD�SEARCH**ˆYES,�FIND�SEGMENT�FOR�KEY*,GTFK40„CLR.W‚D5‘GET�A3->ING�TO�1ST�FAB�ENTRYŠMOVE.B�FABPKY(A3),D5†.ŠLEA„FABSEG(A3,D5),A3ƒ./ŠBSR„SETFSL�INITIALIZE�SEGMENT�STARTING�LSN/LRN*ŠBRA.S‚GTFK50�GO�SEE�IF�KEY�IS�1ST�SEGMENTCGTFK45„MOVE.B�FABSGS(A3),D5†INCREMENT�STARTING�LSN�FOR�NEXT�SEGMENTŠADD.L‚D5,FATSLS(A4)†.=ŠMOVE.W�FABREC(A3),D5†INCREMENT�STARTING�LRN�FOR�NEXT�SEGMENTŠADD.L‚D5,FATSLR(A4)†.ŠCLR.W‚D5‘D5=0(ŠADD.L‚#FABKEY,A3‰GET�NEXT�ENTRY�POINTER#ŠMOVE.B�(A3)+,D5‹.�KEY�FIELD�LENGTHŠBNE.S‚GTFBIE.4‹BRANCH�IF�OK7ŠBSR„ISTAIERR‹INTERNAL�ERROR�-�KEY�LGTH.�MUST�BE�.GE.�4GTFBEX.8‚BRA„GTFBEX.7)GTFBIE.4‚ADD.L‚D5,A3ŽA3�->�NEXT�FAB�ENTRYŠLEA„-3(A5),A0ŠCMP.L‚A0,A3ŽAT�END�OF�FABŠBCC.S‚GTFK55�YES/ŠTST.L‚(A3)�ERROR�IF�CAN'T�FIND�SEGMENT�FOR�KEYŠBEQ.S‚GTFK55�.>FK50„EQU„*’CURRENT�FAB�ENTRY�POINTER*ŠLEA„FABKEY(A3),A0†IS�KEY�IN�THIS�SEGMENT?9ŠMOVE.L�A3,FATCFP(A4)†.�SAVE�ENTRY�ADR�IN�CASE�THIS�IS�IT ŠBSR„CHKKEY�."ŠBHI.S‚GTFK45�NO,�TRY�NEXT�SEGMENT#ŠBRA.S‚GTFK60�GO�READ�DATA�BLOCK�IN/GTFK55„M  OVE.L�FCBDIR+DIRFE(A2),D0�LAST�SEGMENT?ŠCMP.L‚FATFAB(A4),D0†.ŠBEQ.S‚GTFBIE.5‹BRANCH�IF�ERRORŠBSR„ISTAIERR‹NO,�ERROR ŠBRA„GTFBEX.8CGTFBIE.5‚SUB.L‚D5,A3ŠYES,�INSERT�TO�END�OF�FILE,�GET�LAST�FAB�ENTRY#ŠSUB.L‚#FABSSL,A3‰.�POINTER�INTO�A38ŠMOVE.B�FABSGS(A3),D5†RESET�LRN�AND�LSN�FOR�LAST�SEGMENTŠSUB.L‚D5,FATSLS(A4)ŠMOVE.W�FABREC(A3),D5ŠSUB.L‚D5,FATSLR(A4) ŠCLR.W‚D5GTFK60„MOVE.L�A3,A0#ŠBRA„GTFBR0�GO�READ�IN�LAST�SEGMENT*3*ˆKEY�IS�IN�A�PREVIOUS�FAB�OR�IN�A�FAB�THAT�FOLLOWS*"GTFK70„TST.L‚FATFLS(A4)‰FIRST�FAB?0ŠBEQ„GTFK40�YES,�KEY�BELONGS�TO�FIRST�DATA�BLOCK ŠBSR„GTFPSR�NO,�GET�PREVIOUS�FAB ŠBRA.S‚GTFK80GTFK75„TST.L‚(A3)�LAST�FAB?#ŠBEQ„GTFK40�YES,�KEY�AT�END�OF�FILEŠBSR„GTFNSR�NO,�GET�NEXT�FAB)GTFK80„BEQ„GTFK30�GO�CHECK�NEW�FAB'S�KEYS0ŠBRA„GTFBRT�NO�FAB�OR�ERROR,�KEY�CANNOT�BE�FOUND GTGT00„EQU„* GTGE00„EQU„* GTLT00„EQU„*(ŠMOVE.L�#NL+ISTAIF,D0†NO�ACTION�HERE�YET ŠBRA„GTFBRTŠPAGEŠENDC**‚GETFDB�SUBROUTINES**'* FABINP GETS SPECIFIED FAB INTO MEMORY&*ˆCHANGED�FAB�BLOCK�IS�UPDATED�IF�NEC.** ENT: D1 PSN OF FAB TO GET*…A4=FAT�ADDR.*†A3�=�FAB�BUFFER�FWA*†A5�=�FAB�BUFFER�LWA*…A6=VDT�ADDRESS*/* RET: D0 = 0 IF NO ERROR, ELSE IO ERROR STATUS*†A0�->�1ST�SD�OF�FAB*†D1�-�UNKNOWN*†Z�-�1�IF�NO�ERROR&*†Z�-�0�IF�ERROR�AND�D0�=�ERROR�STATUS***INDENTED LIST$* FABINP GETS SPECIFIC FAB IN MEMORY*FABINP* UPDATE CURREN FAB $PUTFAB* FAB-IN OTHER USER'S BUFFER?*‚YES,MOVE�FAB-IN�MEMORY *‚NO,READ�FAB-FROM�DISK�$IOSREAD* MARK FAB-IN MEMORYY* ERROR-IF EMPTY FAB*INDENTED LIST END* FABINP„EQU„**ŠMOVE.L�A1,-(A7)+ŠBSR„PUTFAB�UPDATE�CURRENT�FAB�IF�NECESSARYŠBNE.S‚FABIRT�I/O�ERRORCŠSETSBA�D1,A3,A5,VDTIOS(A6)�SET�PSN,�BUFFER�START�AND�END�ADDRESSES-ŠCLR.L‚FATFAB(A4)‰CLEAR�FAB�PSN�IN�CASE�ERROR0*SEE IF FAB CAN BE TRANSFERRED FROM ANOTHER USER ŠBSR„CHKMAŠBEQ.S‚FABI50�NO�OTHER�ASSIGN.*GO THROUGH OTHER FATSŠMOVE.L�FATSTR,A1FABI10„CMP.L‚A1,A4#ŠBEQ.S‚FABI15�SKIP�OVER�CURRENT�FAT*FAT'S MUST HAVE SAME FCBŠMOVE.L�FATFCB(A1),D0ŠCMP.L‚FATFCB(A4),D0 ŠBNE.S‚FABI15ŠCMP.L‚FATFAB(A1),D1 ŠBEQ.S‚FABI20FABI15„LEA„FATLEN(A1),A1ŠCMP.L‚FATEND,A1ŠBLS.S‚FABI10�CHECK�NEXT�FATŠBRA.S‚FABI50�NOT�IN�MEMORY'*FAB IS IN MEMORY-TRANSFER TO THIS USER*FABI20„BSR„GETOSG�ATTACH�TO�OTHERE�SEGMENT3*MOVE DATA FROM OTHER FAB TO THIS USER'S FAB BUFFER"ŠMOVE.L�A3,A0ŽSTART�OF�CURRENT�FAB(ŠMOVE.L�FATFAA(A1),A1†START�OF�OTHER�FABFABI30„MOVE.L�(A1)+,(A0)+ŠCMP.L‚A5,A0ŽAT�END?ŠBLS.S‚FABI30�NO#*DATA HAS BEEN MOVED FROM OTHER FAB1*…TO�THIS�USER'S�FAB-DE-ATTACH�FROM�OTHER�SEGMENT!*…AND�RE-ATTACH�TO�SHARED�SEGMENT$ŠBSR„GETCSG�ATTACH�TO�COMMON�SEGMENT ŠBRA.S‚FABI55!FABI50„BSR„IOSREADŒREAD�WITH�WAITŠBNE.S‚FABIRT�YES/FABI55„MOVE.L�D1,FATFAB(A4)†SET�CURRENT�FAB�PSN#ŠCLR.L‚D0‘GET�1ST�FAB�ENTRY�POINTERŠMOVE.B�FABPKY(A3),D0†.+ŠLEA„FABSEG(A3,D0),A0ƒA0�->�FIRST�SD�OF�FAB'ŠCMP.L‚FATFAE(A4),A0†BEYOND�END�OF�FAB?!ŠBLO.S‚FABI55.1‹BRANCH�IF�NO�-�OK&ŠBSR„ISTAUFRR‹UNRECOVERABLE�FILE�ERROR ŠBRA.S‚FABIRT)FABI55.1‚MOVE.L�#NL+ISTAFAB,D0…EMPTY�FAB? ŠTST.L‚(A0)�.ŠBEQ.S‚FABIRT�YESFŠBSETW�#FAFLIB,FATFLG(A4)�SET�FAB�INPUT�FLAG�(=>�TRY�TO�COMBINE�WITH�N2ŠBCLRW‚#FAFLMB,FATFLG(A4)�FLAG�OFF�FOR�MERGE�FAB'SŠCLR.L‚D0‘SET�GOOD�RETURN�FLAGS FABIRT„EQU„*ŠMOVE.L�(A7)+,A1ŠRTSŠPAGE*?*ˆGET�NEXT,�PRIOR,�LAST,�AND�FIRST�FAB�ROUTINES�USE�SAME�RETURN%*ˆINSTRUCTIONS�AS�GETFDB�TO�SAVE�CODE**ˆGET�NEXT�FAB*2GTFNSR„MOVEM.L�D1-D7/A3/A1/A5,-(A7)�SAVE�REGISTERS* ŠCLR.L‚D0'ŠMOVE.L�FATFAB(A4),D1†NO�FAB�IN�MEMORY?)ŠBEQ.S‚GTFIER�NO�-�FAB�NOT�FOUND�-�RETURN,ŠMOVE.L�(A3),D1ŒFORWARD�LINK(FABFLK)�EXISTS?"ŠBEQ.S‚GTFIER�NO�-�ERROR�-�NO�FABS*#*ˆGET�NEXT�FAB�IN�CHAIN�INTO�MEMORY*-GTFN05„BSR„FABINP�READ�IN�FAB�WITH�PSN�=�D1.LŠBNE.S‚GTFIRT�ERROR***ˆSETUP�FIRST�SD�AS�CURRENT�SEGMENT�IN�FAB*9ŠMOVE.L�FATLLS(A4),D0†GET�NEW�FAB'S�1ST�LSN�FROM�LAST�FABŠADD.L‚#1,D0Ž.ŠMOVE.L�D0,FATFLS(A4)†.5ŠMOVE.L�D0,FATSLS(A4)†IT�IS�ALSO�SEGMENT�STARTING�  LSNBŠMOVE.L�FATLLR(A4),D1„GET�NEW�FAB'S�1ST�LRN�FROM�PREVIOUS�FAB�INFOŠADD.L‚#1,D1Ž.$ŠMOVE.L�D1,FATFLR(A4)†1ST�LRN�OF�FAB5ŠMOVE.L�D1,FATSLR(A4)†STARTING�LRN�OF�CURRENT�SEGMENT7ŠBSR„GLLSFBŒGET�LAST�LSN�AND�LRN�FOR�FAB�INTO�D0�AND�D1ŠSUB.L‚#1,D0Ž.ŠSUB.L‚#1,D1Ž.4ŠSAVE2‚D0,D1,FATLLS(A4)ƒSAVE�LAST�LSN�AND�LSR�OF�FAB ŠBRA.S‚GTFIOK�NO�ERRORS�-‚RETURNGTFIER„BRA„GTFBERŠPAGE**ˆGET�PREVIOUS�FAB*2GTFPSR„MOVEM.L�D1-D7/A3/A1/A5,-(A7)�SAVE�REGISTERS* ŠCLR.L‚D0'ŠMOVE.L�FATFAB(A4),D1†NO�FAB�IN�MEMORY?ŠBEQ.S‚GTFIER�NO,�FAB�NOT�FOUND,ŠMOVE.L�FABBLK(A3),D1†YES,�GET�BACKWARD�LINK#ŠBEQ.S‚GTFIER�ERROR�NO�PREVIOUS�FAB(ŠBSR„FABINP�GET�PREVIOUS�FAB�INTO�MEMORYGTFIRT„BNE„GTFBRT�ERROR*-*ˆSETUP�1ST�SEGMENT�OF�FAB�AS�CURRENT�SEGMENT*.ŠMOVE.L�FATFLS(A4),D0†GET�LAST�LSN�FOR�NEW�FABŠMOVE.L�D0,D3Ž.�SAVE'ŠSUB.L‚#1,D0Ž.�D0�=�LAST�LSN�OF�NEW�FAB.ŠMOVE.L�FATFLR(A4),D1†GET�LAST�LRN�FOR�NEW�FABŠMOVE.L�D1,D4Ž.�SAVEŠSUB.L‚#1,D1Ž.9ŠSAVE2‚D0,D1,FATLLS(A4)ƒSAVE�LAST�LSN�AND�LRN�FOR�NEW�FAB ŠCLR.L‚D0 ŠCLR.L‚D1/ŠBSR„GLLSFB�GET�#�OF�SECTORS�AND�RECORDS�IN�FAB1ŠSUB.L‚D0,D3ŽD3�=�STARTING�LSN�OF�FAB�AND�SEGMENT-ŠSUB.L‚D1,D4ŽGET�STARTING�LRN�FOR�SEGMENT/FAB5ŠSAVE2‚D3,D4,FATFLS(A4)ƒSAVE�FAB�STARTING�LSN�AND�LRN9ŠSAVE2‚D3,D4,FATSLS(A4)ƒSAVE�SEGMENT�STARTING�LSN�AND�LRN9GTFIOK„BRA„GTFBOK�1ST�SEGMENT�IS�CURRENT�SEGMENT�-�RETURNŠPAGE**ˆGET�FIRST�FAB*2GTFFSR„MOVEM.L�D1-D7/A3/A1/A5,-(A7)�SAVE�REGISTERS*-ŠMOVE.L�FCBDIR+DIRFS(A2),D0�GET�1ST�FAB'S�PSN"ŠBEQ.S‚GTFIER�DOES�FILE�HAVE�FABS?ŠMOVE.L�FATFAB(A4),D10ŠCMP.L‚D0,D1ŽYES,�FIRST�FAB�CURRENTLY�IN�MEMORY?*ŠBEQ.S‚GTFF05�YES,�SET�FIRST�SD=CURRENT�SD)ŠMOVE.L�D0,D1ŽNO,�GET�1ST�FAB�INTO�MEMORYŠMOVE.L�#-1,D0%ŠMOVE.L�D0,FATLLS(A4)†SET�NO�LAST�LSN%ŠMOVE.L�D0,FATLLR(A4)†SET�NO�LAST�LRN"ŠBRA„GTFN05�CONTINUE�AS�FOR�NXTFAB*GTFF05„CLR.W‚D0‘GETŠMOVE.B�FABPKY(A3),D0†.-ŠLEA„FABSEG(A3,D0),A0ƒFIRST�FAB�ENTRY�POINTER3ŠTST.L‚FATSLS(A4)‰IS�CURRENT�SEGMENT�THE�FIRST�ONE?ŠBEQ.S‚GTFIOK�YES,�JUST�RETURNŠCLR.L‚D0‘FLAG�NO�KEY�UPDATE?ŠBSR„PUTDAT„NO,�UPDATE�CURRENT�DATA�BLOCK�SINCE�SWITCH�SEGMENTSŠBNE.S‚GTFLER�ERRORAŠBSR„SETFSL‚SET�SEGMENT�STARTING�LSN/LRN�=�FAB'S�STARTING�LSN/LRNŠBRA.S‚GTFIOK�RETURNŠPAGE**ˆGET�LAST�FAB*2GTFLSR„MOVEM.L�D1-D7/A3/A1/A5,-(A7)�SAVE�REGISTERS* ŠCLR.L‚D0$ŠMOVE.L�FATFAB(A4),D1†FAB�IN�MEMORY?ŠBEQ.S‚GTFL10�NO.ŠMOVE.L�FATFAA(A4),A1†YES,�IS�IT�THE�LAST�FAB?ŠTST.L‚(A1)�.�FORWARD�LINK�=�0ŠBEQ.S‚GTFL25�YES2GTFL10„MOVE.L�FCBDIR+DIRFE(A2),D1�ANY�FABS�AT�ALL? ŠBEQ„GTFIERŠBSR„FABINP�YES,�GET�LAST�FABGTFLER„BNE„GTFBRT�ERROR*7*ˆFOUND�LAST�FAB‚-‚LAST�SEGMENT�WILL�BE�THE�CURRENT�ONE*'GTFL15„CLR.L‚D0‘FLAG�NO�KEY�UPDATE�FLAG2ŠBSR„PUTDAT�UPDATE�CURRENT�DATA�BLOCK�IF�NECESSARYŠBNE„GTFLER�ERROR ŠCLR.L‚D1 ŠCLR.W‚D3‘GETŠMOVE.B�FABPKY(A3),D3†.)ŠLEA„FABSEG(A3,D3),A0ƒA0�->�1ST�FAB�ENTRY<ŠBSR„GLLSFB‡GET�FAB'S�SECTOR�AND�RECORD�COUNTS(A5->LAST�KEY):ŠGET2ƒFCBDIR+DIREOF(A2),D3,D4�GET�LAST�LSN�AND�LRN�OF�FILE4ŠSAVE2‚D3,D4,FATLLS(A4)ƒSAVE�LAST�LSN�AND�LRN�OF�FABŠADD.L‚#1,D3ŽGET�1ST�LSN�OF�FABŠMOVE.L�D3,D5Ž.ŠSUB.L‚D0,D3Ž.ŠADD.L‚#1,D4ŽGET�1ST�LRN�OF�FABŠMOVE.L�D4,D6Ž.ŠSUB.L‚D1,D4Ž. ŠCLR.L‚D09ŠMOVE.B�-(A5),D0‹GET�STARTING�LSN�OF�SEGMENT(D0.B=FABSGS)ŠSUB.L‚D0,D5Ž.6ŠMOVE.W�-(A5),D0‹GET�SEGMENT�STARTING�LRN(D0.W=FABREC)ŠSUB.L‚D0,D6Ž.5ŠTST.L‚-(A5)ŽSET�A5�->ING�TO�FABPSN�OF�LAST�FAB�ENTRY'ŠMOVE.L�A5,A0ŽCURRENT�FAB�ENTRY�POINTER@ŠSAVE4‚D3,D4,D5,D6,FATFLS(A4)�FAB�STARTING�LSN,LRN,FATSLS,FATSLRŠBRA„GTFBOK�RETURN*-GTFL25„EQU„*’IS�CURRENT�SEGMENT�THE�LAST�ONE?*ŠMOVE.L�FATCFP(A4),D1†ANY�CURRENT�SEGMENT?ŠBEQ.S‚GTFL15�NOŠBSR„LASTSG�YES,�IS�IT�LAST?ŠBEQ„GTFBGR�YES,�JUST�RETURN9ŠBRA.S‚GTFL15ŒNO,�UPDATE�CURRENT�SEGMENT,�GET�LAST�ONE�INŠPAGE**!*ˆ*********************************ŒPUTFAB�1.00�8/6/79�HBN6*!*ˆ*********************************@*‚PUTFAB�UPDATES�CURRENT�FAB�ON�DISK,�ERROR�IF�NO�FAB�IN�MEMORY.7*ˆNEXT�FAB'S�FABPKY�IS�UPDATED�IF�LAST�FAB�KEY�CHANGED.+*ˆCALL�IS�IGNORED�  IF�CHANGE�FLAG�IS�NOT�SET* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR$*ˆD0.B�=�ISTAFAB�IF�NO�FAB�IN�MEMORY*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR*/*‚PUTFAB�REFERENCES�FAT�AND�VDT,�CHANGES�VDTIOS"*ˆUSES�TEMPORARY�VIB-SECTOR�BUFFER**INDENTED LIST$* PUTFAB UPDATES CURRENT FAB ON DISK*PUTFAB PASS CURRENT FAB* FAB CHANGED FLAG SET?*‚NO,�SKIP�CALL,�RETURN!* YES,-GET FRACTION OF-FAB IN-USE* WRITE CURRENT FAB TO-DISK *‚$IOSWRITE* LAST FAB KEY CHANGED?#*‚YES,UPDATE�KEY-IN�NEXT-FAB�HEADER*ƒCALL�$NXTFHD* RETURN*INDENTED LIST END* PUTFAB„EQU„**,ŠMOVEM.L�A0-A1/A3/D1-D3,-(A7)�SAVE�REGISTERS$ŠCLR.L‚D0‘CLEAR�IN�CASE�CALL�SKIPPED&ŠBCLRW‚#FAFLFB,FATFLG(A4)�FAB�CHANGED?ŠBEQ.S‚PTFBRT�NO,�IGNORE�CALL*?ŠGET3ƒFATFAA(A4),A0,A1,A3�GET�FAB�BUFFER�START,�END�AND�FAB�PSNŠMOVE.L�A3,D0ŽFAB�IN�MEMORY?ŠBNE.S‚PTFB10�YES ŠMOVE.L�#NL+ISTAFAB,D0…NO,�ERROR ŠBRA.S‚PTFBRT*0*ˆGET�FAB'S�SECTORS-IN-USE�COUNT�INTO�FAB�HEADER* PTFB10„EQU„*FŠSETSBA�D0,A0,A1,VDTIOS(A6)�SET�PSN,�FAB�BUFFER�START�AND�END�FOR�WRITŠCLR.L‚D2‘INIT�FAB�USAGE�COUNTŠMOVE.L�A0,A3ŽFATFAAŠCLR.L‚D1‘TEST�FAB�EMPTYŠMOVE.B�FABPKY(A3),D1†.ŠLEA„FABSEG(A3,D1),A1ƒ. ŠTST.L‚(A1)ŠBNE.S‚PTFB11�EMPTY�FAB?@ŠCLR.L‚FATFAB(A4)…YES,�CLEAR�FAB�IN�MEMORY�POINTER�FOR�EMPTY�FAB#ŠCLR.L‚FATCFP(A4)‰NO�SEGMENT�EITHER ŠBRA.S‚PTFB155PTFB11„LEA„FABKEY(A1),A1†GET�POINTER�TO�LAST�FAB�BYTEŠMOVE.B�(A1)+,D1ŠLEA„2(A1,D1),A1ŠCMP.L‚FATFAE(A4),A1†FOUND�END?$ŠSUB.L‚#2,A1ŽCOND�CODE�NOT�DESTROYEDŠBCC.S‚PTFB13�YES ŠTST.L‚(A1)ŠBNE.S‚PTFB11�NOPTFB13ŠSUB.L‚A3,A1ŽGET�BCT�IN�USE1ŠMOVE.B�FCBDIR+DIRFAB(A2),D2�SECTOR�COUNT�FOR�FAB5ŠMULUƒ#SECSZE/16,D2†ONE�16TH�OF�BCT�AVAILABLE�FOR�FAB8ŠMOVE.L�A1,D0ŽNOW�CALCULATE�HOW�MANY�1/16�IN�USE�FOR�FAB ŠDIVUƒD2,D0Ž.ŠMOVE.B�D0,D2Ž.ŠSWAPƒD0!ŠTST.W‚D0‘.�USED�FRACTION�OF�ONE?ŠBEQ.S‚PTFB15�NO&ŠADD.B‚#1,D2ŽYES,�COUNT�IT�AS�ONE�ALSOGPTFB15„MOVE.B�D2,FABUSE(A3)…SET�COUNT�IN�FAB�HEADER�FOR�COMBINE�FAB�SBR**ˆWRITE�FAB�INTO�DISK@*ˆNOTE:�CANNOT�CLEAR�UNUSED�FAB�SPACE�HERE�SINCE�CALLED�BY�NEWFB*!ŠBSR„IOSWRITE‹WRITE�FAB�WITH�WAITŠIFEQƒFMSLEVEL-3 ŠBNE.S‚PTFBRT+ŠBCLRW‚#FAFLKB,FATFLG(A4)�LAST�KEY�CHANGED?ŠBEQ.S‚PTFBRT�NO,�DONE*1*ˆUPDATE�FAB'S�LAST�KEY�IN�NEXT�FAB�IF�ONE�EXISTS*ŠTST.B‚D1‘ANY�KEYS�AT�ALL?7ŠBEQ.S‚PTFBRT�NO�KEYS,�IGNORE�THAT�BIT�WAS�SET�(D0�=�0)$ŠMOVE.L�(A3),D3ŒGET�NEXT�FAB�POINTER5ŠMOVE.L�#-1,D0�UPDATE�KEY�(ONLY)�IN�NEXT�FAB'S�HEADER ŠBSR„NXTFHD�.ŠENDC5PTFBRT„MOVEM.L�(A7)+,D1-D3/A0-A1/A3�RESTORE�REGISTERSŠRTSŠPAGEŠENDCƒFMSLEVEL-1**%*ˆ*************************************ŒUPTDIR‚1.00‚8/3/79‚HBN6*%*ˆ************************************9*‚UPTDIR�UPDATES�CURRENT�DIRECTORY�ENTRY�IN�FCB�IN�MEMORY* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA2�=�FCB�ADDRESS* *‚ON�RETURN:%*ˆALL�REGISTERS�ARE�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR0*ˆD0.B�=�ISTAIE�IF�DIRECTORY�ENTRY�NOT�IN�MEMORY*�80+�IF�IO�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR* UPTDIR„EQU„**1ŠMOVE.L�FCBDBP(A2),D0†ANY�DIRECTORY�ENTRY�IN�FCB?ŠBNE.S‚UPDR00�YESŠBSR„ISTAIERR‹NO,�ERRORŠRTS)UPDR00„MOVEM.L�A0-A1,-(A7)‡SAVE�REGISTERS*4*ˆMOVE�DIR�ENTRY�IN�FCB�TO�DIRECTORY�BLOCK�IN�MEMORY*2ŠMOVE.L�D0,A1ŽGET�DIRECTORY�ENTRY'S�DB�INTO�MEMORY ŠBSR„GETDBŽ.ŠBNE.S‚UPDRRT�ERROR.ŠMOVE.W�FCBDBO(A2),D0†GET�ENTRY'S�OFFSET�IN�DB'ŠMOVE.L�VDTDMA(A6),A1†DB�BUFFER�ADDRESS(ŠADD.L‚D0,A1ŽA1�->�DIRECTORY�ENTRY�IN�DB/ŠLEA„FCBDIR(A2),A0†A0�->�DIRECTORY�ENTRY�IN�FCB4ŠMOVE.L�#DIRLEN/2,D0‡D0�=�DIRECTORY�ENTRY�WORD�COUNT3UPDR10„MOVE.W�(A0)+,(A1)+ˆMOVE�ENTRY�FROM�FCB�TO�DBŠDCNTƒD0,UPDR104ŠBSETW‚#VDFLDB,VDTFLG(A6)�SET�PDB�TO�BE�UPDATED�FLAGBŠBCLRW‚#FCFLDB,FCBFLG(A2)�FCB�DIRECTORY�ENTRY�UPDATED�-�CLEAR�FLAGŠCLR.L‚D0‘SET�GOOD�RETURN�FLAGS,UPDRRT„MOVEM.L�(A7)+,A0-A1‡RESTORE�REGISTERSŠRTSŠPAGEŠIFGTƒFMSLEVEL-1**#*ˆ***********************************ŒPUTDAT�1.00�10/16/79�HBN6*#*ˆ*********************************  *A*‚PUTDAT‚UPDATES�OR�CKECKS�CURRENT�FAB�ENTRY�ASSOCIATED�WITH�DATA8*ˆBLOCK,�THEN�IT�WRITES�CURRENT�DATA�BLOCK�TO�DISK.‚CALL8*ˆIS�IGNORED�IF�CURRENT�DATA�BLOCK�HAS�NOT�BEEN�CHANGED.* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS!*ˆD0�=�0�IF�NOT�TO�UPDATE�FAB�KEY*�1�IF�UPDATE�REQUESTED* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR!*ˆD0.B�=�ISTAIE�IF�INTERNAL�ERROR8*�ISTANZ,�ISTARWB,�ISTAFD,�OR�ISTARO�IF�DATA�BLOCK�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR**‚PUTDAT�CALLS�UPCFAB,�BLKWRT!*ˆREFERENCES�AND�UPDATES�FAT,�VDT* PUTDAT„EQU„**+*ˆIGNORE�CALL�IF�DATA�BLOCK�HAS�NOT�CHANGED*)ŠBCLRW‚#FAFLDB,FATFLG(A4)�CHANGE�FLAG�SETŠBNE.S‚PTDT00�YESŠCLR.L‚D0‘NO,�IGNORE�CALLŠRTS*=*ˆUPDATE�OR�CHANGE�FAB�ENTRY�ACCORDING�TO�DATA�BLOCK�CONTENTS*8PTDT00„SUB.L‚#1,D0ŽIN�UPCFAB,�FLAG�REVERSED�(0=>-1,1=>0)+ŠBSR„UPCFAB�ERROR�IF�NO�CURRENT�FAB�SEGMENT%ŠBNE.S‚PTDTRT�OR�DATA�BLOCK�MESSED�UP**ˆWRITE�CURRENT�BLOCK�TO�DISK* ŠBSR.S‚BLKWRT PTDTRT„RTSŠPAGE*#*ˆ***********************************ŒBLKWRT�1.00�10/16/79�HBN6*#*ˆ**********************************3*‚BLKWRT�WRITES�DATA�BLOCK'S�SECTORS�IN�USE�TO�DISK?*ˆTHE�DATA�BLOCK'S�SEGMENT�IS�EXPANDED�IF�IT�IS�NOT�DIRDAT�SIZE>*ˆ(THIS�IS�NOT�DONE�NOW�SINCE�ALL�BLOCK�SAME�SIZE).�IF�INDEXED1*ˆFILE�KEYS�ARE�CHECKED�TO�BE�IN�ASCENDING�ORDER.*ˆUNUSED�BUFFER�SPACE�IS�ZEROED**…SHOULDN'T�CALL�BLKWRT�IF�CONTIGUOUS�FILE* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS* *‚ON�RETURN:*ˆD0.L�=�0�IF�NO�ERROR"*ˆD0.B�=�ISTAIE�IF�CONTIGUOUS�FILE*�80+�IF�IO�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR* BLKWRT„EQU„**/ŠMOVEM.L�A0-A1/A3/D1/D3/D4,-(A7)�SAVE�REGISTERS7ŠGET2ƒFATSBS(A4),A0,A1ƒGET�BUFFER�START�AND�LOGICAL�ENDŠMOVE.L�A1,D0Ž.;ŠADD.L‚#1,D0ŠADJUST�END�OF�BUFFER�IF�NOT�AT�SECTOR�BOUNDARY!ŠSUB.L‚A0,D0Ž.�D0�=�BCT�OF�BUFFER-ŠAND.W‚#$FF,D0Œ.�LENGTH�OF�LAST�SECTOR�BUFFER.ŠBEQ.S‚BWRT10�.�LOGICAL�END�AT�SECTOR�BOUNDARYŠMOVE.W�#SECSZE,D1‰.9ŠSUB.W‚D0,D1Œ.�D1�=�REMAINING�UNUSED�BYTES�IN�LAST�SECTOR*>*ˆCLEAR�REMAINDER�OF�DATA�BUFFER�(UNUSED�SPACE�IN�LAST�SECTOR)*)ŠADD.L‚#1,A1ŽA1�->�1ST�BYTE�TO�BE�CLEARED*ŠLSR.W‚#1,D1ŽD1�=�WORD�COUNT�TO�BE�CLEAREDBWRT05„CLR.W‚(A1)+ŠDCNTƒD1,BWRT05'ŠSUB.L‚#1,A1ŽA1�->�END�OF�SECTOR�BUFFER>BWRT10„MOVE.L�FATCFP(A4),A3†GET�DATA�BLOCK'S�FAB�ENTRY�POINTER3ŠMOVE.L�(A3),D0ŒGET�STARTING�SECTOR�NUMBER�(FABPSN)CŠSETSBA�D0,A0,A1,VDTIOS(A6)�SET�PSN,�BUFFER�START�AND�END�FOR�WRITE*8*ˆCHECK�THAT�KEYS�ARE�IN�ASCENDING�ORDER�IF�INDEXED�FILE**ŠMOVE.B�FCBDIR+DIRATT(A2),D0�INDEXED�FILE?ŠAND.B‚#DFTBIT,D0‰.ŠCMP.B‚#DATSEQ,D0‰.ŠBEQ.S‚BWRT40�NO,�SEQUENTIALŠIFEQƒFMSLEVEL-3ŠCLR.L‚D4‘YES,�GET�KEY�SIZEŠMOVE.B�FCBDIR+DIRKEY(A2),D4�.,ŠMOVE.W�FCBDIR+DIRLRL(A2),D1�FRL�OR�VRL�FILE,BWRT15„MOVE.L�D4,D0ŽKEY�SIZE�FOR�CHKKEY�CALLŠCLR.L‚D3‘1/13/81‚D.VŠMOVE.W�D1,D3ŽFRL�FILE?ŠBNE.S‚BWRT20�YES&ŠMOVE.W�(A0)+,D3‹NO,�GET�RECORD�LENGTHŠBNE.S‚BWRTIE.1‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR�IF�0 ŠBRA.S‚BWRTRT BWRTIE.1‚BTSTW‚#0,D3ŽODD�LENGTH?ŠBEQ.S‚BWRT20�NO"ŠADD.W‚#1,D3ŽYES,�SKIP�FILLER�BYTEŠBNE.S‚BWRT20�BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR ŠBRA.S‚BWRTRT0BWRT20„LEA„0(A0,D3.L),A3†GET�NEXT�RECORD�POINTERŠMOVE.L�A3,D3Ž.ŠTST.W‚D1‘FRL?ŠBNE.S‚BWRT25�YES.ŠADD.L‚#BCTFLD,D3‰NO,�SKIP�RECORD�LENGTH�FIELD BWRT25„CMP.L‚FATSBL(A4),D3†DONE?ŠBHI.S‚BWRT40�YES,ŠBSR„CHKKEY1ŒNO,�CHECK�THESE�TWO�KEYS�ARE�OKŠBHI.S‚BWRT35�OKŠBNE.S‚BWRT30�NOT�OK4ŠBSR„DPLKEY�EQUAL�KEYS�OK�ONLY�IN�DUPLICATE�KEY�FILEŠBEQ.S‚BWRT35�OK%BWRT30„MOVE.B�#NL+ISTAKY,D0†KEY�ERROR ŠBRA.S‚BWRTRT&BWRT35„MOVE.L�A3,A0ŽGO�CHECK�NEXT�PAIR ŠBRA.S‚BWRT15ŠENDCƒFMSLEVEL-38BWRTRT„MOVEM.L�(A7)+,A0-A1/A3/D1/D3/D4�RESTORE�REGISTERSŠRTS**ˆWRITE�BLOCK�TO�DISK*1BWRT40„BSR„IOSWRITE‹UPDATE�BLOCK:�WRITE�WITH�WAITŠBNE„BWRTRT�ERROR7ŠBCLRW‚#FAFLDB,FATFLG(A4)�CLEAR�DATA�BLOCK�CHANGED�FLAG!ŠCLR.L‚D0‘RESET�GOOD�RETURN�FLAGSŠBRA„BWRTRT�RETURNŠPAGE* *#*ˆ***********************************ŒUPCFAB�1.00�10/16/79�HBN6*#*ˆ**********************************8*‚UPCFAB�UPDATES�OR�CHECKS�CURRENT�FAB�ENTRY�INFORMATION.*ˆACCORDING�TO�DATA�BLOCK�CONTENTS�TO�PRESERVE.*ˆDATA�BASE�INTEGRITY.‚RECORDS�MUST�BE�ALIGNED*ˆAT�WORD�BOUNDARY.8*ˆUPDATE�FAB�ENTRY:�#�OF�SECTORS�IN�USE�AND�#�OF�RECORDS<*ˆAND�ANY�LAST�KEY�IN�DATA�BLOCK�ARE�DERIVED�FROM�DATA�BLOCK9*ˆCONTENTS�AND�FAT/FCB�INFORMATION.‚THE�LAST�KEY�MUST�NOT**ˆCONFLICT�WITH�ADJACENT�FAB�ENTRIES'�KEYS=*ˆCKECK�FAB�ENTRY:�CURRENT�DATA�BLOCK'S�CONTENT�MUST�COINCIDE7*ˆWITH�INFORMATION�IN�CURRENT�FAB�ENTRY�AND�IN�FAT/FCB.* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS5*ˆD0.B�=�0�IF�REQUEST�UPDATE�LAST�KEY�WHEN�FAFLUB�SET*�NONZERO�IF�TO�LEAVE�KEY�ALONE4*�UNLESS�DUPLICATE�KEY�FILE�AND�KEY�IN�FAB�LESS�THAN*�DATA�BLOCK'S�LAST�KEY* *‚ON�RETURN:%*ˆALL�REGISTERS�ARE�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR0*ˆD0.B�=�ISTAFD�IF�FAB�ENTRY/DATA�BLOCK�CONFLICT'*�ISTARO�IF�RECORD�OVERFLOWS�DATA�BLOCK*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR**INDENTED LISTA* UPCFAB UPDATES FAB FROM DATA BLOCK OR CHECKS FOR DATA INTEGRITY*UPCFAB PASS-FAB AND-DATA BLOCK* CHECK DATA-BLOCK SIZE*‚CALL�$CALSEC"* CHECK FATSBL AT-END-OF LAST-REC.* UPDATE FAB-ENTRY KEY?*‚YES,�CALL�$PUTKEY* UPDATE REST-OF FAB-ENTRY?*‚YES,�CALL�$UPDEOF#*ƒSET-NUMBER�OF-SECTORS�AND�RECORDS*„RETURN%*‚NO,CHECK�FAB-ENTRY�&-DATA-BLK�MATCH*ƒCALL�$CHKKEY,�$DPLKEY*„RETURN*INDENTED LIST END* UPCFAB„EQU„**@*ˆCHECK�LOGICAL�BUFFER�END�->�TO�LAST�RECORD,�RECORDS�ALIGNED�AN*ˆFIT�INTO�THE�BUFFER�EXACTLY*/ŠMOVEM.L�A0-A1/A3/A5/D1-D7,-(A7)�SAVE�REGISTERS"ŠMOVE.B�D0,D2ŽSAVE�KEY�UPDATE�FLAG7ŠGET2ƒFATSBS(A4),A0,A1ƒGET�BUFFER�START�AND�LOGICAL�END"ŠADD.L‚#1,A1Ž1ST�BYTE�AFTER�BUFFER2ŠMOVE.L�FATCFP(A4),A3†A3�->�DATA�BLOCK'S�FAB�ENTRY#ŠMOVE.L�A3,D0ŽNO�CURRENT�FAB�ENTRY?ŠBNE.S‚UPCFIE.1‹BRANCH�IF�OKŠBSR„ISTAIERR‹YES,�ERRORŠBRA.S‚UPCFER.12UPCFIE.1‚MOVE.B�FCBDIR+DIRATT(A2),D7�GET�FILE�TYPEŠAND.B‚#DFTBIT,D7‰. ŠCLR.L‚D6 ŠCLR.L‚D5 ŠCLR.L‚D4ŠCLR.L‚D3‘FLAG�BUFFER�END)ŠMOVE.B�FCBDIR+DIRKEY(A2),D6�GET�KEY�SIZE.ŠMOVE.W�FCBDIR+DIRLRL(A2),D5�GET�RECORD�LENGTHŠBNE.S‚UPCF15�FRL�FILE?�NEXT�RECORD#ŠADD.L‚#1,D4ŽINCREMENT�RECORD�COUNT(ŠCMP.L‚A1,A0ŽPAST�LOGICAL�END�OF�BUFFER?ŠBHI.S‚UPCF25�YES,�ERROR�RETURN;ŠBNE.S‚UPCF00ŠNO,�GO�SKIP�RECORDS�TILL�GET�TO�END�OF�BUFFER1ŠBRA.S‚UPCF20�DONE,�D4.W�=�#�OF�RECORDS�IN�BUFFER$UPCF10„CMP.L‚A1,A0ŽAT�END�OF�BUFFER?ŠBEQ.S‚UPCF20�YES ŠTST.W‚(A0)+ŽREST�OF�BUFFER�=�0?ŠBNE.S‚UPCF25�NO,�ERROR-ŠBRA.S‚UPCF10�TEST�TILL�END�OF�BUFFER�REACHED*.*ˆGET�RECORD�COUNT�FOR�DATA�BLOCK�FOR�FRL�FILE*4UPCF15„MOVE.L�A1,D4ŽGET�RECORD�COUNT�FROM�BUFFER�BCTŠSUB.L‚A0,D4Ž. ŠDIVUƒD5,D4Ž.!ŠMOVE.L�#1,D3ŽSET�BUFFER�END�FLAG-ŠMOVE.L�A1,A5ŽGET�LAST�RECORD�POINTER�INTO�A5ŠSUB.L‚D5,A5Ž.5UPCF20„SWAPƒD4‘RECORDS�DON'T�FIT�OR�TOO�MANY�RECORDS? ŠTST.W‚D4‘.UPCF25„BNE„UPCFRO�YES,�ERROR ŠSWAPƒD4‘NO5ŠBSR„CALSEC�GET�#�OF�SECTORS�NEEDED�FOR�BLOCK�INTO�D13ŠCLR.W‚D0‘SECTOR�COUNT�MUST�BE�LESS�THAN�BLOCK�SIZEŠMOVE.B�FCBDIR+DIRDAT(A2),D0�.ŠCMP.W‚D0,D1Ž.ŠBLS.S‚UPCFIE.2‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERRORUPCFER.1‚BRA.S‚UPCFER3UPCFIE.2‚BTSTW‚#FAFLUB,FATFLG(A4)�UPDATE�FAB�ENTRY?ŠBEQ.S‚UPCF45�NO*,*ˆUPDATE�FAB�ENTRY�AND�FAT�&�FCB�INFORMATION*ŠIFEQƒFMSLEVEL-3ŠTST.B‚D6‘NULL�KEYS?"ŠBEQ.S‚UPCF35�YES,�SKIP�KEY�UPDATE)ŠCMP.B‚#DATISD,D7‰NO,�DUPLICATE�KEY�FILE?ŠBNE.S‚UPCF31�NOFŠMOVEM.L�D3-D4/A0/A5,-(A7)�YES,�CKECK�THAT�FAB�KEY�.GE.�LAST�KEY�IN�DB%ŠMOVE.L�A5,A0Ž.�SETUP�FOR�CHKKEY�CALL>ŠLEA„FABKEY(A3),A5….�A0->LAST�KEY�IN�DATA�BLOCK,�D3�->�FAB�KEY ŠCLR.L‚D4‘.#ŠMOVE.B�(A5)+,D4‹.�D4� =�FAB�KEY�BCTŠMOVE.L�A5,D3Ž. ŠMOVE.L�D6,D0ŠBSR„CHKKEY1Œ.�COMPARE.ŠMOVEM.L�(A7)+,D3-D4/A0/A5�.�RESTORE�REGISTERS5ŠBCS.S‚UPCF32�.�FABKEY�.LT.�LAST�DB�KEY�=>�UPDATE�KEY)ŠBEQ.S‚UPCF35�.�.EQ.�=>�NO�NEED�TO�UPDATE0UPCF31„TST.B‚D2‘KEY�UPDATE�TO�BE�SKIPPED�ANYWAY?"ŠBNE.S‚UPCF35�YES,�LEAVE�KEY�ALONECUPCF32„BSR„PUTKEY†NO,�PUT�KEY�INTO�FAB�ENTRY�(A5�->�LAST�KEY�IN�DB)ŠBNE.S‚UPCFER�ERRORŠENDC+UPCF35„CLR.L‚D0‘RESET�FAB/FILE�LAST�LSN/LRNŠMOVE.W�FABREC(A3),D0†LRNŠSUB.L‚D0,FATLLR(A4)†.ŠSUB.L‚D0,FCBDIR+DIREOR(A2)�.0ŠMOVE.W�D4,FABREC(A3)†SET�#�OF�RECORDS�IN�BUFFERCŠADD.L‚D4,FATLLR(A4)‚LAST�LRN�AND�LSN�OF�FAB�AND�FILE�TO�BE�UPDATEDŠADD.L‚D4,FCBDIR+DIREOR(A2)�.8ŠBSR„UPDEOF‹GET�SECTOR�COUNT,�UPDATE�EOF�LSN�INFO�IN�FAT0ŠBEQ.S‚UPCF40�BUFFER�END�WAS�AT�SECTOR�BOUNDARY?ŠTST.W‚D3‘NO,�SHOULD�HAVE�BEEN?ŠBEQ.S‚UPCFRO�YES,�ERROR4UPCF40„BSETW‚#FCFLDB,FCBFLG(A2)�SET�FCB�GHANGED�FLAG ŠBSR„FABCHG�SET�FAB�CHANGED�FLAGGUPCFRT„AND.W‚#$FFFF-(FAFLUBV+FAFLCBV),FATFLG(A4)�CLEAR�FLAG�BITS�FOR�FAŠCLR.L‚D0‘SET�GOOD�RETURN�FLAGS8UPCFER„MOVEM.L�(A7)+,A0-A1/A3/A5/D1-D7�RESTORE�REGISTERSŠRTSGUPCFRO„MOVE.L�#NL+ISTARO,D0…RECORDS�DON'T�FIT�INTO�BUFFER�AS�THEY�SHOUL ŠBRA.S‚UPCFER*;*ˆCHECK�THAT�FAB�ENTRY�REFLECTS�CURRENT�DATA�BLOCK�CONTENTS*2UPCF45„BTSTW‚#FAFLCB,FATFLG(A4)�BIT�SET�FOR�CHECK?ŠBEQ.S‚UPCFRT�NO,�RETURN1ŠCMP.B‚FABSGS(A3),D1†YES,�CHECK�#�OF�SECTORS�SAMEŠBNE.S‚UPCFFD�ERROR,ŠCMP.W‚FABREC(A3),D4†CHECK�#�OF�RECORDS�SAMEŠIFEQƒFMSLEVEL-3ŠBNE.S‚UPCFFD�ERRORŠMOVE.L�A5,D3ŽKEYS�MATCH?ŠMOVE.W�D6,D4Ž.'ŠBEQ.S‚UPCFRT�.�SKIP�CHECK�IF�NULL�KEYSŠLEA„FABKEY(A3),A0†. ŠBSR„CHKKEY�.%ŠBEQ.S‚UPCFRT�YES�DATA�BLOCK�LOOKS�OKBŠBCC.S‚UPCFFDƒLAST�KEY�LESS�THAN�KEY�IN�FAB�ENTRY:�CHECK�PRIOR�KEY*>*ˆFIND�PRIOR�FAB�ENTRY'S�KEY�TO�CHECK�THAT�KEY�GREATER�THAN�IT*+ŠMOVE.L�FATFAA(A4),A1†A1->�FAB�BUFFER�START$ŠCLR.L‚D0‘FIND�1ST�FAB�ENTRY�POINTERŠLEA„FABPKY(A1),A0†.ŠMOVE.B�(A0),D0=ŠLEA„FABSEG(A1,D0),A1ƒA0�->�FABPKY�FIELD,�A1�->�1ST�FAB�ENTRY2UPCF55„CMP.L‚A1,A3ŽA1�=�CURRENT�FAB�SEGMENT�ENTRY?.ŠBEQ.S‚UPCF60�YES,�A0�->�PRIOR�FAB�ENTRY'S�KEY.ŠMOVE.B�FABKEY(A1),D0†NO,�CHECK�NEXT�FAB�ENTRY*ŠMOVE.L�A1,A0ŽSAVE�FOR�PRIOR�ENTRY�POINTER*ŠLEA„FABSSL(A1,D0),A1ƒA1�->�NEXT�FAB�ENTRY'ŠCMP.L‚FATFAE(A4),A1†BEYOND�END�OF�FAB?ŠBLO.S‚UPCF55�BRANCH�IF�NO,ŠBSR„ISTAUFRR‹YES�-�UNRECOVERABLE�FILE�ERROR ŠBRA.S‚UPCFER>UPCF60„BSR.S‚CHKKEY�KEY�MUST�BE�GREATER�THAN�PRIOR�ENTRY'S�KEYŠBHI.S‚UPCFRT�OK+ŠBSR„DPLKEY�ERROR�UNLESS�DUPLICATE�KEY�FILEŠBEQ.S‚UPCFRT�OKŠBRA.S‚UPCFFD�ERRORŠNOPŠENDCŠIFEQƒFMSLEVEL-2 ŠBRA„UPCFRTŠENDCFUPCFFD„MOVE.L�#NL+ISTAFD,D0†ERROR,�CONFLICT�BETWEEN�DATA�BLOCK�AND�FAB ŠBRA.S‚UPCFERŠENDCƒFMSLEVEL-1*"*PUTALL�1.00�10/22/79ƒL.�STEINHOFF***PUTALL UPDATES ALL CHANGED TABLES ON DISK&*‡(INCLUDING�ANY�INFO.�CHANGED�IN�FCB)*<*PUTALL2 DOES SAME AS PUTALL BUT NO FAB OR DATA BLOCK UPDATE*+*ALL TABLES UPDATED, EVEN IF ERROR DETECTED* *ON CALL:*…A2=FCB�ADDRESS*…A4=FAT�ADDR.�(PUTALL�ONLY)*…A6=VDT�ADDRESS *…BSR�PUTALL* *ON RETURN:*…Z=1�IF�NO�ERROR *†=0�IF�ERROR*…D0.L=0�IF�NO�ERROR*ˆD0.B=80+�IF�IO�ERROR*Š(LAST�ERROR�ENCOUNTERED)* PUTALL„EQU„*ŠMOVE.L�D1,-(A7) ŠCLR.L‚D1/*MOVE FCB DIR. INFO. TO DIR. BLOCK IF NECESSARYŠBTSTW‚#FCFLDB,FCBFLG(A2)ŠBEQ.S‚PUTA10�NOT�CHANGED$ŠBSR„UPTDIR�MOVE�INFO.�TO�DIR.�BLOCKŠMOVE.L�D0,D1ŽSAVE�ERROR�STATUS PUTA10„EQU„*ŠIFGTƒFMSLEVEL-1ŠCLR.L‚D0‘NO�KEY�UPDATEŠBSR„PUTDAT�UPDATE�DATA�BLOCK ŠBEQ.S‚PUTA12 ŠMOVE.L�D0,D1 PUTA12„EQU„*ŠBSR„PUTFAB�UPDATE�FAB ŠBEQ.S‚PUTA15 ŠMOVE.L�D0,D1ŠENDC PUTA15„EQU„*'ŠBSR„PUTSDB�UPDATE�SECONDARY�DIR.�BLOCK ŠBEQ.S‚PUTA20 ŠMOVE.L�D0,D1 PUTA20„EQU„*$ŠBSR„PUTDBŽUPDATE�PRIMARY�DIR.�BLOCK ŠBEQ.S‚PUTA25 ŠMOVE.L�D0,D1 PUTA25„EQU„*ŠBSR„PUTSAT�UPDATE�SAT ŠBNE.S‚PUTART ŠMOVE.L�D1,D0'PUTART„MOVEM.L�(A7)+,D1ŠDON'T�CHANGE�CCŠRTS* PUTALL2ƒEQU„*ŠMOVE.L�D1,-(A7) ŠCLR.L‚D1 ŠBRA.S‚PUTA15ŠPAGEŠIFEQƒFMSLEVEL-3*#*ˆ***********************************ŒCHKKEY �1.00�10/25/79�HBN6*#*ˆ**********************************'*‚CHKKEY�COMPARES�TWO�KEYS�BYTE�BY�BYTE* *‚ON�CALL:@*ˆA0�->�1ST�KEY�BCT,�KEY�FOLLOWS(->KEY�IF�CHKKEY1�&�D0.W=KEY�BCT*ˆD3�->�2ND�KEY*ˆD4.B�=�2ND�KEY'S�LENGTH *‚ON�RETURN: *ˆALL�REGISTERS�UNCHANGED�EXCEPT4*ˆCONDITION�CODES�SET�ACCORDING�TO�LAST�BYTE�COMPARE*ˆA0,�D0�-�UNKNOWN* CHKKEY„EQU„**ŠCLR.W‚D0‘GET�1ST�KEY'S�LENGTHŠMOVE.B�(A0)+,D0‹.&CHKKEY1ƒMOVE.L�A5,-(A7)‹SAVE�REGISTERSŠMOVE.L�D3,A5ŽA5->2ND�KEYŠTST.B‚D0‘ZERO�LENGTH�KEY?ŠBEQ.S‚CHKK15�YES2ŠCMP.B‚D4,D0ŽGET�MINIMUM�KEY�LENGTH�FOR�COMPARISONŠBCS.S‚CHKK00�.ŠMOVE.B�D4,D0Ž.&ŠBEQ.S‚CHKK10�.�IGNORE�CALL�IF�BCT�=�0�KEY�TO�BE�INSERTED�(FULL�KEY)* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR*ˆD0.B�=�ISTAKY�IF�KEY�ERROR*�ISTAIE�IF�INTERNAL�ERROR*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR**INDENTED LIST$* PUTKEY UPDATES FAB ENTRY KEY FIELD$*PUTKEY PASS-KEY &-CURRENT FAB-ENTRY!* CHECK PREVIOUS FAB-ENTRY KEY-OK*‚CALL�$CHKKEY,�$DPLKEY)*ƒKEY-.LT.�(.LE.-IF�DUPL.KEYS)�PRIOR-KEY?*„NO,�RETURN�KEY�ERROR* CHECK NEXT FAB-ENTRY KEY-OK *‚CALL�$CHKKEY,�$DPLKEY,�$GPTSEC(*ƒKEY-.GT.�(.GE.-IF�DUPL.KEYS)�NEXT-KEY?*„NO,�RETURN�KEY�ERROR* KEY-IS OK,-SET-IN FAB-ENTRY*‚SAME�KEY�AS�BEFORE?*ƒYES,LEAVE�AS-IS�RETURN* UPDATED LAST KEY OF-FAB?'*‚YES,FLAG�TO-UPDATE�IN-NEXT�FAB-HEADER* RETURN AND-FLAG FAB CHANGED*INDENTED LIST END* PUTKEY„EQU„**7*ˆTEST�PRIOR�FAB�ENTRY'S�KEY�DOES�NOT�CONFLICT�WITH�KEY*/ŠMOVEM.L�D1-D5/A0-A1/A3/A5,-(A7)�SAVE�REGISTERS/ŠMOVE.L�FATCFP(A4),A1†CURRENT�FAB�ENTRY�POINTERŠMOVE.L�A1,D0Ž.�ERROR�IF�NONEŠBNE.S‚PUTK.1�BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR�IF�NONEŠBRA.S‚PUTKRT.1PUTK.1„CLR.L‚D5‘GET�KEY�SIZEŠMOVE.B�FCBDIR+DIRKEY(A2),D5$ŠBEQ„PUTKGR�IGNORE�CALL�IF�NULL�KEYS;ŠLEA„FABKEY(A1),A3†A3�->�KEY�FIELD�BCT�IN�CURRENT�FAB�ENTRYŠCLR.L‚D0‘GET�FIELD�BCT(ŠMOVE.B�(A3)+,D0‹.�(A3�->�FIELD�FOR�KEY)"ŠBNE.S‚PUTK.2�OK�IF�NOT�NULL�FIELD!ŠBSR„ISTAIERR‹ERROR�IF�NULL�FIELDPUTKRT.1‚BRA.S‚PUTKRT.2)PUTK.2„CMP.B‚D0,D5ŽFULL�KEY�FIELD�IN�FAB?ŠBEQ.S‚PUTK.3�BRANCH�IF�OKBŠBSR„ISTAUFRR‚ERROR�FOR�NOW,�LATER�ALLOW�PARTIAL�KEYS*************PUTKRT.2‚BRA.S‚PUTKRT.3/*ˆD5�TO�CONTAIN�CURRENT�FAB�ENTRY'S�KEY�FLD�BCT.PUTK.3„MOVE.L�FATFAA(A4),A0†FAB�MEMORY�ADDRESS%ŠCLR.L‚D2‘GET�PRIOR�FAB�ENTRY�POINTER1ŠMOVE.L�#FABPKY,D3‰LAST�KEY�OF�PREVIOUS�FAB�FIELD4ŠADD.L‚A0,D3ŽD3�POINTS�TO�LGH�OF�PREV�FAB'S�LAST�KEYŠMOVE.B�FABPKY(A0),D2†.+ŠLEA„FABSEG(A0,D2),A0ƒ.�A0�->�1ST�FAB�ENTRY-PUTK00„CMP.L‚FATFAE(A4),A0†BEYOND�END�OF�FAB?ŠBLO.S‚PUTK00.1‹NO�-�OK+ŠBSR„ISTAUFRR‹YES!�UNRECOVERABLE�FILE�ERRORŠBRA.S‚PUTKRT.32PUTK00.1‚CMP.L‚A0,A1Ž.�FIND�PREVIOUS�ENTRY�POINTERŠBEQ.S‚PUTK10�.�FOUND�ITDŠMOVE.L�A0,D3‚.�SAVE�THIS�IN�CASE�IT�IS�THE�ENTRY�BEFORE�CURRENT�ONEŠADD.L‚#FABKEY,D3‰..ŠMOVE.B�FABKEY(A0),D2†.�GET�NEXT�ENTRY�POINTERŠLEA„FABSSL(A0,D2),A0ƒ.ŠBNE.S‚PUTK00�.2ŠBSR„ISTAUFRR‹INTERNAL�ERROR�IF�FAB�KEY�FIELD�ZEROPUTKRT.3‚BRA.S‚PUTKRT/PUTK10„MOVE.L�D3,A0ŽA0�=>�PRIOR�FAB�ENTRY'S�KEY,ŠMOVE.L�A5,D3ŽSETUP�REGISTERS�TO�CALL�CHKKEY8ŠMOVE.L�D5,D4Ž.�D5�=�PROPOSED�LENGTH�OF�KEY�IN�FAB�ENTRY;ŠBSR„CHKKEYˆCOMPARE�PREVIOUS�FAB�ENTRY'S�KEY�TO�CURRENT�ONEŠBHI.S‚PUTK20�OK$ŠBCS.S‚PUTK45�CONFLICT�WITH�FAB�KEYS@ŠBSR„DPLKEYƒEQUAL�KEYS,�(F ULL�KEYS),�ERROR�UNLESS�DUPLICATE�KEYSŠBEQ.S‚PUTK20�OK#ŠTST.L‚FATSLS(A4)‰OK�IF�1ST�SEGMENTŠBNE.S‚PUTK45�ERROR*5*ˆCKECK�NEXT�FAB�ENTRY'S�KEY�GREATER�THAN�CURRENT�ONE*'PUTK20„EQU„*’GET�NEXT�FAB�ENTRY�POINTER<ŠLEA„0(A3,D5),A0‡.�D5�=�BCT�OF�CURRENT�FAB�ENTRY'S�KEY�FIELD5ŠMOVE.L�FATFAE(A4),D2†END�OF�FAB�ENTRIES�IN�THIS�FAB?ŠSUB.L‚#3,D2Ž.ŠCMP.L‚D2,A0Ž. ŠBCC.S‚PUTK55�.�PAST�END�OF�FAB?#ŠTST.L‚(A0)�.�NO,�MORE�FAB�ENTRIES?!ŠBEQ.S‚PUTK55�.�NO,�NEED�NEXT�FAB2ŠADD.L‚#FABKEY,A0‰A0�->�NEXT�FAB�ENTRY'S�KEY�FIELD*ŠCLR.L‚D2‘FLAG�FOR�NOT�LAST�FAB�KEY�CHANGEPUTK25„BSR„CHKKEY�COMPARE�KEYSŠBCS.S‚PUTK30�.LT.�IS�OK!ŠBHI.S‚PUTK45�ERROR,�KEY�CONFLICT#ŠBSR.S‚DPLKEY�UNLESS�DUPLICATE�KEYS-ŠBEQ.S‚PUTK30�OR�CHECKING�1ST�KEY�OF�NEXT�FAB ŠTST.B‚D2‘PUT�LAST�KEY�INTO�FAB?ŠBEQ.S‚PUTK45�NO,�ERROR6ŠCLR.B‚D2�RESET�FLAG�SO�DON'T�SET�FAFLKB�UNNECESSARILY*;*ˆLEAVE�KEY�ALONE�IF�NEW�KEY�=�OLD�ONE�(DUPLICATE�KEY�FILE)*'PUTK30„BSR.S‚DPLKEY�DUPLICATE�KEY�FILE?ŠBNE.S‚PUTK35�NO&ŠMOVEM.L�D5/A3/A5,-(A7)„SAVE�REGISTERS*PUTK31„MOVE.B�(A5)+,D0‹SAME�KEY�AS�BEFORE?ŠCMP.B‚(A3)+,D0‹.ŠBNE.S‚PUTK32�NOŠDCNTƒD5,PUTK31/PUTK32„MOVEM.L�(A7)+,D5/A3/A5„RESTORE�REGISTERS/ŠBEQ.S‚PUTKGR�YES,�SAME�KEYS,�LEAVE�FIELD�ALONE*!*ˆKEY�IS�OK,�MOVE�IT�TO�FAB�ENTRY*PUTK35„MOVE.B�(A5)+,(A3)+-ŠDCNTƒD5,PUTK35ŠD5�=�ENTRY'S�KEY�FIELD�LENGTH ŠBSR„FABCHG�SET�FAB�CHAGNED�FLAG"ŠTST.L‚D2‘LAST�KEY�IN�FAB�CHANGED?ŠBEQ.S‚PUTKGR�NOFŠBSETW�#FAFLKB,FATFLG(A4)�YES,�SET�FLAG�TO�UPDATE�IT�IN�NEXT�FAB�HEADEPUTKGR„CLR.L‚D0‘GOOD�RETURN8PUTKRT„MOVEM.L�(A7)+,A0-A1/A3/A5/D1-D5�RESTORE�REGISTERSŠRTS*%PUTK45„MOVE.L�#NL+ISTAKY,D0†KEY�ERROR ŠBRA.S‚PUTKRT*2*ˆREAD�IN�1ST�SECTOR�OF�NEXT�FAB�TO�CHECK�NEXT�KEY*5PUTK55„MOVE.L�FATFAA(A4),A0†GET�NEXT�FAB�STARTING�PSN4ŠMOVE.L�#1,D2ŽFLAG�FOR�LAST�KEY�FIELD�IN�FAB�CHANGEDŠMOVE.L�(A0),D0Œ.�FABFLKŠBEQ.S‚PUTK30�NO�NEXT�FAB?ŠMOVE.L�#IOREAD,D1‰READ3ŠBSR„GPTSEC�A1�RETURNS�POINTING�TO�SECTOR�JUST�READŠBNE.S‚PUTKRT�ERROR?:ŠLEA„FABPKY(A1),A0†GET�A0->ING�TO�FABPKY�FIELD�OF�NEXT�FABŠBRA.S‚PUTK25�GO�CHECK�KEYŠPAGE*6*‚DPLKEY�CHECKS�IF�FILE�CONTAINS�DUPLICATE�KEYS�OR�NOT *‚ON�RETURN:'*ˆZ�=�1�IF�FILE�MAY�HAVE�DUPLICATE�KEYS*"DPLKEY„MOVE.B�FCBDIR+DIRATT(A2),D0ŠAND.B‚#DFTBIT,D0‰GET�FILE�TYPEŠCMP.B‚#DATISD,D0ŠRTSŠPAGE**#*ˆ***********************************ŒFNDKEY�1.00�11/6/79�HBN6*#*ˆ**********************************<*‚FNDKEY�FINDS�THE�RECORD�WITH�THE�GIVEN�KEY�IF�IT�EXISTS�IN;*ˆTHE�FILE,�OTHERWISE�THE�INSERT�POSITION�FOR�THE�GIVEN�KEY*ˆIS�RETURNED.* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS$*ˆA3�=�KEY�POINTER�(KEY�TO�BE�FOUND)*ˆD2�=�LENGTH�OF�KEY* *‚ON�RETURN:%*ˆALL�REGISTERS�ARE�UNCHANGED�EXCEPT:#*ˆD0.B�=�ISTARN�IF�NO�RECORD�EXISTS*�ISTARE�IF�RECORD�EXISTS*�ISTAIE�IF�INTERNAL�ERROR*�80+�IF�IO�ERROR*ˆZ-FLAG�-�UNKNOWN0*ˆA1�=�POINTER�TO�RECORD�IN�DATA�BLOCK�IF�ISTARE)*�OR�POINTER�TO�INSERT�POSITION�IF�ISTARN<*ˆD1.L�=�LRN�OF�RECORD�FOUND�OR�INSERT�POSITION(NEXT�RECORD)**INDENTED LIST-* FNDKEY FINDS FILE POSITION ACCORDING TO KEY*FNDKEY PASS KEY* GET-DATA BLOCK-FOR KEY*‚CALL�$GETFDB* FIND KEY-OR INSERT POSITION*‚CALL�$CHKKEY* RECORD FOUND?*‚NO,�RETURN�RECORD�NOT-FOUND*‚YES,�RETURN�RECORD�FOUND*INDENTED LIST END* FNDKEY„EQU„**:*ˆGET�DATA�BLOCK�WHERE�KEY�SHOULD�BE�OR�SHOULD�BE�INSERTED*&ŠMOVEM.L�A0/D2-D6,-(A7)„SAVE�REGISTERS;ŠTST.B‚FCBDIR+DIRKEY(A2)‚MAKE�SURE�NOT�CALLED�FOR�NULL�KEYSŠBNE.S‚FNDKIE.1‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR ŠBRA.S‚FNDKRT*FNDKIE.1‚MOVE.L�A3,D0ŽSETUP�TO�CALL�GETFDB=ŠMOVE.L�#KEYFDB+RDBFLG+NL,D1�.�READ�BLOCK�IF�FIND�ONE�FOR�KEYŠBSR„GETFDB�FOUND�DATA�BLOCK?ŠBNE.S‚FNDKRT�NO,�ERROR**ˆSEARCH�FOR�KEY�IN�DATA�BLOCK*<ŠMOVE.L�FATSLR(A4),D6†KEEP�TRACK�OF�CURRENT�LOGICAL�RECORD�#2ŠCLR.L‚D4‘GET�KEY�LENGTH�IN�DATA�BLOCK�(FULL�KEYS)ŠMOVE.B�FCBDIR+DIRKEY(A2),D4�.-ŠMOVE.L�FATSBS(A4),A1†STARTING�SEARCH�ADDRESS"ŠCLR.L‚D5‘COMPARE�RECORD�BY�RECORD,ŠMOVE.W� FCBDIR+DIRLRL(A2),D5�VRL�OR�FRL�FILEŠMOVE.L�D5,D1Ž.ŠTST.L‚D2‘.�CAN'T�HAVE�NULL�KEYŠBNE.S‚FNDK00�BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR ŠBRA.S‚FNDKRT+FNDK00„CMP.L‚FATSBL(A4),A1†EMPTY�DATA�BLOCK"ŠBCC.S‚FNDK25�OR�AT�END�OF�BUFFER?ŠTST.W‚D5‘NO,�VRL�FILE?ŠBNE.S‚FNDK05�NO,�FRL'ŠMOVE.W�(A1)+,D1‹YES,�GET�RECORD�LENGTHŠBNE.S‚FNDKIE.2‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR ŠBRA.S‚FNDKRT$FNDKIE.2‚BTSTW‚#0,D1ŽODD�BYTE�COUNT?ŠBEQ.S‚FNDK05�NO'ŠADD.L‚#1,D1ŽYES,�SKIP�FILLER�BYTE�ALSOFNDK05„MOVE.L�A3,A0ŽKEY�TO�FINDŠMOVE.W�D2,D0ŽAND�ITS�BCT1ŠMOVE.L�A1,D3ŽCURRENT�RECORD'S�KEY�(D4�=�ITS�BCT)ŠBSR„CHKKEY1ŒCOMPARE�OR�MATCHŠBEQ.S‚FNDK20�FOUND�KEY?"ŠBCS.S‚FNDK15�NO,�CONTINUE�SEARCH?FFNDK10„MOVE.L�#NL+ISTARN,D0†NO,�KEY�NOT�FOUND,�BUT�CAN�INSERT�IN�FRONT?FNDKOK„MOVE.L�D6,D1�OF�CURRENT�KEY�-�RETURN�LRN�OF�RECORD�IN�D11ŠTST.W‚D5‘GET�A1�POINTING�TO�CURRENT�RECORD�STARTŠBNE.S‚FNDKRT�.�IT�ALREADY�ISFŠTST.W�-(A1)�.�FOR�VRL�FILES�SKIPPED�RECORD�BYTE�COUNT�FIELD,�RESTORE�/FNDKRT„MOVEM.L�(A7)+,A0/D2-D6„RESTORE�REGISTERSŠRTS*)*ˆCONTINUE�SEARCH�-�CURRENT�KEY�TOO‚SMALL*;FNDK15„ADD.L‚D1,A1ŽNEXT�RECORD�POINTER�(D1�=�RECORD�LENGTH)ŠADD.L‚#1,D6ŽINCREMENT�CLR%ŠBRA.S‚FNDK00�CHECK�NECT�RECORD'S�KEY**ˆFOUND�RECORD�WITH�GIVEN�KEY*-FNDK20„MOVE.L�#NL+ISTARE,D0†FLAG�RECORD�FOUND1ŠBRA.S‚FNDKOK�RETURN�WITH�A1->ING�TO�RECORD�FOUND*4FNDK25„MOVE.L�#1,D5ŽAT�END�OF�BUFFER:�LEAVE�A1�THERE9ŠBRA.S‚FNDK10Œ(WILL�NOT�SUBTRACT�2�FROM�IT�BEFORE�RETURN)ŠPAGE**"*ˆ**********************************ŒEXPNDB�1.00�11/7/79�HBN6*"*ˆ*********************************D*‚EXPNDB�EXPANDS�THE�CURRENT�DATA�BLOCK�BY�GIVEN�NUMBER�OF�BYTES�FOR6*ˆRECORD�INSERTION�OR�UPDATING�(NEW�RECORD�LONGER�THAN9*ˆTHE�EXISTING�ONE).‚IF�THERE�IS�NOT�SUFFICIENT�ROOM�LEFT>*ˆIN�THE�BLOCK�THE�BLOCK�MUST�BE�SPLIT�AS�FOLLOWS:‚THE�SMALLER=*ˆHALF�IS�USED�IF�IT�CAN�ACCOMODATE�THE�EXPANSION.‚THE�LARGER;*ˆHALF�IS�WRITTEN�TO�DISK�AS�THE�CURRENT�SEGMENT.‚A�NEW�FAB>*ˆENTRY�IS�CREATED�FOR�THE�SMALLER�HALF�WHICH�WILL�CONTAIN�THE<*ˆEXPANSION�(AT�THE�BEGINNING�OR�END�DEPENDING�ON�WHICH�PART:*ˆOF�THE�OLD�BLOCK�IT�WAS).‚IF�NEITHER�HALF�HAS�SUFFICIENT?*ˆROOM�BOTH�PARTS�ARE�WRITTEN�TO�DISK�(A�NEW�FAB�ENTRY�AND�DATA?*ˆBLOCK�IS�ALLOCATED�FOR�ONE�HALF)�AND‚A�NEW�FAB�ENTRY�AND�DATA=*ˆBLOCK�IS�CREATED�FOR�THE�EXPANSION�(BETWEEN�THE�BLOCKS�JUST *ˆWRITTEN).=*…EXPNDB�ALLOCATES�MAXIMUM�NO.�OF�DATA�BLOCKS�AND�FABS�BEFORE>*…STARTING�SPLIT.‚THIS�IS�DOWN�TO�INSURE�SUFFICIENT�DISK�SPACE* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS=*ˆA0�=�START�OF�NEXT�RECORD�IF�UPDATE�(1ST�BYTE�TO�MOVE�DOWN)*‹A0=A1�IF�INSERT *ˆA1�=�START�OF�RECORD�IF�UPDATE9*‹INSERT�POSITION�IF�INSERT�(->�NEXT�RECORD�TO�MOVE�DOWN)3*‹IN�EITHER�CASE�A1�->�1ST�BYTE�MOVED�FOR�EXPANSION&*ˆ(NOTE:�A1&A0�MUST�BE�EVEN�ADDRESSES)*ˆD0�=�BYTE�COUNT�TO�EXPAND**‹IF�ODD�BYTE�COUNT�WILL�EXPAND�D0+1�BYTES* *‚ON�RETURN:%*ˆALL�REGISTERS�ARE�UNCHANGED�EXCEPT:*ˆD0.L�=�0�IF�NO�ERROR*�ELSE�ERROR�CODE�IN�D0.B*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR:*ˆA1�=�START�OF�RECORD�OR�1ST�AVAILABLE�BYTE�FOR�INSERTION0*ˆD1�=�0�IF�FAB/FAT/FCB�CORRESPOND�TO�DATA�BLOCK3*�1�IF�LAST�KEY�OF�DATA�BLOCK�CHANGED�(CALL�PUTKEY)7*�2�IF�DATA�BLOCK�CONTENTS�TO�BE�UPDATED�IN�FAB/FAT/FCB#*�BY�CALLING�UPCFAB�WITH�KEY�UPDATE7*�3�IF�DATA�BLOCK�CONTENTS�TO�BE�UPDATED�IN�FAB/FAT/FCB&*�BY�CALLING�UPCFAB�WITH�NO�KEY�UPDATE*ˆA0�-�UNKNOWN**INDENTED LISTG* EXPNDB CREATES SPACE IN FILE FOR INSERTED RECORD OR EXPANSION(UPDATE)$*EXPNDB PASS-BCT &-POSITION IN-BLOCK!* RECORD FITS-INTO CURRENT BLOCK?*‚YES,EXPAND�DATA�BLOCK*ƒCALL�$MOVEBD,�$UPDEOF*„RETURN�NEW�FATSBL* NO, SPLIT DATA-BLOCK!*‚TOP-HALF�OF-DATA�BLOCK�SMALLER?#*ƒNO,�MOVE-LOWER�HALF-DOWN:�$MOVEBD!*„WRITE�TOP-HALF�TO-DISK:�$WRTUHF'*ƒYES,WRITE�LOWER-HALF�TO-DISK:�$WRTLHF+*„MOVE-LOWER�HALF-UP,�LEAVE-ROOM�FOR-RECORD* GET-NEW FAB-ENTRY FOR-NEW-DB*‚CALL�$NEWFBD* RETURN NEW-DATA BLOCK, FATSBL*INDENTED LIST END* EXPNDB „EQU„**:*ˆEXPAND�CURRENT�BUFFER�IF�POSSIBLE(MOVE�LOGICAL�END�DOWN)*)ŠMOVEM.L�A3/A5/D2-D7,-(A7)�SAVE�REGISTERS5*USE STACK FOR SAVING PSN'S OF ALLOCATED DB'S AND FAB*…(A7)=PSN�OF�FAB*…4(A7)=PSN�OF�1ST�DB#*…8(A7)=PSN�OF�2ND�DB�(IF�REQUIRED)= DE:";*D24::B;JAR:Z9bBj6rDzL‚@Š>’JšJ¢2ªN²hºIÂ@ ŠCLR.L‚-(A7)Ž0�PSN�INFO�ON�STACK ŠCLR.L‚-(A7) ŠCLR.L‚-(A7)&ŠMOVE.L�A0,D6ŽSAVE�NEXT�RECORD�POINTER1ŠBTSTW‚#0,D0ŽODD�BCT�=>�ROUND�UP�TO�NEXT�EVEN�BCT ŠBEQ.S‚EXPN00 ŠADD.L‚#1,D0'EXPN00„MOVE.L�D0,D4ŽSAVE�EXPANSION�SIZEŠBNE.S‚EXPNIE.1‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR�IF�ZERO ŠBRA.S‚EXPNRT5EXPNIE.1‚MOVE.L�A1,D1ŽTEST�EVEN�ADR�PARAMETERS�PASSED ŠOR.BƒD6,D1Ž.ŠBTSTW‚#0,D1Ž.ŠBEQ.S‚EXPNIE.2‹BRANCH�IF�OKŠBSR„ISTAIERR‹INTERNAL�ERROR ŠBRA.S‚EXPNRT4EXPNIE.2‚MOVE.L�FATSBL(A4),A3†GET�BUFFER�LOGICAL�END&ŠMOVE.L�FATSBE(A4),D7†AND�PHYSICAL�ENDŠCLR.L‚D1‘INSERT�IN�THE�MIDDLE?ŠCMP.L‚A3,A1Ž./ŠBLS.S‚EXPN05�YES(�OR�AT�TOP�OR�THIS�IS�UPDATE)BŠMOVE.L�#1,D1„NO,�INSERT�AT�END�OF�DATA�BLOCK,�SET�KEY�UPDATE�FLAG2EXPN05„EQU„*’TRY�TO�MOVE�BUFFER�DOWN�FOR�EXPANSION)ŠMOVE.L�D7,D3ŽSAVE�PHYSICAL�END�OF�BUFFERŠBSR.S‚MOVEBD�EXPAND0ŠBNE.S‚EXPN10�NOT�ENOUGH�ROOM�-�MUST�SPLIT�BLOCK*;*ˆSET�NEW�LOGICAL�END�POINTER,�CLEAR�WORD�AFTER�LOGICAL�END *ˆTO�SUPPORT�SHARED�BUFFER�USAGE*7EXPNOK„MOVE.L�A5,FATSBL(A4)†SET�END�OF�BUFFER�INDICATOR?ŠBSR„UPDEOF„UPDATE�LOGICAL�SECTOR�INFO.�IN�FAT,�FCB-DIR�AND�FABŠCMP.L‚FATSBE(A4),A5†AT�END?ŠBEQ.S‚EXPN07�YES3ŠBSR„FTL.HI�.�MUST�NOT�GET�PAST�PHYSICAL�BUFFER�END,ŠCLR.L‚1(A5)ŽNO,�SET�END�OF�BUFFER�INDICATOR,EXPN07„BSR„DBCHGŽSET�DATA�BLOCK�CHANGED�FLAGŠCLR.L‚D0‘EXPANDED�OK EXPNRT„EQU„*"*DEALLOCATE ANY UNUSED FAB OR DB'S4ŠMOVE.L�D0,D2ŽSAVE�REGISTERS�THAT�ARE�TO�BE�RETURNED ŠMOVE.L�D1,D3 ŠMOVE.L�A1,A0 ŠCLR.L‚D4ŠMOVE.L�(A7)+,A1ŠMOVE.L�A1,D5ŽSKIP�IF�PCN=0ŠBEQ.S‚EXPNRTAŠBSR„DEALFB�DEALLOCATE�FABŠMOVE.L�D0,D4ŽSAVE�ERROR�STATUSEXPNRTAƒMOVE.L�(A7)+,A1 ŠMOVE.L�A1,D5ŠBEQ.S‚EXPNRTBŠBSR„DEALDB�DEALLOCATE�DBŠBEQ.S‚EXPNRTB"ŠMOVE.L�D0,D4ŽNO-SAVE�ERROR�STATUSEXPNRTBƒMOVE.L�(A7)+,A1 ŠMOVE.L�A1,D5ŠBEQ.S‚EXPNRTCŠBSR„DEALDB�DEALLOCATE�DBŠBEQ.S‚EXPNRTC ŠMOVE.L�D0,D4"EXPNRTCƒMOVE.L�D3,D1ŽRESTORE�REGS. ŠMOVE.L�A0,A1 ŠMOVE.L�D2,D0(ŠBNE.S‚EXPNRTDŒERROR�BEFORE�DEALLOCATION#ŠMOVE.L�D4,D0ŽSAVE�NEW�ERROR�STATUS EXPNRTDƒEQU„*,ŠMOVEM.L�(A7)+,A3/A5/D2-D7�RESTORE�REGISTERSŠRTS*%*‚MOVEBD�SUBROUTINE�MOVES�BUFFER�DOWN*ˆENT:�D0�=�BCT�TO�MOVE*�A3�=�CURRENT�END�OF�BUFFER*�A1�=�MOVE�FROM�ADR*ˆRET:�A5�=�NEW�END*�D0,A0,A3�CHANGED*�Z�=�1�IF�MOVED�OK4*‘0�IF�NOT�MOVED�BECAUSE‚WOULD�END�PAST�PHYSICAL�END*‘OF�DATA�BUFFER*‘(AND�A3�NOT�CHANGED)* MOVEBD„EQU„**!ŠMOVE.L�D0,A0ŽGET�NEW�END�POINTERŠADD.L‚A3,A0Ž.ŠMOVE.L�A0,A5Ž.�RETURN�IT�IN�A5>ŠCMP.L‚D7,A0‡ERROR�IF�WOULD�END�UP�PAST�PHYSICAL�END�OF�BUFFER"ŠBHI.S‚MOVEB9�ERROR�-�MOVE�NOTHING%ŠADD.L‚#1,A3ŽADJUST�POINTERS�FOR�MOVE ŠADD.L‚#1,A06MOVEB1„CMP.L‚A3,A1ŽNOTHING�TO�MOVE�IF�AT�END�OF�BUFFERŠBEQ.S‚MOVEB8�.ŠMOVE.W�-(A3),-(A0)ˆMOVEŠBRA.S‚MOVEB1�.MOVEB8„CLR.L‚D0‘FLAG�OK�MOVE MOVEB9„RTS*2*ˆENOUGH�ROOM�IN�EITHER�PART�TO�USE�FOR�EXPANSION?8*ˆD6->NEXT�RECORD,�D4�=�BCT�TO�EXPAND,�D1�=�KEY/FAB�FLAG*ˆA3�=�FATSBL,�D7=D3�=�FATSBE*+EXPN10„MOVE.L�FATSBS(A4),A0†TOP�OF�1ST�HALFBŠMOVE.L�D3,D0„CALCULATE�MAX�SIZE�OF�PARTIAL�BUFFER�FOR�FIT(D3=SBE)ŠSUB.L‚A0,D0Ž. ŠADD.L‚#1,D0ŠSUB.L‚D4,D0Ž.FŠMOVE.L�D6,D2�GET�BCT�OF�UPPER�HALF(COUNT�PARTIAL�REC.�AS�PART�OF�BOTHŠSUB.L‚A0,D2Ž.�HALVES)#ŠMOVE.L�A3,D3ŽGET�BCT�OF�LOWER�HALFŠSUB.L‚A1,D3Ž.ŠADD.L‚#1,D3Ž./ŠMOVE.L�FATCFP(A4),D5†GET�CURRENT�FAB�ENTRY�PTRŠBNE.S‚EXPNIE.3‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR�IF�NONEEXPNRT.2‚BRA„EXPNRT7EXPNIE.3‚CMP.L‚D2,D0ŽEXPANSION�COULD�FIT�IN�UPPER�HALF?ŠBCC.S‚EXPN15�YES"ŠCMP.L‚D0,D3ŽNO,�INTO�SECOND�HALF?,ŠBHI„EXPN65�NO,�CAN'T�FIT�IT�INTO�EITHER�ONE*3*ˆYES, �USE�THE�SMALLER�PART�FOR�INSERTION/EXPANSION**ALLOCATE 1 FAB AND 1 DBEXPN15„MOVE.L�A7,D0 ŠBSR„ALDBFŠBNE.S‚EXPNRT.2#ŠCMP.L‚D2,D3ŽWHICH�PART�IS�SMALLER?ŠBCC.S‚EXPN60�UPPER�HALF?*@*ˆLOWER�HALF�IS�SMALLER,�WRITE�OUT�TOP�HALF�AS�CURRENT�DATA�BLOC?*ˆMOVE�LOWER�HALF�DOWN�SO�CAN�CLEAR�TOP�HALF�TO�SECTOR�BOUNDARY*-ŠMOVE.L�A1,D1ŽGET�START�OF�LOWER�HALF�INTO�D1ŠTST.L‚D3‘NO�LOWER�HALF?ŠBEQ.S‚EXPN20�NOAŠMOVE.L�A3,A5…FIND�END�OF�2ND�HALF(=FATSBL�IF�AT�SECTOR�BOUNDARY)6ŠTST.B‚D1�.�IS�SECOND�HALF�ALREADY�AT�SECTOR�BOUNDARY?;ŠBEQ.S‚EXPN20Š.�YES,�SBL�=�END�OF�2ND�HALF�ASLO(SECSZE=100):ŠCLR.L‚D0‹.�NO,�HAVE�TO�MOVE�LOWER�HALF�TO�SECTOR�BOUNDARY&ŠSUB.B‚D1,D0Ž.�GET�BCT�TO�MOVE�DOWN�BY5ŠADD.L‚D0,D1Ž.�NOW�D1�=�TOP�OF�SECOND�HALF�AFTER�MOVEBŠADD.L‚#SECSZE,D7ƒ.�NEW�PHYSICAL�END�OF�BUFFER�USING�OVERFLOW�AREA8ŠBSR.S‚MOVEBD�MOVE�BUFFER�DOWN,�A5�=�NEW�END�OF�2ND�HALFŠBEQ.S‚EXPN20�BRANCH�IF�OK3ŠBSR„ISTAIERR‹THIS�SHOULDN'T�HAPPEN�-�WHAT'S�WRONG?ŠBRA.S‚EXPNRT.20EXPN20„MOVE.L�FATSBS(A4),A0†RESTORE�BUFFER�START2ŠBSR„WRTUHF�WRITE�UPPER�HALF�AS�CURRENT�DATA�BLOCKŠBNE„EXPNRT�ERROR*%*ˆMOVE�LOWER�HALF�TO�END�OF�EXPANSION*:ŠMOVE.L�A0,A1ŒMOVE�LOWER�HALF�UP�TO�END�OF�INSERT�LOCATIONŠADD.L‚D4,A0ŽMOVE�TO�ADR#ŠLEA„-1(A0,D3.L),A5…NEW�LOGICAL�ENDŠMOVE.L�D1,A3ŽMOVE�FROM�ADRŠLSR.W‚#1,D3ŽWORD�COUNT�TO�MOVEŠBEQ.S‚EXPN45�NOTHING�TO�MOVE?ŠCMP.L‚A3,A0Ž.ŠBEQ.S‚EXPN45�.�NOŠBHI.S‚EXPN35�YES,�MOVE�DOWN?GEXPN30„MOVE.W�(A3)+,(A0)+…NO,�MOVE�COMPLETE�LOWER�HALF�UP�TO�END�OF�EXPŠDCNTƒD3,EXPN30Š.ŠBRA.S‚EXPN45�.$EXPN35„MOVE.L�A3,D1ŽMOVE�BUFFER�DOWNŠLSL.W‚#1,D3Ž.ŠADD.L‚D3,A3Ž."ŠADD.L‚D3,A0Ž.�MOVE�FROM�BOTTOM�UPEXPN40„MOVE.W�-(A3),-(A0)ˆ.!ŠCMP.L‚A3,D1Ž.�DONE�IF�AT�THE�TOPŠBNE.S‚EXPN40�.-EXPN45„MOVE.L�D5,A3ŽCURRENT�FAB�ENTRY�POINTER*4*ˆCREATE�NEW�DATA�BLOCK�AND�FAB�ENTRY�FOR�LOWER�HALF*DEXPN46„CLR.W‚D0‡GET�NEW�FAB�ENTRY�FOR�LOWER�HALF�AFTER�CURRENT�ENTRYŠMOVE.B�FABKEY(A3),D0†.3ŠLEA„FABSSL(A3,D0),A3ƒPOINT�TO�GET�NEW�FAB�ENTRY�AT'ŠCMP.L‚FATFAE(A4),A3†BEYOND�END�OF�FAB?ŠBLO.S‚EXPN50.1‹BRANCH�IF�NO#ŠBSR„ISTAIERR‹INTERNAL�ERROR�IF�YES ŠBRA.S‚EXPN55BEXPN50.1‚MOVE.L�#2,D1ŒSET�UPDATE�KEY�FLAG,�NEWFBD�WILL�NOT�SET�KEY ŠMOVE.L�A7,D0=ŠBSR.S‚NEWFBDˆGET�NEW�DATA�BLOCK�AND�FAB�ENTRY�FOR�LOWER�HALFEXPN51„BEQ„EXPNOK�NO�ERRORSEXPN55„BRA„EXPNRT�RETURN**ˆTOP�HALF�IS�SMALLER?*ˆWRITE�OUT�LOWER�HALF�AND�CREATE�NEW�DATA�BLOCK�OUT�OF�THE�TOP*EXPN608ŠBSR.S‚WRTLHF�WRITE�OUT�LOWER�HALF�AS�CURRENT�DATA�BLOCKŠBNE.S‚EXPN55�ERROR?.ŠMOVE.L�D6,A0ŽNO,�A0->1ST�RECORD�OF�LOWER�HALF=ŠLEA„-1(A0,D4.L),A5…EXPAND�UPPER�HALF�AT�THE�END(GET�NEW�SBL)7ŠMOVE.L�D5,A3ŽGET�NEW�FAB�ENTRY�IN�FRONT�OF�CURRENT�ONEDŠMOVE.L�#3,D1‚RETURN�DON'T-UPDATE-FAB-ENTRY'S-KEY-FIELD�SINCE�NEWFBD ŠMOVE.L�A7,D09ŠBSR.S‚NEWFBDŒWILL�SET�KEY�FIELD�TO�PREVENT�FRAGMENTATIONŠBNE„EXPN55�ERROR>ŠBSR„DPLKEY…IF�DUPLICATE�KEY�FILE�CANNOT�LEAVE�SAME�KEY�IN�NEW>ŠBNE.S‚EXPN61‡.�FAB�ENTRY�SINCE�COULD�BE�INSERTING�SMALLER�KEY.ŠMOVE.L�#2,D1ŽDUPL.�KEYS�=>�FLAG�TO�UPDATE�KEYEXPN61„CLR.L‚D0‘SET�GOOD�RETURN ŠBRA„EXPN51*8*ˆNEITHER�PART�IS�EMPTY�ENOUGH;�WRITE�OUT�BOTH�HALFS�AND-*ˆCREATE�NEW�DATA�BLOCK�BETWEEN�THE�TWO�HALFS**ALLOCATE 1 FAB AND 2 DB'SEXPN65„MOVE.L�A7,D0 ŠBSR„AL2DBF ŠBNE.S‚EXPN558ŠBSR.S‚WRTLHF�WRITE�OUT�LOWER�HALF�AS�CURRENT�DATA�BLOCK ŠBNE.S‚EXPN551ŠMOVE.L�A1,FATSBL(A4)†SET�UPPER�HALF'S�BUFFER�END;ŠMOVE.L�D5,A3‹GET�NEW�FAB�ENTRY�&�DATA�BLOCK�FOR�UPPER�HALF$ŠCLR.L‚D1‘SET�FLAG�NOT�TO�UPDATE�KEY ŠMOVE.L�A7,D0ŠBSR.S‚NEWFBD�.ŠBNE.S‚EXPN55�ERRORŠBSR.S‚WRTUHF�WRITE�UPPER�HALFŠBNE.S‚EXPN55�ERROR=ŠSUB.L‚A1,D6ˆIF�UPDATE�ACCOUNT�FOR�INITIAL�RECORD�LENGTH�ALSOFŠADD.L�D6,D4�.�BCT�OF�NEW�DATA�BLOCK�(BCT�OF�EXPANSION+OLD�RECORD�LENG#ŠLEA„-1(A0,D4.L),A5…A5�->�END�OF�DBŠMOVE.L�A0,A1ŽINSERT�LOCATION8ŠBRA.S‚EXPN46�CREATE�NEW�DB�BETWEEN�THE�TWO�JUST�WRITTENŠPAGE**‚EXPNDB�SUBROUTINES*F*‚WRTUHF�AND�WRTLHF�WRITE�PART�OF�THE�DATA�BLOCK�TO�DISK�AS�THE�CURREN.*“DATA�BLOCK,�FAB�ENTRY�IS�UPDATED�ACCORDINGLY**‚ENT:�A1�=�END�OF �1ST�HALF+1'*‡D6�=�START�OF�2ND�HALF�AT�NEXT�RECORD*‡A0�=�DATA�BUFFER�START *‡A3�=�FATSBL*7*‚RET:�ALL�REGISTERS�UNCHANGED�EXCEPT�D0�=�ERROR�STATUS* WRTUHF„EQU„*AŠMOVE.L�A1,FATSBL(A4)…WRITE�UPPER�HALF,�POINT�OF�EXPANSION�IS�ITSŠSUB.L‚#1,FATSBL(A4)†.�LWA+1 ŠMOVE.L�#1,D0ŽFLAG�TO�UPDATE�KEY ŠBRA.S‚WRTHLF WRTLHF„EQU„*6ŠMOVE.L�D6,FATSBS(A4)†LOWER�HALF�STARTS�AT�NEXT�RECORD!ŠCLR.L‚D0‘FLAG�TO�LEAVE�KEY�ALONE,WRTHLF„BSETW‚#FAFLUB,FATFLG(A4)�FORCE�UPDATEŠBSR„DBCHGŽINDICATE�DB�CHANGED ŠBSR„PUTDAT�.9ŠMOVE.L�A0,FATSBS(A4)†RESTORE�NORMAL�BUFFER�START�AND�ENDŠTST.B‚D0‘RETURN�FLAGSŠRTS*ŠPAGE**#*ˆ***********************************ŒNEWFBD�1.00�11/10/79�HBN6*#*ˆ***********************************D*‚NEWFBD�CREATES�A�NEW�FAB�ENTRY�AND�ALLOCATES�A�NEW�DATA�BLOCK.‚FAB=*ˆENTRY�CREATED�BECOMES�NEW�CURRENT�FAB�ENTRY,�IT�IS�SETUP�TO*ˆINDICATE�NULL�DATA�BLOCK.=*ˆIF�A�NEW�FAB�ENTRY�CANNOT�BE�INSERTED�INTO�THE�CURRENT�FAB,3*ˆTHE�TOP�HALF�OF�THE�FAB�IS�WRITTEN�OUT�AS�CURRENT=*ˆFAB,�&�A�NEW�FAB�IS�LINKED�INTO�THE�FAB�CHAIN�FOR�THE�LOWER7*ˆHALF.‚THIS�NEW�FAB�WILL�CONTAIN�NEW�FAB‚ENTRY�(AT�THE4*ˆSTART�OR�END�OF�THE�FAB)�TOGETHER�WITH�THE�ENTRIES,*ˆFROM�THE�SMALLER�HALF�OF�THE�ORIGINAL�FAB.* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS;*ˆA3�=�LOCATION�TO�INSERT�NEW�FAB�ENTRY�INTO�IN�CURRENT�FAB0*…D0=POINTER�TO�ALLOCATED�SECTORS�TABLE�ON�STACK0*ˆD1.L�=�3�IF�TO�SET�NEW�ENTRY'S�KEY�FIELD�USING5*‘KEY�POINTED�TO�BY�D6,�(USE�KEY-1�ACTUALLY),�DO�THIS"*‘TO�HELP�AVOID�FILE�FRAGMENTATION+*�ANYTHING�ELSE�=>�CLEAR�KEY�FIELD,�IT�WILL*‘BE�SET�LATER�BY�UPCFAB8*ˆD6�->�1ST�RECORD�OF�DISCARDED�LOWER�HALF�OF�DATA�BLOCK2*ŽKEY�IS�USED�WHEN�NEED�TO�CREATE�NEW�FAB�IN�FRONT*ŽOF�CURRENT�FAB* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:**ˆA3�=�NEW�FATCFP,‚FAB�ENTRY�JUST�INSERTED*ˆD0.L�=�0�IF�NO�ERROR*ˆD0.B�=�ERROR�CODE�OTHERWISE*ˆZ�=�1�IF�NO�ERROR *Œ0�IF�ERROR**INDENTED LISTA* NEWFBD ALLOCATES NEW DATA BLOCK AND GETS A NEW FAB ENTRY FOR IT *NEWFBD PASS FAB-ENTRY LOC.&-KEY* ALLOCATE DATA BLOCK*‚CALL�$DSALLC* GET-NEW FAB ENTRY *‚FAB�FULL?*ƒYES,�SPLIT�FAB *„CALL�$DSALLC,�$PRVFHD,�$NXTFHD!*ƒNO,-MOVE�ENTRIES�TO-GET�NEW-ONE* SET-UP FOR-NEW DATA-BLOCK*‚CALL�$GLLSFB,�$SETFSL* RETURN NEW CURRENT FAB-ENTRY*INDENTED LIST END* NEWFBD„EQU„**7*ˆFIND�END�OF�FAB�ENTRIES�AND�PRIOR�ENTRY'S�KEY�POINTER*@ŠMOVEM.L�A0-A1/A5/D0-D7,-(A7)�SAVE�REGS,�POSITION�OF�D6�CRITICAL'*…PSN�TABLE�POINTER�NOW�ON�TOP�OF�STACK/ŠMOVE.L�A3,D7ŽSAVE�PTR�TO�INSERT�ENTRY�LOCATION ŠCLR.L‚D0.ŠCLR.L‚D2‘CLEAR�FOR�LAST�KEY�FIELD�OF�TOP�HALF'ŠMOVE.L�FATCFP(A4),A1†CURRENT�FAB�ENTRYŠCMP.L‚D0,A1Ž.ŠBNE.S‚NEWFIE.1‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR�IF�NONEŠBRA.S‚NEWFRT.1*NEWFIE.1‚TST.L‚(A1)�.�ERROR�IF�EMPTY�ENTRYŠBNE.S‚NEWFIE.2‹BRANCH�IF�OK2ŠBSR„ISTAIERR‹NONZERO�=>�AT�LEAST�ONE�ENTRY�IN�FABNEWFRT.1‚BRA„NEWFRT.NEWFIE.2‚MOVE.L�FATFAA(A4),A1†GET�FORWARD�LINKŠMOVE.L�(A1),D3Œ.�FABFLK'ŠMOVE.L�FABBLK(A1),D4†AND�BACKWARD�LINK+ŠMOVE.B�FABPKY(A1),D0†GET�1ST�ENTRY�POINTERŠLEA„FABSEG(A1,D0),A1ƒ.'ŠMOVE.L�FATFAE(A4),D5†END�OF�FAB�BUFFER;NEWF00„LEA„FABKEY(A1),A5†A5->KEY�FIELD�OF�FAB�ENTRY�AT�HAND,ŠMOVE.B�(A5),D0ŒGET�ENTRY'S�KEY�FIELD�LENGTH*ŠLEA„FABSSL(A1,D0),A1ƒA1�->�NEXT�FAB�ENTRY ŠMOVE.L�D5,D6*ŠSUB.L‚#1,D6ŽD6�->�LAST�WORD�IN�FAB�BUFFER:ŠCMP.L‚A3,A1‹GET�TOP�HALF'S�LAST�KEY�FIELD�POINTER�INTO�D2ŠBHI.S‚NEWF05�IN�SECOND�HALF?5ŠMOVE.L�A5,D2ŽNO,�SAVE�FOR�LAST�KEY�FIELD�OF�TOP�HALF$NEWF05„CMP.L‚D6,A1ŽAT�END�OF�BUFFER?-ŠBCC.S‚NEWF10�PAST�END�OF�FAB�(=�FAB�IS�FULL)ŠTST.L‚(A1)�NO,�END�OF�ENTRIES?ŠBNE.S‚NEWF00�NOCNEWF10„MOVE.B�FCBDIR+DIRKEY(A2),D0�GET�END�OF�FAB�IF�ADDED�AN�ENTRY/ŠLEA„FABSSL(A1,D0),A5ƒ.�A1,A5�->�BYTE�AFTER�END)ŠCMP.L‚D6,A5ŽDOES�ONE�MORE�FAB�ENTRY�FIT?ŠBHI„NEWF55�NO*>*ˆEXPAND�FAB�TO�INSERT�NEW�FAB�ENTRY�SINCE�ROOM�IN�CURRENT�FAB<*ˆD2�=�0�IF�NO�TOP�HALF,�ELSE�=�LAST�KEY�POINTER�IN�TOP�HALF.*ˆA5�=�NEW�END�OF�FAB�IF�ADD�NEW�ENTRY�(LWA+1)7*ˆD5�=�END�O F�FAB�BUFFER,�A1�->�END�OF�LAST�FAB�ENTRY+16*ˆD3�=�NEXT�FAB�PSN,�D4�=�PRIOR�FAB�PSN,�A3�=�INSERT�.*6ŠBEQ.S‚NEWF15�CLEAR�TRAILING�LONG�WORD�IF�FAB�NOT�FULL0ŠCLR.L‚(A5)�.�TO�INDICATE�NEW�END�OF�FAB�ENTRIES1NEWF15„ADD.L‚#FABSSL,D0‰D0�=�BCT�TO�EXPAND�FAB�BY,ŠCLR.L‚D6‘FLAGS�OFF�FOR�EXPAND,�NO�SPLITTING4ŠCMP.L‚A1,A3ŽNOTHING�TO�MOVE�IF�INSERT�AT�END�OF�FABŠBNE.S‚NEWF25�MOVE2NEWF20„LEA„FABKEY(A3),A1†GET�NEW�ENTRY'S�KEY�FIELD.ŠMOVE.L�A1,FATKEY(A4)†IT�IS�THE�FAB'S�LAST�KEY ŠBRA.S‚NEWF30*9NEWF25„MOVE.B�-(A1),-(A5)ˆEXPAND�SO�MOVE�BOTTOM�HALF�DOWNŠCMP.L‚A1,A3Ž. ŠBNE.S‚NEWF250ŠADD.L‚D0,FATKEY(A4)†ADJUST�LAST�FAB�KEY�POINTER�MOVE�TO�ADDRESS.*ˆA5�->�RECORD�WITH�NEW�KEY�TO�SUBTRACT�1�FROM*ˆD4�=�BCT�TO�MOVE'*ˆD6�=�-2�IF�NOT�TO�SUBTRACT�1,�ELSE�DO"ŠTST.W‚FCBDIR+DIRLRL(A2)‚VRL�FILE?ŠBNE.S‚GKMN00�NO,�FRL+ŠADD.L‚#BCTFLD,A5‰YES,�ADD�BCT�FIELD�LENGTHGKMN00„CLR.L‚D0+ŠMOVE.B�FCBDIR+DIRKEY(A2),D0�GET�KEY�LENGTHŠCMP.L‚#-2,D6�SKIP�SUBTRACTION?ŠBEQ.S‚GKMN10�.�YES ŠLEA„0(A5,D0.L),A0†NO,�GET�KEY-1 ŠCLR.W‚D1ŠSUB.W‚#1,-(A0)‹.GKMN05„MOVE.W�-(A0),D0‹.ŠSUBX.W�D1,D0Ž.ŠMOVE.W�D0,(A0)Œ.%ŠCMP.L‚A0,A5Ž.�SUBTRACTION�COMPLETED?2ŠBNE.S‚GKMN05�NO,�CONTINUE�TO�CARRY�BORROW�THROUGH"GKMN10„MOVE.B�(A5)+,(A3)+ˆMOVE�KEYŠDCNTƒD4,GKMN10Š.ŠRTS** *ˆHAVE�TO�SPLIT�FAB:�THREE�CASES)*ˆCASE1:�INSERT�AT�THE�TOP�OF�CURRENT�FAB=*ˆALLOCATE�NEW�FAB�AND�LINK�IT�IN�FRONT�OF�CURRENT�FAB;�WRITE?*ˆCURRENT�FAB�TO�DISK,�NEW�FAB�WILL�CONTAIN�ONLY�NEW�FAB�ENTRY.,*ˆCASE2:�INSERT�IN�THE�MIDDLE�OF�CURRENT�FAB7*ˆALLOCATE�NEW�FAB�AND�LINK�IT�AFTER�CURRENT�FAB;�WRITE>*ˆTOP�HALF�OF�CURRENT�FAB�AS�CURRENT�FAB�TO�DISK,�NEW�FAB�WILL9*ˆCONTAIN�NEW�FAB�ENTRY�FOLLOWED�BY�REST�OF�ORIGINAL�FAB.)*ˆCASE3:�INSERT�AT�THE�END�OF�CURRENT�FAB;*ˆSAME�AS�CASE2�EXCEPT�NEW�FAB�WILL�CONTAIN�ONLY�NEW�ENTRY.<*ˆD2�=�0�OR�LAST�KEY�IN�TOP�HALF,�D3,D4�=�NEXT/PRIOR�FAB�PSN4*ˆA3�=�INSERT�POSITION,�A1�=�E ND�OF�LAST�FAB�ENTRY+1* NEWF55„EQU„*)ŠCLR.L‚D6‘D6�=�0�=>�INSERT�AT�TOP�-�CASE1$ŠMOVE.L�FATFAA(A4),A0†FAB�BUFFER�FWA1ŠMOVE.L�A1,D5ŽSAVE�LAST�FAB�ENTRY�POINTER�(LWA+1)ŠTST.L‚D2‘ANY�TOP�HALF?ŠBEQ.S‚NEWF60�NOŠSUB.L‚#1,D6ŽINSERT�CASE3ŠCMP.L‚A1,A3ŽAT�END�OF�FAB?ŠBEQ.S‚NEWF65�YES>ŠMOVE.L�(A3),D6ˆNO,�SAVE�1ST�LONG�WORD�AFTER�TOP�HALF�-�CASE�2ŠBGT.S‚NEWFIE.3‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR�IF�<=�0 ŠBRA.S‚NEWFRT.NEWFIE.3‚CLR.L‚(A3)�AND�SET�ZERO�AS�END�OF�FAB ŠBRA.S‚NEWF65CNEWF60„MOVE.L�FATKEY(A4),D2†D2�TO�CONTAIN�TOP�PART'S�LAST�KEY�FIELD:ŠBSETW‚#FAFLMB,FATFLG(A4)�FLAG�NEXT�FAB�TOO�FULL�FOR�MERGE**…GET�PSN�FOR�NEW�FAB*,NEWF65„MOVE.L�(A7),A1ŒGET�ADDR.�OF�PSN�TABLEŠMOVE.L�(A1),D1ŒGET�FAB�PSNŠBNE.S‚NEWFIE.4‹BRANCH�IF�OK#ŠBSR„ISTAIERR‹ERROR�IF�ALREADY�USEDNEWFRT.4‚BRA„NEWFRT!NEWFIE.4‚CLR.L‚(A1)�INDICATE�USEDŠMOVE.L�D1,A1ŽA1=FAB�PSNŠTST.L‚D6‘CASE�1?ŠBEQ„NEW120�YES*9*ˆCASE�2�OR�3:�UPDATE�BACKWARD�LINK�OF�NEXT�FAB�AND�WRITE *ˆTOP�HALF�OF�FAB�AS�CURRENT�FAB*=ŠMOVE.L�A1,(A0)‰SET�CURRENT�FAB�FORWARD�LINK�->ING�TO�NEW�FAB#ŠCLR.L‚D0‘UPDATE�BACKWARD�LINK�ONLY>ŠMOVE.L�A1,D4ˆD4�=�NEXT�FAB'S�BACKWARD�LINK�(=�PSN�OF�NEW�FAB)ŠBSR„NXTFHD�UPDATENEWFER„BNE.S‚NEWFRT.4‹ERROR?)ŠMOVE.W�FATFLG(A4),-(A7)ƒSAVE�FLAG�STATUS-ŠBCLRW‚#FAFLKB,FATFLG(A4)�CLEAR�LAST�KEY�FLAGŠBSR„FABCHG�FAB�CHANGED9ŠBSR„PUTFABŠAND�UPDATE�THE�TOP�HALF�OF�FAB�AS�CURRENT�FAB&ŠMOVE.W�(A7)+,FATFLG(A4)ƒRESTORE�FLAGSŠTST.B‚D0‘ERROR?ŠBNE„NEWFER�YES*)*ˆSETUP�FOR�NEW�FAB�TO�FOLLOW�CURRENT�ONE*:ŠMOVE.L�FATFAB(A4),FABBLK(A0)�SET�BACKWARD�LINK�TO�OLD�FAB3ŠMOVE.L�D3,(A0)ŒSAME�FABFLK�AS�IN�OLD�FAB�(RESTORE)-ŠMOVE.L�D4,FATFAB(A4)†THIS�IS�NEW�CURRENT�FAB.ŠMOVE.L�D2,A1ŽOLD�FAB'S�LAST�KEY�FIELD�POINTER*$*ˆADJUST�FAB�INFO�FOR�NEW�FAB�IN�FAT*?ŠCLR.L‚D0†CALCULATE�#�OF�SECTORS�AND�RECORDS�LOST�WITH�TOP�HALF ŠCLR.L‚D1‘.)ŠLEA„FABPKY(A0),A0†FAB�HEADER�KEY�POINTERŠMOVEM.L�D5/A0-A1,-(A7)+ŠCLR.L‚D5‘GET�1ST�FAB�ENTRY�POINTER�INTO�A0ŠMOVE.B�(A0)+,D5 ŠADD.L‚D5,A0!ŠBSR„GLLSFB�.�A0�->�1ST�FAB�ENTRYŠMOVEM.L�(A7)+,D5/A0-A17ŠADD.L‚D0,FATFLS(A4)†SET�NEW�FAB'S�STARTING�LSN�AND�LRNŠADD.L‚D1,FATFLR(A4)†.ŠGET2ƒFATFLS(A4),D2,D3ƒ.*/*ˆMOVE�OLD�FAB'S�LAST�KEY�INTO�NEW�FAB'S�HEADER* ŠCLR.L‚D0(ŠMOVE.B�(A1)+,D0‹LAST�KEY�FIELD'S�LENGTH&ŠMOVE.B�D0,(A0)+‹SAME�KEY�FIELD�LENGTHŠBEQ.S‚NEWF75�SKIP�IF�NULL�KEY0NEWF70„MOVE.B�(A1)+,(A0)+ˆMOVE�THE�KEY�TO�HEADERŠDCNTƒD0,NEWF70Š.*)*ˆMOVE�REST�OF�FAB�UP�TO�END�OF�NEW�ENTRY*ˆA0->1ST�FAB�ENTRY�LOCATION*!NEWF75„CLR.L‚D4‘GET�FULL�KEY�SIZEŠMOVE.B�FCBDIR+DIRKEY(A2),D4�.GNEWF80„LEA„FABSSL(A0,D4),A1‚A1=2ND�ENTRY�POINTER:LEAVE�ROOM�FOR�NEW�ENTŠMOVE.L�A1,A5ŽSAVEŠTST.L‚D6‘CASE�3?"ŠBMI.S‚NEW100�YES,�NOTHING�TO�MOVE7ŠMOVE.L�D6,(A3)ŒNO�-�CASE�2,�RESTORE�START�OF�2ND�ENTRYEŠMOVE.L�A3,D0�GET�BCT�OF�GAP�BETWEEN�NEW�ENTRY'S�END�AND�START�OF�2NDŠSUB.L‚A1,D0Ž.�ENTRY0ŠCMP.L‚A1,A3ŽMOVE�LOWER�HALF�TO�END�OF�NEW�ENTRY0ŠBEQ.S‚NEWF95�.�NOTHING�TO�MOVE�IF�ALREADY�THERE)ŠBHI.S‚NEWF85�.�ENOUGH�ROOM�FOR�FULL�KEY?;ŠADD.L‚D0,D4Š.�NO,�D4�=�NEW�SHORTER�KEY�FIELD�THAT�WILL�FIT:ŠBHI.S‚NEWF80‹.�NOW�NEW�ENTRY�RIGHT�IN�FRONT�OF�LOWER�HALF&ŠBSR„ISTAIERR‹INTERNAL�ERROR�IF�.LE.�0NEWFRT.5‚BRA„NEWFRT2NEWF85„SUB.L‚A3,D5Ž.�MOVE�:�GET�BCT�OF�REST�OF�FABŠLSR.W‚#1,D5Ž.�WORD�COUNTŠBNE.S‚NEWF90�BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR�IF�NULLNEWFRT.6‚BRA.S‚NEWFRT.5CNEWF90„MOVE.W�(A3)+,(A1)+ˆ.�MOVE�REST�OF�FAB�UP�TO�END�OF�NEW�ENTRYŠDCNTƒD5,NEWF90Š.*ŠCLR.L‚(A1)�CLEAR�FOR�END�OF�FAB�INDICATOR**ˆGET�FAB'S�LAST�LSN�AND�LRN*NEWF95„MOVE.L�A0,A3ŽNEW�FATCFPDŠMOVE.L�A5,A0‚CALCULATE�#�OF�RECORDS�AND�SECTORS�IN�REMAINDER�OF�FABŠCLR.L‚D0‘.�IGNORE�NEW�ENTRY ŠCLR.L‚D1‘. ŠCLR.L‚D5‘.<ŠBSR„GLLSFB‡.�CALL�SETS�ALSO�FATKEY�FIELD�FOR�FAB�IN�THE�FAT ŠSUB.L‚#1,D0ŽGET�LAST�LSN�OF�FABŠADD.L‚D0,D2Ž. ŠSUB.L‚#1,D1ŽGET�LAST�LRN�OF�FABŠADD.L‚D1,D3Ž.NEW100„MOVE.L�A3,D0ŽSAVE/ŠMOVE.L�FATFAA(A4),A3†CURRENT�FAB�THE�LAST�ONE?ŠTST.L‚(A3)�.�YES�IF�FABFLK�=�0ŠMOVE.L�D0,A3Ž.�RESTOREŠBNE.S‚NEW105�NO@ŠMOVE.L�FATFAB(A4),FCBDI R+DIRFE(A2)�YES,�NEW�FAB�IS�THE�LAST�NOW.ŠBSETW‚#FCFLDB,FCBFLG(A2)�SET�FCB�CHANGED�FLAG;NEW105„SAVE2‚D2,D3,FATLLS(A4)ƒSAVE�LAST�LSN�AND�LRN�FOR�FAB%ŠBSR„SETFSL�NEW�SEGMENT�AT�TOP�OF�FAB**ˆRETURN�FOR�CASE�2�&�3*ŠTST.L‚D6‘CASE�2?ŠBPL„NEWF40�YES,ŠMOVE.L�A0,A3ŽCASE�3:�FAB�HAS�ONLY�NEW�ENTRY*ŠCLR.L‚(A5)�CLEAR�FOR�END�OF�FAB�INDICATORDŠMOVE.L�A3,FATCFP(A4)‚SET�SO�DON'T�TRY�TO�UPDATE�SLS&SLR�AGAIN�LATER ŠBRA„NEWF20*7*ˆCASE�1:�NEW�FAB�TO�BE�CREATED�IN�FRONT�OF�CURRENT�ONE*NEW120„EQU„*’A1�=�NEW�FAB�PSN*>*ˆSAVE�OLD�FAB'S�HEADER�FOR�NEW�FAB�IN�DB�OVERFLOW�SPACE,�THEN?*ˆSET�OLD�FAB'S�HEADER�KEY�=�1ST�KEY-1�OF�LOWER�HALF,�THAT�WILL!*ˆALSO�BE�THE�NEW�FAB�ENTRY'S�KEY?*ˆIF�DUPLICATE�KEYS�SET�FIELD�TO�'KEY'�SO�WILL�NOT�HAVE�'KEY-1'*ˆAND�USER�INSERTS�'KEY'*#ŠBSR„DPLKEY�DUPLICATE�KEYS�ALLOWED?ŠBNE.S‚NEW121�NO6ŠMOVE.L�#-2,D6�YES,�FLAG�TO�ENTER�'KEY'�INTO�NEW�FIELD5NEW121„CLR.L‚D4‘SAVE�CURRENT�FAB'S�HEADER�FOR�NEW�FAB0ŠMOVE.B�FCBDIR+DIRKEY(A2),D4�.�GET�HEADER�LENGTHŠADD.L‚#FABSEG,D4‰.'ŠMOVE.L�FATSBE(A4),A5†.�MOVE�TO�ADDRESSŠADD.L‚#1,A5Ž.1ŠMOVEM.L�D4/A0/A5/A3,-(A7)�.�SAVE�FOR�MOVING�BACK%NEW125„MOVE.B�(A0)+,(A5)+ˆSAVE�HEADERŠDCNTƒD4,NEW125Š.CŠMOVE.L�10*4(A7),A5ƒGET�NEW�KEY=�1ST�KEY�OF�FAB�-�1(A5=ORIGINAL�D6))ŠMOVE.L�FATFAA(A4),A3†GET�MOVE-TO�ADDRESSŠADD.L‚#FABPKY,A3‰.ŠMOVE.B�(A3)+,D4‹.!ŠBEQ.S‚NEW129�.�SKIP�IF�NULL�KEYS+ŠBSR„GKMNS1�GET�KEY�MINUS�1�INTO�FAB�HEADER*@*ˆSET�BACKWARD�LINK�=�NEW�FAB�PSN�AND�UPDATE�CURRENT�FAB�ON�DISK*NEW129„MOVE.L�FATFAA(A4),A09ŠMOVE.L�A1,FABBLK(A0)†SET�NEW�BACK�WARD�LINK�INTO�OLD�FABŠBSR„FABCHG�UPDATE�CUURENT�FAB ŠBSR„PUTFAB�.,ŠMOVEM.L�(A7)+,D4/A0/A5/A3�RESTORE�REGISTERSNEWFRT1ƒBNE„NEWFRT.6‹IO�ERROR?* *ˆRESTORE�FAB�HEADER�FOR�NEW�FAB*8NEW130„MOVE.B�(A5)+,(A0)+ˆMOVE�HEADER�BACK�TO�FAB�BUFFERŠDCNTƒD4,NEW130Š.&ŠMOVE.L�FATFAA(A4),A0†A0�->�FAB�BUFFER=ŠMOVE.L�FATFAB(A4),(A0)„SET�FORWARD�LINK�FOR�NEW�FAB�(FABFLK),ŠMOVE.L�A1,FATFAB(A4)†NEW�FAB�IS�CURRENT�FAB*6*ˆADJUST�FORWARD�LINK�IN�PRIOR�FAB�TO�POINT�TO�NEW�FAB*)ŠMOVE.L�FABBLK(A0),D4†GET�PRIOR�FAB'S�PSN(ŠMOVE.L�A1,D3ŽFORWARD�LINK�FOR�PRIOR�FAB9ŠBSR„PRVFHDŠUPDATE�LINK�AND�SET�FCBDIR+DIRFS�IF�NECESSARYŠBNE„NEWFRT1ŒERROR**ˆSETUP�FAT�INFO�FOR�NEW�FAB*#ŠCLR.L‚D0‘GET�NEW�FAB�ENTRY�POINTERFŠMOVE.B�FABPKY(A0),D0�.�LEAVE�SAME�HEADER�KEY�LENGTH�AS�IN�ORIGINAL�FAŠLEA„FABSEG(A0,D0),A0ƒ.=ŠGET2ƒFATFLS(A4),D2,D3ƒADJUST�STARTING�LSN�AND�LRN�OF�SEGMENTŠSUB.L‚#1,D2Ž.DŠSUB.L‚#1,D3�.�ADJUST�SINCE�UPCFAB�WILL�ADD�#�OF�RECORDS�AND�SECTORS1ŠMOVE.L�#-2,D6�CONTINUE�AS�IF�ADDED�TO�END�OF�FAB8ŠBRA„NEWF75‹AND�FLAG�NOT�TO�SUBTRACT�1�FROM�KEY�ANY�MOREŠPAGE**#*ˆ***********************************ŒCMPRDB�1.00�11/16/79�HBN6*#*ˆ**********************************C*‚CMPRDB�COMPRESSES�THE�CURRENT�DATA�BLOCK�BY�GIVEN�NUMBER�OF�BYTES>*ˆFOR�RECORD�DELETION�OR�UPDATING�(NEW�RECORD�SHORTER�THAN�THE?*ˆEXISTING�ONE).‚LSN�INFO�IN�FAT�&�FCB�DIR�&�FAB�ARE�UPDATED�TO;*ˆREFLECT�ANY�CHANGE.‚IF�THE�DATA�BLOCK�BECOMES�EMPTY�IT�IS>*ˆDELETED�TOGETHER�WITH�ITS�FAB�ENTRY-�NO�CURRENT�SEGMENT�WILL7*ˆEXIST.‚IF�THE�FAB�BECOMES�EMPTY�IT�IS�DELETED.‚IF�THE?*ˆFAB(OR�DATA�BLOCK)�BECOMES�MARGINALLY�FULL�AN�ATTEMPT�IS�MADE6*ˆTO�COMBINE�IT�WITH�ANY�NEXT�FAB(OR�NEXT�DATA�BLOCK).* *‚ON�CALL:*ˆA6�=�VDT�ADDRESS*ˆA4�=�FAT�ADDRESS*ˆA2�=�FCB�ADDRESS@*ˆA1�=�POINT�OF�DELETION�(1ST�BYTE�TO�BE�DELETED,�MUST�BE�EVEN�A *‹->�BYTE�AFTER�RECORD�IF�UPDATE*‹->�START�OF�RECORD�IF�DELETE*ˆD0�=�BYTE�COUNT�TO�COMPRESS%*ˆIF�ODD�BCT�WILL�COMPRESS�D0+1�BYTES* *‚ON�RETURN:!*ˆALL�REGISTERS�UNCHANGED�EXCEPT:*ˆA1�=�UNKNOWN*ˆD0.L�=�0�IF�NO�ERROR*ˆD0.B�=�ERROR�CODE�OTHERWISE**INDENTED LIST@* CMPRDB DELETES SPACE IN DATA BLOCK FOR RECORD DELETE OR UPDATE$*CMPRDB PASS-BCT &-POINT-OF DELETION%* DELETION RESULTS IN-EMPTY DATA-BLK?!*‚NO,-UPDATE�DB-INFO�CALL�$UPDEOF"*ƒTRY-MERGE�WITH-NEXT�CALL�$CMBNDB*„DELETED�LAST�RECORD?*…YES,�CALL�$DPLKEY,�$PUTKEY*†RETURN�NEW�FATSB L*…NO,�RETURN�NEW�FATSBL"*‚YES,DELETE�DATA-BLOCK�&FAB-ENTRY *ƒCALL�$DSDEAL,�$GLLSFB,�$DELFAB*„EMTPTY�FAB�RESULTS?*…YES,�DEALLOCATE�IT*‡RETURN�NO�DATA-BLK�OR-FAB*…NO,-TRY�MERGE-WITH�NEXT-FAB*†CALL�$CMBNFB,�RETURN*INDENTED LIST END* CMPRDB„EQU„***ˆCHECK�THAT�PARAMETERS�ARE�OK*,ŠMOVEM.L�A0/A3/A5/D1-D5,-(A7)�SAVE�REGISTERS.ŠBTSTW‚#0,D0ŽODD�BCT�=>�D0+1�BYTES�TO�COMPRESSŠBEQ.S‚CMPR05�.ŠADD.L‚#1,D0Ž.%CMPR05„TST.L‚D0‘ERROR�IF�NULL�BCT�NOWŠBNE.S‚CMPRIE.1‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR�IF�NULL ŠBRA.S‚CMPRRTGCMPRIE.1‚GET2ƒFATSBS(A4),A0,A5ƒGET�BUFFER�START�AND�CURRENT�LOGICAL�END4ŠCMP.L‚A1,A5ŽDELETE�POSITION�MUST�BE�IN�FRONT�OF�END5ŠBHI.S‚CMPRIE.2‹...�AND�AFTER�BUFF�START�BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR ŠBRA.S‚CMPRRTCMPRIE.2‚CMP.L‚A1,A0Ž.ŠBLS.S‚CMPRIE.3‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERROR ŠBRA.S‚CMPRRTFCMPRIE.3‚MOVE.L�A5,D1ˆGET�NEW�DATA�BLOCK�LOGICAL�END�AFTER�COMPRESSIONŠSUB.L‚D0,D1Ž.4ŠMOVE.L�D1,FATSBL(A4)†SAVE�SECTOR�BUFFER�LOGICAL�END@ŠADD.L‚#1,D1…WILL�AN�EMPTY�DATA�BLOCK�BE�THE�RESULT�OF�COMPRESS?ŠCMP.L‚D1,A0Ž.ŠBEQ.S‚CMPR20�YES?ŠCLR.W‚(A1)†NO,�CLEAR�FOR�END�OF�BUFFER�IF�DEL�LAST�REC�AND�VRLŠBSR„DBCHGŽDATA�BLOCK�CHANGED0ŠCMP.L‚A1,D1ŽDELETE�RECORD�AT�END�OF�DATA�BLOCK? ŠBEQ„CMPR45�YES,�NOTHING�TO�MOVE*)*ˆCOMPRESS�DATA�BLOCK:�MOVE�LOWER�PART�UP0*ˆD0�=�BCT�TO�COMPRESS,�A0�=�FATSBS,�A5�=�FATSBL:*ˆA1�=�POINT�OF�DELETION,�D1�=�NEW�FATSBL+1�AFTER�DELETION*ŠMOVE.L�A1,A3ŽA1�=�MOVE�TO�ADRŠADD.L‚D0,A3ŽA3�=�MOVE�FROM�ADR0CMPR10„MOVE.W�(A3)+,(A1)+ˆDELETE�REQUESTED�BYTESŠCMP.L‚D1,A1ŽDONE?ŠBNE.S‚CMPR10�. ŠCLR.W‚(A1)�ZERO�NEXT�BYTE�COUNT*@*ˆUPDATE�FAB�ENTRY�AND�DIRECTORY�IN�FCB�TO�REFLECT�NEW�DATA�BLOC*=CMPR15„BSR„UPDEOFŒUPDATE�LSN�INFO�IN�FAT�AND�FCB-DIR,�AND�FAB;ŠBSR„CMBNDBˆTRY�TO�COMBINE�DATA�BLOCK�WITH�NEXT�IF�POSSIBLE5CMPRRT„MOVEM.L�(A7)+,A0/A3/A5/D1-D5�RESTORE�REGISTERSŠRTS*+*ˆDELETE�EMPTY�DATA�BLOCK�AND�ITS�FAB�ENTRY**CMPR20„MOVE.L�FATFAE(A4),A3†FAB�BUFFER�END&ŠMOVE.L�FATFAA(A4),D3†FAB�BUFFER�START/ŠMOVE.L�FATCFP(A4),A1†CURRENT�FAB�ENTRY�POINTER6ŠBCLRW‚#FAFLDB,FATFLG(A4)�NO�DATA�BLOCK�=>�NOT�CHANGED7ŠMOVE.L�(A1),D2ŒSAVE�FABPSN�FOR�DATA�BLOCK�DEALLOCATION!ŠCLR.L‚D1‘AND�GET�DATA�BLOCK�SIZE(ŠMOVE.B�FABSGS(A1),D1†ADJUST�LLS�AND�EOF3ŠSUB.L‚D1,FATLLS(A4)†ADJUST�LAST�LSN�OF�CURRENT�FAB<ŠSUB.L‚D1,FCBDIR+DIREOF(A2)�ADJUST�EOF�LSN�IN�PRIM�DIR�IMAGE=ŠSUB.L‚#3,A3ˆGET�FAB�BUFFER�END�-3�(->�LAST�LONG�WORD�OF�FAB)6ŠCLR.L‚D0�DELETE�FAB�ENTRY:�GET�NEXT�FAB�ENTRY�POINTERŠMOVE.B�FABKEY(A1),D0†.,ŠLEA„FABSSL(A1,D0),A5ƒ.�A5�->�NEXT�FAB�ENTRY#ŠCMP.L‚A3,A5ŽDELETE�LAST�FAB�ENTRY?ŠBCC.S‚CMPR28�YES)ŠTST.L‚(A5)�DELETE�LAST�FAB�ENTRY�IN�FAB?ŠBEQ.S‚CMPR28�YES(ŠADD.L‚#4,A3ŽA3�->�BYTE�AFTER�FAB�BUFFER.CMPR25„MOVE.W�(A5)+,(A1)+ˆNO,�DELETE�FAB�ENTRY-ŠCMP.L‚A3,A5ŽBY�MOVING�REST�OF�FAB�ENTRIES�UP ŠBNE.S‚CMPR25 ŠBRA.S‚CMPR30=CMPR28„BSETW‚#FAFLKB,FATFLG(A4)�SET�LAST�FAB�KEY�CHANGED�FLAG6CMPR30„CLR.L‚(A1)�DELETE�LAST�FAB�ENTRY�IN�CURRENT�FAB$ŠCLR.L‚FATCFP(A4)‰NO�CURRENT�SEGMENT#ŠMOVE.L�D2,A1ŽDEALLOCATE�DATA�BLOCK"ŠBSR„DEALDB�.�D1�=�DATA�BLOCK�SIZE!ŠMOVE.L�D0,-(A7)‹SAVE�RETURN�CODEŠMOVE.L�D3,A0ŽFAB�BUFFER�START%ŠCLR.L‚D0‘FIND�1ST�FAB�ENTRY�POSITIONŠMOVE.B�FABPKY(A0),D0†.ŠLEA„FABSEG(A0,D0),A0ƒ.#ŠBSR„GLLSFB�SET�FATKEY�FIELD�IN�FAT#* RETURNS WITH D0 = LAST LSN OF FAB*ŽD1�=�LAST�LRN�OF�FAB$ŠMOVE.L�(A7)+,D0‹RESTORE�RETURN�CODEŠBNE.S‚CMPRR1�ERROR?ŠPAGE*#*ˆDEALLOCATE�FAB�IF�IT�BECAME�EMPTY*ŠTST.L‚(A0)�EMPTY�FAB?ŠBNE.S‚CMPR40�NO%ŠBSR„DELFAB�YES,�DEALLOCATE�FAB�SPACECMPRRT.1‚EQU„*CMPRR1„BRA.S‚CMPRRT**ˆTRY�TO�COMBINE�WITH�NEXT�FAB* CMPR40„EQU„*(ŠBSR„CMBNFB�TRY�TO�COMBINE�FAB�WITH�NEXTŠBNE„CMPRR1�ERROR ŠBSR„FABCHG�SET�FAB�CHANGED�FLAGŠCLR.L‚D0‘GOOD�RETURN�FLAGS ŠBRA.S‚CMPRR1*'*ˆDELETED�LAST�RECORD�IN�THE�DATA�BLOCK&*ˆNSERT�NEW�LAST�RECORD'S�KEY�INTO�FAB*.CMPR45„TST.B‚FCBDIR+DIRKEY(A2)‚YES,�NULL�KEYS?!ŠBEQ.S‚CMPR70�YES,�SKIP�KEY�STUFF$ŠCLR.L‚D5‘NO,�FIND�LAST�RECORD�IN�DB!ŠMOVE.W�FCBDIR+DIRLRL(A2),D5�FRL?ŠBNE.S‚CMPR60�YESŠCLR.L ‚D0‘NO,�VRL2CMPR50„MOVE.W�(A0)+,D0‹SKIP�RECORDS�TILL�FIND�LASTŠBNE.S‚CMPRIE.4‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERRORŠBRA.S‚CMPRRT.10CMPRIE.4‚MOVE.L�A0,A5Ž.�SAVE�IN�CASE�LAST�RECORDŠBTSTW‚#0,D0Ž.�ODD�BCT?ŠBEQ.S‚CMPR55�NO$ŠADD.L‚#1,D0Ž.�YES,�SKIP�FILLER�BYTE$CMPR55„ADD.L‚D0,A0ŽA0�->�NEXT�RECORDŠCMP.L‚D1,A0ŽLAST�RECORD?ŠBNE.S‚CMPR50�NOŠBRA.S‚CMPR65�YES,�A5�->�IT3CMPR60„MOVE.L�D1,A5ŽGET�LAST�RECORD�POINTER�INTO�A5ŠSUB.L‚D5,A5Ž.+CMPR65„BSR„PUTKEY�SAVE�DB'S�LAST�KEY�IN�FABCMPR70„BEQ„CMPR15�PUT�OKŠBNE„CMPRR1�ERRORŠPAGE*$*ˆ************************************ŒSKPCMB�1.00�2/18/80�HBN6*!*ˆ********************************C*‚SKPCMB�WILL�CKECK�IF�FILE�IS�SEQUENTIAL�OR�ONLY�ASSIGNED�FOR�READ**‚ON�EXIT:�Z�=�1�IF�SKIP*�0�IF�INDEXED�AND�WRITE�ASSIGN*‹D0,�D1,�D2�-�UNKNOWN SKPCMB„EQU„*3ŠMOVE.W�FATASN(A4),D1†GET�CURRENT�ACCESS�PROTECTION%ŠAND.W‚#FAPBIT,D1‰MASK�OFF�OTHER�BITS ŠBSETW‚#6,D1ŠBSR„CHKAPŽGET�READ/WRITE�TYPESŠBSR„FTL.NE�UNEXPECTED�ERROR.ŠTST.W‚D2‘WRITE�ACCESS?(D2.L�=READ/WRITE�TYPE)ŠBEQ.S‚SKPRTN�NO,�SKIP�COMBINE,ŠMOVE.B�FCBDIR+DIRATT(A2),D1�CHECK�FILE�TYPEŠAND.B‚#DFTBIT,D1‰.ŠCMP.B‚#DATSEQ,D1#SKPRTN„RTS„OTHERWISEŠTRY�TO�COMBINEŠPAGE**#*‰***********************************�CMBNDB�1.00�1/17/80�HBN6*#*‰**********************************B*‚CMBNDB�TRIES�TO�COMBINE�CURRENT�DATA�BLOCK�WITH�NEXT�ONE�IF�BOTH*‰ARE�SUFFICIENTLY�EMPTY**‚ON�ENTRY:�A6�=�VDT�ADDRESS*ŒA4�=�FAT�ADDRESS*ŒA2�=�FCB�ADDRESS,*‚ON�RETURN:�ALL�REGISTERS�UNCHANGED�EXCEPT:*ŒD0.L�=�0�IF�NO�ERROR*ŒD0.B�=�80+�IF�IO�ERROR*ŒZ�=�1�IF�NO�ERROR *�0�IF�ERROR**INDENTED LIST4* CMBNDB TRIES TO MERGE CURRENT DATA BLOCK WITH NEXT*CMBNDB PASS CURRENT DATA-BLK* POSSIBLE TO MERGE?*‚CALL�$SKPCMB*ƒNO,�RETURN�UNCHANGED�DATA-BLK * YES,MERGE!*‚CALL�$IOSREAD,�$GLLSFB,�$UPCFAB* DEALLOCATE MERGED DATA-BLOCK*‚CALL�$DSDEAL* RETURN*INDENTED LIST END* CMBNDB„EQU„**6*ˆSKIP�CALL�IF�CURRENT�DATA�BLOCK�TOO�FULL�OR�FMS�DOES>*ˆNOT�HAVE�BUFFER,�OR�FILE�IS�SEQUENTIAL�OR�ONLY�READ�ASSIGNED*5ŠMOVEM.L�D1-D2/D5-D7/A0-A1/A3/A5,-(A7)�SAVE�REGISTERSFŠBSR.S�SKPCMB�SKIP�COMBINE�ATTEMPT�IF�SEQUENTIAL�FILE�OR�READ�ONLY�ASSŠBEQ.S‚CMBNG1�SKIP)ŠBTSTW‚#FAFLSB,FATFLG(A4)�FMS�HAS�BUFFER?ŠBEQ.S‚CMBNG1�NO,�SKIP�CALL8ŠMOVE.L�FATCFP(A4),A5†YES,�GET�CURRENT�FAB�ENTRY�POINTER)ŠMOVE.L�A5,D0ŽERROR�IF�NO�CURRENT�SEGMENTŠBEQ.S‚CMBNI1�.:ŠMOVE.L�FATSBL(A4),A3†GET�#�OF�BYTES�IN�USE�FOR�DATA�BLOCKŠMOVE.L�A3,D1Ž.ŠSUB.L‚FATSBS(A4),D1†.ŠADD.L‚#1,D1Ž. ŠCLR.L‚D2‘.<ŠMOVE.B�FCBDIR+DIRDAT(A2),D2�GET�1/DATFRC�OF�DATA�BLOCK�SIZEŠMOVE.L�D2,D0Ž.ŠMULUƒ#SECSZE/DATFRC,D0‚.0ŠCMP.W‚D0,D1ŽDATA�BLOCK�MORE�THAN�1/DATFRC�FULL?ŠBHI.S‚CMBNG1�YES,�SKIP�CALL*3*ˆCHECK�NEXT�DATA�BLOCK�NOT�MORE�THAN�1/DATFRN�FULL* ŠCLR.L‚D10ŠMOVE.B�FABKEY(A5),D1†GET�NEXT�FAB�ENTRY�POINTERŠLEA„FABSSL(A5,D1),A1ƒ.3ŠMOVE.L�FATFAE(A4),D7†GET�END�OF�FAB�BUFFER�ADDRESS!ŠSUB.L‚#1,D7Ž.�POINT�TO�LAST�WORD3ŠCMP.L‚D7,A1ŽCURRENT�FAB�ENTRY�THE�LAST�ONE�OF�FAB?ŠBCC.S‚CMBNG1�.�YES,�SKIP�CALLDŠTST.L‚(A1)�.�BECAUSE�COMBINING�BETWEEN�TWO�FABS�IS�TOO�MUCH�TO�CODEŠBEQ.S‚CMBNG1�YESEŠMOVE.B�FABSGS(A1),D1�NO,�GET�#�OF�SECTORS�IN�USE�FOR�NEXT�DATA�BLOCK"CMBNI1„BNE.S‚CMBNIE.1‹BRANCH�IF�OKŠBSR„ISTAIERR‹ERRORŠBRA.S‚CMBNRT.1=CMBNIE.1‚MULUƒ#SECSZE,D1‰#�OF�BYTES�IN�USE�IN�NEXT�DATA�BLOCK-ŠMOVE.L�D2,D0ŽGET�1/DATFRN�OF�DATA�BLOCK�SIZEŠMULUƒ#SECSZE/DATFRN,D0‚.5ŠCMP.W‚D0,D1ŽNEXT�DATA�BLOCK�MORE�THAN�1/DATFRN�FULL?ŠBLS.S‚CMBN05�NO CMBNG1„BRA„CMBNGR�YES,�SKIP�CALLŠPAGE*'*ˆCOMBINE�CURRENT�DATA�BLOCK�WITH�NEXT:=*ˆREAD�IN�NEXT�DATA�BLOCKS�SECTORS�AFTER�LAST�BYTE�OF�CURRENT *ˆDATA�BLOCK<*ˆA3=FATSBL,�A5=FATCFP,�A1=NEXT�FAB�ENTRY�POINTER,�D2=DIRDAT *ˆD7=FATFAE-1*8CMBN05„MOVE.L�(A1),D6ŒGET�NEXT�DATA�BLOCK'S�PSN�(FABPSN)ŠMOVE.L�A3,D0Ž.ŠADD.L‚#1,D0Ž.ŠADD.L‚A3,D1ŽGET�END�ADDRESSŠMOVE.L�D6,VDTIOS+IOSRRN(A6)ŠMOVE.L�D0,VDTIOS+IOSSAD(A6)ŠMOVE.L�D1,VDTIOS+IOSEAD(A6)6ŠMOVE.L�D1,A0ŽCLEAR�LONG�WORD�AT�END�OF�NEW�BUFFER�END  ŠCLR.L‚1(A0)ŠBSR„IOSREADŒREADŠBNE„CMBNRT�IO�ERROR**ˆGET�NEW�LOGICAL�BUFFER�END*&ŠMOVE.W�FCBDIR+DIRLRL(A2),D0�VRL�FILE?ŠBEQ.S‚CMBN11�YESŠCLR.L‚D1‘NO,�FRL;ŠMOVE.W�FABREC(A1),D1†GET�BUFFER�END�FROM�#�OF�RECORDS�READŠMULUƒD1,D0Ž.�BCT�OF�RECORDS-ŠADD.L‚D0,A3ŽNEW�BUFFER�ADDRESS�FOR�FRL�FILES ŠBRA.S‚CMBN25;CMBN10„MOVE.W�(A3)+,D0‹SKIP�RECORDS�TILL�GET�TO�END�OF�FILE)ŠBEQ.S‚CMBN20�.�END�OF�RECORDS�IF�BCT�=�0ŠADD.L‚D0,A3Ž.�SKIP�RECORDŠBTSTW‚#0,D0ŽODD�BCT�RECORD?ŠBEQ.S‚CMBN15�NO(CMBN11„ADD.L‚#1,A3ŽYES,�SKIP�FILLER�BYTE7CMBN15„CMP.L‚FATSBE(A4),A3†GETTING�BEYOND�BUFFER�LIMIT?.ŠBLS.S‚CMBN10�NO,�GO�CHECK�NEXT�RECORD�OR�DONE ŠBSR„ISTAIERRCMBNRT.1‚BRA.S‚CMBNRT.2/CMBN20„SUB.L‚#3,A3ŽNEW�BUFFER�END�FOR�VRL�FILES7CMBN25„MOVE.L�A3,FATSBL(A4)†SAVE�NEW�LOGICAL�BUFFER�END*0*ˆADJUST�FAB�AND�FAT�FOR�NEW�DATA�BLOCK�CONTENTS* ŠCLR.L‚D09ŠMOVE.B�FABSGS(A1),D0†REMOVE�SECTORS�FOR�ADDED�DATA�BLOCKŠSUB.L‚D0,FATLLS(A4)ŠSUB.L‚D0,FCBDIR+DIREOF(A2)CŠMOVE.W�FABREC(A1),D0ƒREMOVE�RECORDS�ASSOCIATED�WITH�THE�DATA�BLOCK;ŠSUB.L‚D0,FATLLR(A4)†.�THEY�WILL�BE�ACCOUNTED�FOR�BY�UPCFABŠSUB.L‚D0,FCBDIR+DIREOR(A2)*7*ˆSET�CURRENT�FAB�ENTRY�KEY�FROM�NEXT�ENTRY'S�KEY�FIELD* ŠCLR.L‚D0ŠMOVEM.L�A1/A5,-(A7)#ŠADD.L‚#FABKEY,A1‰MOVE�FROM�ADDRESS!ŠADD.L‚#FABKEY,A5‰MOVE�TO�ADDRESS8ŠMOVE.B�(A1)+,D0‹FULL�KEYS�IN�FAB�FOR�NOW�SO�SAME�LENGTH!ŠBEQ.S‚CMBN31�.�SKIP�IF�NULL�KEYS*ŠCMP.B‚(A5)+,D0‹.�ERROR�IF�NOT�SAME�LENGTHŠBEQ.S‚CMBN30�BRANCH�IF�OK:ŠBSR„ISTAIERR‰LATER�IF�HANDLE�PARITAL�FAB�KEYS�CHANGE�THISCMBNRT.2‚BRA.S‚CMBNRT&CMBN30„MOVE.B�(A1)+,(A5)+ˆMOVE�THE�KEYŠDCNTƒD0,CMBN30GCMBN31„MOVEM.L�(A7)+,A1/A5…RESTORE�FATCFP,�NEXT�FAB�ENTRY�POINTER�IN�A5ŠPAGE*1*ˆDELETE�THE�FAB�ENTRY�FOR�DATA�BLOCK�JUST�MERGED'*ˆA1�->�FAB�ENTRY�TO�BE�DELETED,�D0�=�0*>ŠMOVE.B�FABKEY(A1),D0†IS�THE�ENTRY�TO�BE�DELETED�THE�LAST�ONE?.ŠLEA„FABSSL(A1,D0),A3ƒ.�A3�->�ENTRY�AFTER�NEXTŠCMP.L‚D7,A3Ž.ŠBCC.S‚CMBN40�. ŠTST.L‚(A3)�.1ŠBEQ.S‚CMBN40�.�YES,�NEED�NOT�MOVE�REST�OF�FAB�UPFCMBN35„MOVE.W�(A3)+,(A1)+†NO,�MOVE�REST�OF�FAB�UP�TO�DELETE�NEXT�ENTRYŠCMP.L‚D7,A3Ž. ŠBLS„CMBN35�.CMBN40„MOVE.L�A1,A30CMBN45„CLR.W‚(A3)+ŽCLEAR�UNUSED�FAB�SPACE�AT�END ŠCMP.L‚D7,A3 ŠBLS„CMBN45�.!ŠCLR.L‚D5‘GET�NEW�FATKEY�INTO�FATŠMOVE.L�A5,A0Ž.ŠBSR.S‚GLLSFB�.*;*ˆDEALLOCATE�THE�DATA�BLOCK�THAT�WAS�APPENDED�TO�CURRENT�DB*-ŠMOVE.L�D6,A1ŽPSN�OF�1ST�SECTOR�TO�DEALLOCATE$ŠMOVE.L�D2,D1Ž#�OF�SECTORS�TO�DELETEŠBSR„DSDEAL�DEALLOCATEŠBNE.S‚CMBNRT�ERROR?*0*ˆADJUST�FAT/FAB/FCB�FOR�NEW�DATA�BLOCK�CONTENTS*ŠBSETW‚#FAFLUB,FATFLG(A4)'ŠBSR„DBFCHG�INDICATE�FAB�AND�DB�CHANGED;ŠMOVE.L�#1,D0‹LEAVE�FAB�ENTRY'S�KEY�ALONE�SINCE�ALREADY�SETŠBSR„UPCFAB�UPDATEŠBNE.S‚CMBNRT�ERRORCMBNGR„CLR.L‚D0‘OK>CMBNRT„MOVEM.L�(A7)+,D1-D2/D5-D7/A0-A1/A3/A5�RESTORE�REGISTERSŠRTS*ŠPAGEŠENDCƒFMSLEVEL-3ŠIFGTƒFMSLEVEL-1**$*ˆ************************************ŒGLLSFB�1.00�12/13/79�HBN6*$*ˆ************************************* GLLSFB GETS LAST LSN+1 AND LRN+1 FOR FAB&*ˆ(OR�#�OF�SECTORS�AND�RECORDS�IN�FAB)*&* ON ENTRY: D0 = 1ST LSN OF FAB (OR 0)*‹D1�=�1ST�LRN�OF�FAB�(OR�0)*‹D5�=�ONE�BYTE�VALUE%*‹A0�->�1ST�SEGMENT�DESCRIPTOR�IN�FABA* ON RETURN: D0 = LAST LSN+1 OF FAB (OR # OF SECTORS IF D0 WAS 0)6*‹D1�=�LAST�LRN+1�OF�FAB�(OR�#�OF�RECORDS�IF�D1�WAS�0)*‹A0,�D5�=�UNCHANGED*‹A1�->�END�OF�FAB�ENTRIES�+�1!*‹A5�->�LAST�KEY�BCT�FIELD�OF�FAB+*‹IF�EMPTY�FAB�D0,D1,A1,�AND�A5�MEANINGLESS*)GLLSFB„MOVEM.L�D5-D6,-(A7)‡SAVE�REGISTERS ŠCLR.L‚D6 ŠMOVE.L�A0,A1ŠTST.L‚(A0)�EMPTY�FAB?ŠBEQ.S‚GLLSFR�YES:GLLSF0„MOVE.B�FABSGS(A1),D5†#�OF�SECTORS�IN�USE�IN�SEGMENTŠADD.L‚D5,D0ŽADD�THEM�TO�LSN-ŠMOVE.W�FABREC(A1),D6†#�OF�RECORDS�IN�SEGMENTŠADD.L‚D6,D1ŽADD�THEM�TO�LRN$ŠLEA„FABKEY(A1),A5†A5->KEY�BCT�FIELD ŠMOVE.B�(A5),D5ŒGET�FIELD�LENGTH1ŠLEA„FABSSL+2(A1,D5),A1�POINTER�TO�NEXT�FAB�ENTRY ŠCMP.L‚FATFAE(A4),A1†END�OF�FAB?%ŠSUB.L‚#2,A1ŽCOND.�CODE�NOT�DESTROYEDŠBCC.S‚GLLSF5�YES#ŠTST.L‚(A1)�NO,�END�OF�FAB�ENTRIES?"ŠBNE.S‚GLLSF0�NO ,�COUNT�NEXT�ENTRYGLLSF5„MOVE.L�A5,FATKEY(A4)†.,GLLSFR„MOVEM.L�(A7)+,D5-D6‡RESTORE�REGISTERSŠRTS*$*ˆ************************************ŒLASTSG�1.00�12/13/79�HBN6*$*ˆ***********************************A*‚LASTSG�FINDS�OUT�IF�CURRENT�SEGMENT�IS�THE�LAST�ONE�OF�THE�FILE* *‚ON�CALL:(*ˆD1�=�CURRENT�SEGMENT�FAB�ENTRY�POINTER *‚ON�RETURN: *ˆA0�=�CURRENT�FAB�ENTRY�POINTER*ˆD1�=�CURRENT�SEGMENT�LAST�LSN-*ˆZ�=�1�IF�SEGMENT�IS�THE�LAST�ONE�(D1�=�EOF) *Œ0�IF�NOT* LASTSG„EQU„*.ŠMOVE.L�D1,A0ŽGET�CURRENT�SEGMENT'S�ENDING�LSNŠMOVE.L�FATSLS(A4),D1†. ŠCLR.L‚D0‘.7ŠMOVE.B�FABSGS(A0),D0†.�#�OF�SECTORS�IN�CURRENT�SEGMENTŠADD.L‚D0,D1Ž.%ŠSUB.L‚#1,D1ŽD1�=�LAST�LSN�OF�SEGMENT5ŠCMP.L‚FCBDIR+DIREOF(A2),D1�IS�THIS�THE�LAST�SEGMENT?ŠRTSŠPAGEŠENDCŠIFEQƒFMSLEVEL-3**$*ˆ************************************‹CMBNFB�1.00�1/17/80�HBN6*$*ˆ***********************************?*‚CMBNFB�TRIES�TO�COMBINE�CURRENT�FAB�WITH�NEXT�ONE�IF�BOTH�ARE.*‰SUFFICIENTLY�EMPTY�(�AND�A�NEXT�FAB�EXISTS�)*#*‚ENTRY�AND�EXIT�SAME�AS�FOR�CMBNDB**INDENTED LIST-* CMBNFB TRIES TO MERGE CURRENT FAB WITH NEXT*CMBNFB PASS CURRENT FAB* POSSIBLE TO MERGE?*‚CALL�$SKPCMB,�$GPTSEC*ƒNO,�RETURN�UNCHANGED�FAB * YES, MERGE!*‚CALL�$IOSREAD,�$GLLSFB,�$NXTFHD* DEALLOCATE MERGED FAB*‚CALL�$DSDEAL* RETURN*INDENTED LIST END* CMBNFB„EQU„**/ŠMOVEM.L�D1-D7/A0-A1/A3/A5,-(A7)�SAVE�REGISTERS*<*ˆSKIP�CALL�IF�SEQUENTIAL�FILE�OR�ASSIGNED�FOR�READ�ONLY,�OR#*ˆALREADY�KNOW�NEXT�FAB�IS�TOO�FULL*EŠBSR‚SKPCMB�SKIP�CALL�IF�SEQUENTIAL�FILE�OR�READ�ONLY�TYPE�ASSIGNMENTŠBEQ.S‚CMBFG1�SKIP/ŠBTSTW‚#FAFLMB,FATFLG(A4)�IS�NEXT�FAB�TOO�FULL?ŠBNE.S‚CMBFG1�YES-RETURN*$*ˆIS�CURRENT�FAB�SUFFICIENTLY�EMPTY?*0ŠMOVE.L�FATKEY(A4),A1†GET�LAST�FAB�ENTRY�POINTER2ŠMOVE.L�A1,D0Ž.�ERROR�IF�NO�LAST�KEY�FIELD�POINTERŠBNE.S‚CMBF00�.ŠBSR„ISTAIERR‹ERRORCMBFR1„BRA„CMBFRT CMBF00„EQU„*(ŠCLR.L‚D0‘GET�END�OF�FAB�ENTRIES�POINTERŠMOVE.B�(A1)+,D0‹LENGTH�OF�KEYŠADD.L‚D0,A1Ž.'ŠMOVE.L�A1,D7Ž.�SAVE�END�OF�FAB�POINTER(ŠMOVE.L�FATFAA(A4),A3†.�FAB�BUFFER�START#ŠSUB.L‚A3,A1ŽA1�=�BCT�OF�FAB�IN�USE1ŠMOVE.B�FCBDIR+DIRFAB(A2),D0�GET�FAB�SECTOR�COUNTŠMOVE.L�D0,D6Ž.�SAVE,ŠMULUƒ#SECSZE/FABFRC,D0‚GET�1/FABFRC�FAB�BCTŠMOVE.L�D0,D5Ž.�SAVE,ŠCMP.L‚D0,A1ŽIS�FAB�MORE�THAN�1/FABFRC�FULL?ŠBHI.S‚CMBFG1�YES,�SKIP�CALL*6*ˆYES,�READ�IN�NEXT�FAB'S�1ST�SECTOR�TO�CHECK�ITS�SIZE6*ˆD7�->�END�OF�FAB�ENTRIES�IN�CURRENT�FAB,�A3�=�FATFAA)*ˆD6�=�FAB�SIZE,�D5�=�BCT�OF�FAB�FRACTION*.ŠMOVE.L�(A3),D0ŒGET�NEXT�FAB'S�PSN�FROM�FABPSNŠMOVE.L�D0,D4ŽSAVE&ŠBEQ.S‚CMBFG1�SKIP�CALL�IF�NO�NEXT�FABŠMOVE.L�#IOREAD,D1‰READ3ŠBSR„GPTSEC�A1�RETURNS�POINTING�TO�SECTOR�JUST�READŠBNE.S‚CMBFR1�IO�ERROR,ŠMOVE.L�#ISTAFAB+NL,D0…EMPTY�FAB�MEANS�ERROR.ŠMOVE.L�A1,D2ŽSave�address�of�temporary�buffer ŠCLR.L‚D3‘./ŠMOVE.B�FABUSE(A1),D3†.�GET�FABUSE�FOR�NEXT�FABŠBEQ„CMBFRT�ERROR6ŠCMP.B‚#FABFRN,D3‰NEXT�FAB�LESS�THAN�FABFRN/16TH�FULL?ŠBLS.S‚CMBF05�YES>ŠBSETW‚#FAFLMB,FATFLG(A4)�SET�NEXT�FAB�TOO�FULL�FOR�MERGE�FLAG7CMBFG1„BRA„CMBFGR�TOO�MUCH�STUFF,�DON'T�BOTHER�TO�MERGE*8*ˆMOVE�FAB�ENTRIES�FROM�1ST�SECTOR�TO�END�OF�CURRENT�FAB;*ˆD4�=�NEXT�FAB�PSN,�D3�=�NEXT�FAB�USAGE�COUNT,�D2�=�VIBSTR*CMBF05„BSR„FABCHG ŠCLR.L‚D0ŠMOVE.L�D7,A0ŽMOVE�TO�ADDRESS$ŠMOVE.B�FABPKY(A1),D0†GET�FABPKY�BCT.ŠLEA„FABSEG(A1,D0),A1ƒTO�GET�MOVE�FROM�ADDRESS* vvvvvvvvv Changed 9/3/83 SCB.1* Merge first sector of next FAB with current one<ŠMOVE.L�FATFAA(A4),D1†Next�FAB�memory�block�starting�address7ŠADD.L‚#SECSZE,D1‰Ending�address�of�1st�sector�next�FAB+CMBF10„MOVE.B�(A1)+,(A0)+ˆMove�stuff�to�FAB ŠCMP.L‚D1,A0ŽAre�we�done�moving?ŠBNE.S‚CMBF10�Branch�if�no%* See if FAB was longer than 1 sector ŠSUB.L‚#1,D67ŠBEQ.S‚CMBF30�Branch�if�one�sector�long�-�merge�is�doneH* We need to read in extra sectors from next FAB to merge with this one.F*ƒA0�points�to�the�memory�address�we�need�to�read�in�to.‚Construct�theG*ƒlargest�possible�block�read�of�the�next�FAB�(starting�with�2nd�sectorD*ƒsince�1st�sector�all �ready�merged)�into�this�one�without�exceeding+*ƒbuffer�boundaries�for�this�FAB�of�course!*6ŠMOVE.L�A0,VDTIOS+IOSSAD(A6)�Starting�address�for�read<ŠMOVE.L�FATFAE(A4),VDTIOS+IOSEAD(A6)�Ending�address�for�read?ŠMOVE.B�VDTIOS+IOSSAD+3(A6),D0�Force�integral�block�read�by�....ŠSUB.L‚#1,D0Ž...�adjusting�ending�read�addressŠMOVE.B�D0,VDTIOS+IOSEAD+3(A6)*^^^^^^^^^^ Changed 9/3/83 SCB.-ŠADD.L‚#1,VDTIOS+IOSRRN(A6)�READ�NEXT�SECTORSŠBSR.S‚IOSREADŒREAD�WITH�WAITŠBNE.S‚CMBFRT�IO�ERROR*9*ˆGET�#�OF�RECORDS�AND�SECTORS�ADDED�FROM�NEXT�FAB�TO�FAT*CMBF30„CLR.L‚D0 ŠCLR.L‚D1 ŠCLR.L‚D5'ŠMOVE.L�D7,A0ŽA0�->�1ST�FAB�ENTRY�ADDED8ŠBSR„GLLSFB‹GET�#�OF�RECORDS�AND�SECTORS,�SET�NEW�FATKEY*ŠADD.L‚D0,FATLLS(A4)†UPDATE�FAB'S�LAST�LSNŠADD.L‚D1,FATLLR(A4)†AND�LRN*2*ˆDELETE�AND�DEALLOCATE�NEXT�FAB�(FAB�JUST�MERGED)*%ŠMOVE.L�FATFAB(A4),D3†CURRENT�FAB�PSNFŠMOVE.L�D2,A5�A5�->�NEXT�FAB'S�FIRST�SECTOR�AGAIN�(DESTROYED�BY�GLLSFB:ŠMOVE.L�(A5),D5ŒGET�FABFLK�FOR�FAB�AFTER�NEXT�(3RD�IN�ROW)<ŠMOVE.L�D5,(A3)ŠSET�FORWARD�LINK�IN�CURRENT�FAB�TO�SKIP�NEXT5ŠBNE.S‚CMBF35�CURRENT�FAB�LAST�IN�CHAIN�AFTER�DELETE?0ŠMOVE.L�D3,FCBDIR+DIRFE(A2)�SET�LAST�FAB�POINTER&ŠBSETW‚#FCFLDB,FCBFLG(A2)�IN�DIRECTORY&CMBF35„ADD.L‚#1,D6ŽD6�=�FAB�SIZE�AGAIN(ŠMOVE.L�D6,D1Ž#�OF�SECTORS�TO�DEALLOCATEŠMOVE.L�D4,A1ŽSTARTING�PSNŠBSR„DSDEAL�DEALLOCATEŠBNE.S‚CMBFRT�ERROR* *ˆUPDATE�HEADER�FOR�NEW�NEXT�FAB*:ŠMOVE.L�#2,D0ŒUPDATE�BACKWARD�LINK�AND�KEY�IN�NEW�NEXT�FABŠMOVE.L�D3,D4ŽBACKWARD�LINK(ŠMOVE.L�D5,D3ŽNEXT�FAB�PSN�(THE�NEW�ONE)ŠBSR„NXTFHD�UPDATE�ITS�HEADERŠBNE.S‚CMBFRT�ERRORCMBFGR„CLR.L‚D0‘GOOD�RETURN8CMBFRT„MOVEM.L�(A7)+,D1-D7/A0-A1/A3/A5�RESTORE�REGISTERSŠRTSŠPAGEŠENDC**$*ˆ************************************ŒIOSREAD�1.00�1/30/80�HBN6*$*ˆ***********************************9*‚IOSREAD�READS�FROM�DISK�WITH�WAIT,�IMAGE,�RANDOM�SECTOR3*ŠON�CALL�PARAMETER�BLOCK�(VDTIOS)�IS�SET�UP�EXCEPT*ŠFOR�FUNCTION�AND�OPTION�CODES**‚ON�CALL:�A6�=�VDT�ADDRESS*0*‚ON�RETURN:�ALL�REGISTERS�ARE�UNCHANGED�EXCEPT:*‹A0�->�VDTIOS*‹D0�=�0�IF�NO�ERROR*‹D0.B�=�80+�OTHERWISE*‹Z�=�1�IF�NO�ERROR *�0�IF�ERROR*IOSREADƒMOVE.L�#IOREAD,D0ŠBRA.S‚IOSRDWR**$*ˆ************************************ŒIOSWRITE�1.00�1/30/80�HBN6*$*ˆ***********************************.*‚IOSWRITE�IS�SAME�AS�IOSREAD�EXCEPT�FOR�WRITE*IOSWRITE‚MOVE.L�#IOWRIT,D0**IOSRDWRƒSETRFO�D0,IOPIMG+IOPRAN,VDTIOS(A6) ŠBSR„DOIOŠRTSŠPAGEŠIFGTƒFMSLEVEL-1* *ALDBF 1.00 7/10/80 L. STEINHOFF*AL2DBF*;*ALDBF ALLOCATES DISK SPACE FOR FAB AND DATA BLOCK AND PUTS*…THEIR�PSN'S�IN�TABLE�ON�STACK(*AL2DBF ALLOCATES 2 DATA BLOCKS AND FABB* *ON CALL:*…D0=POINTER�TO�AREA�ON�STACK*…A2=FCB�ADDR.*…A6=VDT�ADDR.*…BSR�ALDBF�OR�AL2DBF* *ON RETURN:*…Z=1�IF�NO�ERROR *†=0�IF�ERROR*…D0.B=0�IF�NO�ERROR*‰=80+�IF�I/O�ERROR* AL2DBF„EQU„*ŠMOVEM.L�A0-A1/D1,-(A7) ŠMOVE.L�D0,A0 ŠBSR.S‚ALLODB$ŠBNE.S‚AL2DRT�ERROR�ON�DB�ALLOCATION"ŠMOVE.L�A1,8(A0)‹SAVE�DB�PSN�ADDR.AL2D10„BSR.S‚ALLODB ŠBNE.S‚AL2DRTŠMOVE.L�A1,4(A0) ŠBSR.S‚ALLOFB ŠBNE.S‚AL2DRTŠMOVE.L�A1,(A0)AL2DRT„MOVEM.L�(A7)+,A0-A1/D1 ŠTST.B‚D0ŠRTS**ALLOCATE 1 DB AND 1 FAB* ALDBF…EQU„*ŠMOVEM.L�A0-A1/D1,-(A7) ŠMOVE.L�D0,A0 ŠBRA.S‚AL2D10ŠPAGE*!*ALLODB 1.00 7/10/80 L. STEINHOFF*ALLOFB*#*ALLODB CALLS DSALLC TO ALLOCATE DB*ALLOFB DOES SAME FOR FAB* *ON CALL:*…A2=FCB�ADDR.*…BSR�ALLODB�OR�ALLOFB* *ON RETURN:!*…SEE�DSALLC�FOR�RETURN�REGISTERS* ALLODB„EQU„* ŠCLR.L‚D1(ŠMOVE.B�FCBDIR+DIRDAT(A2),D1�GET�DB�SIZE ALLOD10ƒEQU„* ŠBSR„DSALLCŠRTS ALLOFB„EQU„* ŠCLR.L‚D1)ŠMOVE.B�FCBDIR+DIRFAB(A2),D1�GET�FAB�SIZEŠBRA.S‚ALLOD10ŠPAGE*!*DEALDB 1.00 7/10/80 L. STEINHOFF*DEALFB**DEALDB DEALLOCATES DB*DEALFB DOES SAME FOR FAB* *ON CALL:*…A1=PSN�OF�DATA�BLOCK�FAB*…A2=FCB�ADDR.*…BSR�DEALDB�OR�DEALFB* *ON RETURN:!*…REGISTERS�AS�RETURNED�BY�DSDEAL* DEALDB„EQU„* ŠCLR.L‚D1,ŠMOVE.B�FCBDIR+DIRDA T(A2),D1�DATA�BLOCK�SIZEDEALD10ƒBSR„DSDEALŠRTS DEALFB„EQU„* ŠCLR.L‚D1+ŠMOVE.B�FCBDIR+DIRFAB(A2),D1�FAB�BLOCK�SIZEŠBRA.S‚DEALD10ŠPAGE* *DBCHG 1.00 6/16/80 L. STEINHOFF*FABCHG*DBFCHG*+*DBCHG SETS THE DATA BLOCK CHANGED FLAG AND&*…IF�OTHER�ASSIGNMENTS�EXIST�FOR�FILE,+*…THEIR�DATA�BLOCKS�ARE�CHECKED.‚IF�SAME�DB,*…IS�IN�MEMORY,�IT�IS�MARKED�AS�NON=EXISTENT-*…SO�NEW�DB�WILL�BE�RETRIEVEE�ON�NEXT�REQUEST*FABCHG DOES SAME FOR FAB,*…EXCEPT�CHANGED�FAB�IS�MOVED�TO�OTHER�USERS-*DBFCHG DOES SAME FOR BOTH DATA BLOCK AND FAB* *ON CALL:*…A4=FAT�ADDR.*…BSR�DBCHG�OR�FABCHG�OR�DBFCHG* *ON RETURN:*…AL�REGISTERS�ARE�UNALTERED* DBCHG…EQU„*ŠMOVEM.L�D0-D3/A0-A2,-(A7)ŠMOVE.L�#FAFLDBV,D0ˆDB�CHANGED ŠBRA.S‚DBFC10 FABCHG„EQU„*ŠMOVEM.L�D0-D3/A0-A2,-(A7)ŠMOVE.L�#FAFLFBV,D0ˆFAB�CHANGED ŠBRA.S‚DBFC10 DBFCHG„EQU„*ŠMOVEM.L�D0-D3/A0-A2,-(A7).ŠMOVE.L�#FAFLDBV+FAFLFBV,D0�DB�AND�FAB�CHANGED-DBFC10„OR.WƒD0,FATFLG(A4)†SET�CHANGED�FLAG(S)1*SEE IF MORE THAN ONE ASSIGNMENT EXISTS FOR FILE.(*…WCNT/RCNT�IN�RANGE�-1�TO�1�IF�ONE�USER ŠBSR„CHKMAŠBEQ.S‚DBFC30�ONLY�ONE�ASSIGN+*MORE�THAN�1�ASSIGNMENT�EXISTS.‚SEE�IF�DATA**…BLOCK/FAB�IS�IN�MEMORY�FOR�ANOTHER�ASSN.#ŠMOVE.L�FATFAB(A4),D1†D1=PSN�OF�FAB,ŠMOVE.L�FATCFP(A4),D2†POINTS�TO�D.B.�POINTER%ŠSUB.L‚FATFAA(A4),D2†D2=OFFSET�TO�CFP$ŠMOVE.L�FATSTR,A1ŠGET�START�OF�FAT'S*MUST BE SAME FCBDBFC20„MOVE.L�FATFCB(A1),D3ŠCMP.L‚FATFCB(A4),D3 ŠBNE.S‚DBFC25"ŠCMP.L‚FATFAB(A1),D1†FOR�THIS�FAB?ŠBNE.S‚DBFC25�NO-SKIP ŠCMP.L‚A1,A4 ŠBEQ.S‚DBFC25�SKIP�CURRENT�ENTRY$ŠBTSTƒ#FAFLDB,D0‰DATA�BLOCK�CHANGED?ŠBEQ.S‚DBFC22�NOŠMOVE.L�FATCFP(A1),D3ŠSUB.L‚FATFAA(A1),D3ŠCMP.L‚D2,D3ŽOOFSETS�THE�SAME?ŠBNE.S‚DBFC22�NO%ŠCLR.L‚FATCFP(A1)‰INDICATE�NO�CFP�AND(ŠBCLRW‚#FAFLDB,FATFLG(A1)�DB�NOT�CHANGED#DBFC22„BTSTƒ#FAFLFB,D0‰FAB�CHANGED?ŠBEQ.S‚DBFC25�NO#*MOVE THIS FAB TO OTHER USER'S AREA%ŠBSR.S‚GETOSG�ATTACH�OT�OTHER�SEGMENTŠMOVE.L�FATFAA(A4),A0ŠMOVE.L�FATFAA(A1),A2DBFC23„MOVE.L�(A0)+,(A2)+ŠCMP.L‚FATFAE(A4),A0†AT�END?ŠBLS.S‚DBFC23�NO4ŠMOVE.L�FATKEY(A4),FATKEY(A1)�UPDATE�FAB�INFO�IN�FATŠMOVE.L�FATLLS(A4),FATLLS(A1)ŠMOVE.L�FATLLR(A4),FATLLR(A1)*ŠBSR.S‚GETCSG�YES-ATTACH�TO�COMMON�SEGMENT)ŠBCLRW‚#FAFLFB,FATFLG(A1)�FAB�NOT�CHANGEDDBFC25„LEA„FATLEN(A1),A1ŠCMP.L‚FATEND,A1!ŠBLS.S‚DBFC20�GO�CHEKC�NEXT�ENTRY DBFC30„MOVEM.L�(A7)+,D0-D3/A0-A2ŠRTSŠPAGE* *GETOSG 1.00 7/3/80 L. STEINHOFF*-*GETOSG DEATTACHES FROM SHARED COMMON SEGMENT+*…AND�ATTACHES�TO�OTHER�USER'S�DATA�SEGMENT* *ON CALL:*…A1=OTHER�FAT�ADDR.*…A4=FAT�ADDR. *…BSR�GETOSG*$* DOES TO FMSFTL IF ERROR FROM DESEG* GETOSG„EQU„*ŠMOVEM.L�D0/A0,-(A7)ŠERQ.DESEG�SEGBLKSGETOS10ƒBSR„FTL.NE ŠEXG„A4,A1 ŠBSR„ATTIOBO ŠEXG„A4,A1ŠMOVEM.L�(A7)+,D0/A0ŠRTSŠPAGE* *GETCSG 1.00 7.3.80 L. STEINHOFF*)*GETCSG DEATTACHES FROM OTHER SEGMENT AND&*…RE-ATTACHES�TO�SHARED�COMMON�SEGMENT* *ON CALL: *…BSR�GETCSG*+*GOES TO FMSFTL IF ERROR ON EXEC DIRECTIVES* GETCSG„EQU„*ŠMOVEM.L�A0/D0,-(A7)ŠERQ.DESEG�SEGBLKOŠBNE.S‚GETOS10ŒFATALŠERQ.ATTSEG�SEGBLKSŠBNE.S‚GETOS10ŒFATALŠMOVEM.L�(A7)+,D0/A0ŠRTSŠENDCƒFMSLEVEL-1%*************************************-* ISTAIERR SAVES ADDRESS OF ISTAIE ERROR (C7)(*ƒIN�FDTA�AT�C7ERR�FOR�USE�IN�DEBUGGING.**�ENTRY:ƒBSR‚ISTAIERR**�EXIT:„D0�=�#NL+ISTAIE/*ŠC7ADDR�=�ADDRESS�OF�INSTRUCTION�FOLLOWING�BSR*ISTAIERR‚EQU„*ŠMOVE.L�(A7),C7ADDRŠMOVE.L�#NL+ISTAIE,D0ŠRTS%*************************************-* ISTAUFRR SAVES ADDRESS OF ISTAUF ERROR (CE))*ƒIN�FDTA�AT�CEADDR�FOR�USE�IN�DEBUFFING.**�ENTRY:‚BSR„ISTAUFRR**�EXIT:ƒD0�=�#NL+ISTAUF/*‰CEADDR�=�ADDRESS�IF�INSTRUCTION�FOLLOWING�BSR*ISTAUFRR‚EQU„*ŠMOVE.L�(A7),CEADDRŠMOVE.L�#NL+ISTAUF,D0ŠRTSŠENDé éé=/* =/*†FIOS.AF=/*"=/* Chain file to assemble FIOS.SA=/*:=/* If no output argument is specified for the listing the&=/* chain file will default to FIOS.LS=/*=/IFC \1 ƒ=ARG�FIOS.LS=/ENDIF=/*&=ASM FMSI.SA/FIOS.SA,FIOS.RO,\1;RZ=186=/*{ Included files are:=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.EXE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.TR1.EQ=/*ƒ9995.&.FME.EQ=/*ƒ9995.&.FMI.EQ=/*}=/*=ENDééééééÊŠPAGEŠNOLISTŠINCLUDE�9995.&.TR1RTCD.EQŠINCLUDE�9995.&.IOE.EQŠINCLUDE�9995.&.EXE.EQŠINCLUDE�9995.&.NIO.EQŠINCLUDE�9995.&.TR1.EQŠINCLUDE�9995.&.FME.EQŠINCLUDE�9995.&.FMI.EQŠLIST*‰INCLUDE�9995.&.IOE.EQ*‰INCLUDE�9995.&.TR1RTCD.EQ*‰INCLUDE�9995.&.EXE.EQ*‰INCLUDE�9995.&.NIO.EQ*‰INCLUDE�9995.&.TR1.EQ*‰INCLUDE�9995.&.FME.EQ*‰INCLUDE�9995.&.FMI.EQ*ŠPAGE*E* 3/15/84 At label FMRW22B changed BCS IOSER6, BCS IOSER8 to indicate@*„invalid�random�record�instead�of�end�of�volume�when�the�volume)*„read�begins�past�the�end�of�the�volume.*!*HANDLE IOS REQUEST FOR DISK FILE**„A1=ADDR.�OF�ASQ1�ENTRY ŠSECTION�0 ŠDC.Bƒ'FIOS'ŠDC.Lƒ'031584�4'‰IDENTIFICATIONIOS‡IDNTƒ4,2�IOS�HANDLER ŠXDEFƒFMRW15 ŠXDEFƒFMSIOS ŠXDEFƒIREWIND ŠXREFƒACKREQ ŠXREFƒCALREC ŠXREFƒCHKASN ŠXREFƒCHKWPD ŠXREFƒCLRIOP ŠXREFƒDEVBSY ŠXREFƒDOIO ŠXREFƒFMSBLK1 ŠXREFƒFMSF35 ŠXREFƒFMSREV ŠXREFƒFMSRTN ŠXREFƒFTL.EQ ŠXREFƒFTL.HI ŠXREFƒFTL.NE ŠXREFƒFTL.T ŠXREFƒGETVID ŠXREFƒICMDJPŠXREFƒISTAIERR ŠXREFƒMOVE2U ŠXREFƒPUTALL ŠXREFƒSETBEG ŠXREFƒSETPTR ŠXREFƒSMOVE4 ŠXREFƒSMOVEA ŠXREFƒZERPTRŠIFGTƒFMSLEVEL-1 �XREFƒATTIOB �XREFƒCMPSPC �XREFƒDBCHG �XREFƒFSALLC �XREFƒFSDEAL �XREFƒGETFDB �XREFƒGETIOB �XREFƒMVEDTA �XREFƒMVEREC  �XREFƒPUTDAT �XREFƒUPCFAB �XREFƒUPDEOF �XREFƒUPDEORŠENDC*ŠIFGTƒFMSLEVEL-2 �XREFƒCMPKEY �XREFƒCMPRDB �XREFƒEXPNDB �XREFƒFNDKEY �XREFƒMVEKEY �XREFƒPUTKEYŠENDCF************************************************************************INDENTED LIST** FMSIOS HANDLES I/O FOR FILES AND VOLUMES*FMSIOS * WAIT ONLY?*‚YES,BLOCK�TASK-UNTIL�I/O�DONE* PROCEED I/O?*‚YES,�ACKNOW.�REQUEST�$ACKREQ * ERROR-IF DEVICE STATUS CHANGED*‚CHECK-FOR�DEVICE�BUSY�$DEVBSY*ƒREAD-OR�POSITION�REQUEST?"*„NO,ERROR�IF-DISK�WRITE�PROTECTED* FORMAT REQUEST?"*‚YES,FORMAT�VOLUME-OR�TRACK�$DOIO&*ƒINDICATE�NO-TABLES�IN-MEMORY�$ZERPTR*„READ�VOLUME-ID�$GETVID*…MAKE�GOOD�RETURN�$FMSRTN* WRITE, DELETE, UPDATE? ÓfÜDä=ìIôEüAG <FB$J,>4B<HDCL>TB\IdKlKtE|H„RŒ(*‚YES,MAKE�SURE-FILE�NOT-WRITE�PROTECTED* CALCULATE USER RECORD LENGTH* VOLUME OR-CONT. FILE?*‚YES,GO-TO�BLOCK-I/O�$FBLK*‚NO,ERROR�IF�SEC.�MAP*ƒDATA�SEGMENT�EXIST?*„NO,�ALLOCATE�SEGMENT�$GETIOB*„YES,ATTACH�TO-SEG.�$ATTIOB* READ OR POSITION?*‚NO,�OVERWRITE�REQUEST?*ƒYES,CLEAR�OVERWRITE�FLAG*„ALREADY�DONE�OVERWRITE?*…NO,DEAL.�FILE�SPACE�$FSDEAL * RECORD I/O?*‚NO,GO�TO-BLOCK�I/O�$FBLK*‚YES,GO�TO-RECORD�I/O�$FREC*INDENTED LIST END* FMSIOS„EQU„*(ŠLEA„FMSBLK1,A5‰GET�ADDR.�OF�PARM.�BLOCK*GET ADDR. OF FAT, FCB, AND VDT ŠBSR„SETPTR*A6=VDT, A4=FAT, A2=FCB ADDR.ŠMOVE.L�A6,A3ŽSAVE�VDT�ADDR.%ŠSUB.L‚A6,A6Ž0�A6�UNTIL�DEVBSY�CALLED**IF WAIT ONLY REQUEST, MAKE SURE I/O STILL1*…PENDING�AND�THEN�BLOCK�TASK�UNTIL�I/O�COMPLETESŠCMP.W‚#IOWAIT,IOSFCT(A5) ŠBNE.S‚FMRW01*CLEAR PROCEED I/O BIT!ŠBCLRW‚#IOPWATB,FATIOS+IOSOPT(A4)ŠMOVE.L�EVTLUE(A1),A0&ŠBTSTW‚#LUSFIO,LUTCAP(A0)�I/O�PENDING?ŠBEQ„IOSGRT�NOŠBRA„FMSREV�RETURN�FROM�EVENT FMRW01„EQU„*9ŠMOVE.L�EVTRA0(A1),FATUPB(A4)�SAVE�USER�PARM.�BLOCK�ADDR.ŠMOVE.W�#IOSBLN/2,D0*MOVE USER PARM. BLOCK TO FATŠLEA„FATIOS(A4),A0FMRW02„MOVE.W�(A5)+,(A0)+ŠDCNTƒD0,FMRW02*****************C*FROM HERE ON OUT IN IOS, NOTHING IS NEEDED FROM FMSASQ1 OR FMSBLK1*$*IF PROCEED I/O REQUEST, ACKNOWLEDGE*…REQUEST�TO�USER�NOW�SO�ON#*…COMPLETION�OR�IF�ERROR�LATER,�I/O!*…COMPLETION�EVENT�WILL�BE�QUEUED.ŠBTSTW‚#IOPWATB,FATIOS+IOSOPT(A4)�PROCEED�I/O?ŠBEQ.S‚FMRW04�NO$ŠCLR.L‚D1‘VALUE�TO�BE�RETURNED�IN�D0ŠMOVE.L�FATTSK(A4),D2ŠMOVE.L�FATSES(A4),D3ŠMOVE.L�#IOSTIN,D4ŠBSR„ACKREQ�ACKNOWLEDGE�REQUEST FMRW04„EQU„**ERROR IF DEVICE STATUS CHANGEDŠBTSTW‚#FCFLCB,FCBFLG(A2)(ŠBNE„IOSER13ŒDEVICE�STATUS�CHANGED�ERRORŠMOVE.L�A3,A6ŽRESTORE�VDT�ADDR./ŠBSR„DEVBSY�DON'T�GO�ANY�FURTHER�IF�DEVICE�BUSY&*ONLY A2,A4, AND A6 ARE MEANINGFUL NOW/ŠTST.B‚FATIOS+IOSFCT(A4)‚DATA�TRANSFER�REQUEST?ŠBEQ.S‚FMRW05�YES/*NO-MUST BE COMMAND-JUMP TO APPROPRIATE ROUTINEŠMOVE.L�#ICMDJP,A0ŠMOVE.W�FATIOS+IOSFCT(A4),D0 ŠBRA„FMSF35 FMRW05„EQU„*:*UNLESS READ REQUEST, MAKE SURE DISK IS NOT WRITE PROECTED ŠCMP.W‚#IOREAD,FATIOS+IOSFCT(A4)ŠBEQ.S‚FMRW05A!ŠBSR„CHKWPD�WRITE�PROTECTED�DISK?ŠBNE„IOSERR�YES-ERROR FMRW05AƒEQU„*0*IF REQUEST IS FORMAT, MUST BE EREW VOLUME ASSN.(ŠCMP.W‚#IOFRMT,FATIOS+IOSFCT(A4)�FORMAT?ŠBNE.S‚FMRW06�NOŠCMP.B‚#'�',FCBDIR+DIRFIL(A2))ŠBNE.S‚FMRER4�NOT�VOLUME-INVALID�FUNCTIONŠMOVE.L�FATLUE(A4),A0ŠCMP.B‚#FOPEREW,LUTCAP(A0)FMRER4„BNE„FMER4ŽNOT�EREW&*GO AHEAD AND REQUEST FORMAT OF DEVICE;ŠMOVE.W�FATIOS+IOSFCT(A4),VDTIOS+IOSFCT(A6)�SET�UP�FUNCTION:ŠMOVE.W�FATIOS+IOSOPT(A4),VDTIOS+IOSOPT(A6)�SET�UP�OPTIONS%*RRN CONTAINS PSN IF FORMATTING TRACK+ŠMOVE.L�FATIOS+IOSRRN(A4),VDTIOS+IOSRRN(A6)ŠBSR„DOIO�ISSUE�I/O ŠBRA„PROS66 FMRW06„EQU„*F*IF WRITE/UPDATE/DELETE REQUEST, DON'T ALLOW IF WRITE PROTECT CODE=$FFŠMOVE.W�FATIOS+IOSFCT(A4),D0ŠAND.W‚#IOWRIT+IODELR+IOUPDR,D0ŠBEQ.S‚FMRW15�MUST�BE�READ-ŠCMP.B‚#$FF,FCBDIR+DIRWCD(A2)�WRITE�CODE=$FF?ŠBEQ„IOSER1�YES-PROTECT�ERROR% *DETERMINE IF BLOCK OR RECORD REQUEST5*IF VOLUME OR CONTIGUOUS FILE ASSIGN, FORCE BLOCK I/O**ENTRY POINT FOR POSITION *…D6=IOSSAD *…D7=IOSEAD**CALCULATE USER BUFFER LENGTH"FMRW15„MOVE.L�FATIOS+IOSSAD(A4),D6ŠMOVE.L�FATIOS+IOSEAD(A4),D7 ŠMOVE.L�D7,D4 ŠSUB.L‚D6,D4 ŠADD.L‚#1,D4 ŠBSR„CHKASN*…D5.W=NEG�IF�CONTIGUOUS/VOLUME*‰=POS�IF�NON-CONTIGUOUSŠIFGTƒFMSLEVEL-1 ŠBMI.S‚FBLK�CONTIGUOUS�OR�VOLUMEI*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 10/08/84 >>>8*CAN'T HAVE SECONDARY MEMORY MAP FOR NON-CONTIGUOUS FILE"*‰BTSTW‚#IOPSMPB,FATIOS+IOSOPT(A4)*‰BNE„FMRER4�INVALID�FUNCTIONI*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 10/08/84 >>><*ALLOCATE DATA BUFFER FOR NON-CONTIGUOUS FILE (IF IT DOESN'T*…EXIST)�AND�ATTACH�TO�ITŠTST.L‚FATBSN(A4)(ŠBNE.S‚FMRW16CŒSEGMENT�ALREADY�ALLOCATED4*IF�DOING�BLOCK�I/O,�NEED�FAB�ONLY.‚RECORD�I/O�NEEDS*…FAB�AND�DATA�BLOCK'ŠCLR.B‚D0‘SET�UP�FOR�FAB/DB,�NOT�GLOBAL-ŠBTSTW‚#IOPRECB,FATIOS+IOSOPT(A4)�RECORD�I/O?ŠBEQ.S‚FMRW16�YES'ŠMOVE.B�#$80,D0ŒBLOCK�I/O-NEED�FAB�ONLY"FMRW16„BSR„GETIOB�ALLOCATE�SEGMENT%ŠBNE„IOSERR�INSUFFICIENT�SYSTEM�SPACEŠBRA.S‚FMRW16EŠIFGTƒFMSLEVEL-1$FMRW16CƒBSR„ATTIOB�ATTACH�TO�SEGMENTŠENDC+*IF OVERWRITE WAS REQUESTED AND THIS IS NOT8*…READ�OR�POSITION,�DE-ALLOCAATE�ALL�EXISTING�FILE�SPACE=*OVERWRITE BIT CAN ONLY BE SPECIFIED FOR NON-CONTIGUOUS FILES FMRW16EƒEQU„* ŠCMP.W‚#IOREAD,FATIOS+IOSFCT(A4)ŠBEQ.S‚FMRW17�READ ŠCMP.W‚#IOPOST,FATIOS+IOSFCT(A4) ŠBEQ.S‚FMRW17?ŠBCLRW‚#FOPOVRTB,FATASN(A4)�WAS�OVERWRITE�SET?�(AND�CLEAR�FLAG)ŠBEQ.S‚FMRW17�NOB*YES-TO HANDEL CASE OF MULTIPLE WRITE ACCESSES, ONLY 1ST OVERWRITE*…ENCOUNTERED�IS�OPERATED�ON1ŠBSETW‚#FCFLOB,FCBFLG(A2)�OVERWRITE�ALREADY�DONE?!ŠBNE.S‚FMRW17�YES-IGNORE�THIS�ONE"ŠBSR„FSDEAL�DE-ALLOCATE�FILE�SPACE ŠBNE„IOSERR FMRW17„EQU„*3ŠBTSTW‚#IOPRECB,FATIOS+IOSOPT(A4)�RECORD�RETRIEVAL? ŠBEQ„FREC�YESŠENDCƒFMSLEVEL-1ŠPAGE**BLOCK I/O PROCESSING!*…D4=LENGTH�OF�USER�BUFFER�PASSED*…D5.W=TYPE�OF�ASSIGN *…D6=IOSSAD *…D7=IOSEAD*…A6=VDT�ADDR.*…A4=FAT�ADDR.*…A2=FCB�ADDR.**MAKE SURE FUNCTION IS VALID FOR BLOCK I/O**…UPDATE,�DELETE,�AND�POSITION�ARE�INVALID**INDENTED LIST * FBLK DOES BLOCK I/O PROCESSING*FBLK* BLOCK I/O VALID?*‚NO,�INVALID�FUNCTION%* VALID-DATA BUFFER ADDR.-AND LENGTH?*‚NO,INVALID�DATA�BUFFER�ADDR.%* DETERMINE CURRENT LOG.SECT. $CALREC*‚ERROR-IF�CLS-NOT�IN-RANGE* VOLUME ASSN.?"*‚YES,ERROR�IF-NOT�RANDOM�REC.REQ.)*ƒERROR-IF�NOT-VOLUME�OWNER-OR�SUPERVISOR* NON-CONT. FILE?*‚YES,GO�TO�$PROS70* DETERMINE PSN,NO. OF BYTES&* SET-UP-TO TRANSFER THROUGH USER-BUF."*‚SET-UP-FOR�SEC.MEM.�IF�REQUESTED*ƒTRANSFER�DATA�$DOIO* VOLUME WRITE?&*‚YES,IND.�NO-TABLES�IN-MEMORY�$ZERPTR*ƒSECTOR-0�WRITTEN?*„YES,READ�VOLUME-ID�$GETVID* CALCULATE BYTES TRANSFERRED*‚GO-TO�I/O�COMPLETION�$FMRW31*INDENTED LIST END* FBLK†EQU„*ŠMOVE.W�FATIOS+IOSFCT(A4),D0ŠCMP.W‚#IOPOST,D0 ŠBEQ.S‚FMER4ŠCMP.W‚#IODELR,D0ŠBEQ.S‚FMER4ŽINVALID�FUNCTIONŠCMP.W‚#IOUPDR,D0 ŠBEQ.S‚FMER4ŠIFGTƒFMSLEVEL-1 ŠTST.W‚D5ŠBMI.S‚FMRW18�CONTIGUOUS/VOLUME8*CAN'T SWITCH BETWEEN RECORD AND BLOCK I/O UNLESS SHARED!*…BUFFER�REQUESTED�AT�ASSIGN�TIME'ŠBTSTW‚#FOPABFB,FATASN(A4)�SHARED�REQ.?!ŠBNE.S‚FMRW18AŒYES-OKAY�TO�SWITCH/*SEE IF A RECORD I/O HAS ALREADY BEEN PROCESSEDŠBTSTW‚#FAFLRB,FATFLG(A4)!ŠBNE.S‚FMER4ŽYES-INVALID�FUNCTION8*CAN'T DO WRITE BLOCK I/O FOR NON-CONTIGUOUS FILE UNLESS*…SHARED�BUFFER ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4) ŠBNE.S‚FMRW18!FMER4…BRA„IOSER4�INVALID�FUNCTION-*SAVE DATA BUFFER START AND END ADDRS. IN FAT*DON'T DO IF SHARED BUFFERG*IF CONTIGUOUS FILE OR VOLUME ASSIGNMENT, BUFFER MUST BE MULTIPLE OF 25 FMRW18„EQU„* ŠTST.W‚D5ŠBPL.S‚FMRW18BŒNON-CONTIGUOUSŠENDCƒFMSLEVEL-1ŠAND.B‚#$FF,D45ŠBNE„IOSER2�NOT�256�BYTE�MULTIPLE-INVALID�DATA�BUFFERŠMOVE.L�D7,FATSBL(A4)ŠIFGTƒFMSLEVEL-1ŠBRA.S‚FMRW18H5*SHARED BUFFER-MAKE SURE USER'S PASSED ADDRS ARE GOOD2*…STARTING�ADDR.�MUST�BE�SAME�AS�THAT�SPECIFIED�AT*…AT�ASSIGNM ENT�TIMEFMRW18AƒMOVE.L�D6,D0ŠCMP.L‚FATSLA(A4),D0&ŠBNE.S‚FMER2ŽINVALID�DATA�BUFFER�ADDR.ŠMOVE.L�FATSBE(A4),D0ŠSUB.L‚FATSBS(A4),D0$ŠADD.L‚#1,D0ŽD0=LENGTH�OF�FMS�BUFFER ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)ŠBEQ.S‚FMRW18A2‹WRITE�REQUEST9ŠCMP.L‚D0,D4ŒBUFFER�MUST�BE�FULL�LENGTH�FOR�READ/POSITION!ŠBNE.S‚FMER2ŽINVALID�DATA�BBUFFERŠBRA.S‚FMRW190;*FOR WRITE, USER'S BUFFER CANNOT BE BIGGER THATN FMS BUFFERFMRW18A2‚CMP.L‚D0,D4ŠBHI.S‚FMER2ŽTOO�BIGŠMOVE.W�FCBDIR+DIRLRL(A2),D1ŠBEQ.S‚FMRW18CŒVRL0*FRL-MAKE SURE USER BUFFER LENGTH IS MULTIPLE OF*…RECORD�LENGTH#ŠMOVE.L�D4,D2ŽD2=USER�RECORD�LENGTH ŠDIVUƒD1,D2ŠSWAPƒD2 ŠTST.W‚D2 ŠBNE.S‚FMER2ŽINVALID�DATA�BUFFERŠBRA.S‚FMRW18F**VRL-CALCULATE NO. OF BYTES OF ACTUAL DATAFMRW18CƒCLR.L‚D1 ŠCLR.L‚D2ŠMOVE.L�FATSBS(A4),A1+FMRW18DƒMOVE.W�(A1)+,D2‹GET�REC.�BYTE�COUNTŠBEQ.S‚FMRW18EŒALL�DONE ŠBTSTW‚#0,D2ŠBEQ.S‚FMRW18D2 ŠADD.L‚#1,D2FMRW18D2‚EQU„* ŠADD.L‚D2,D1ŠADD.L‚#BCTFLD,D1*ŠADD.L‚D2,A1ŽPOINT�TO�START�OF�NEXT�RECORD*MAKE SURE HAVEN(T GONE TOO FAR ŠCMP.L‚D4,D1ŠBEQ.S‚FMRW18EŒAT�END�OF�BUFFER/ŠBHI.S‚FMER2ŽGONE�BEYON�END-INVALID�DATA�BUFFERŠBRA.S‚FMRW18D-FMRW18EƒMOVE.L�D1,D4ŽSAVE�NEW�LENGTH�OF�BLOCK*ERROR IF ONLY 0'S IN BUFFER ŠBEQ.S‚FMER2 FMRW18FƒEQU„*!*CALCULATE LOGICAL END OF BUFFEERŠADD.L‚FATSBS(A4),D4 ŠSUB.L‚#1,D4ŠMOVE.L�D4,FATSBL(A4)ŠBRA.S‚FMRW190/*NON-CONTIGUOUS BLOCK I/O FOR NOT SHARED BUFFER5*…READ�MUST�HAVE�BUFFER�AT�LEAST�AS�BIG�AS�DATA�BLOCK**…SIZE.‚WRITE�BLOCK�REQUIRES�SHARED�BUFFERFMRW18BƒCLR.W‚D1ŠMOVE.B�FCBDIR+DIRDAT(A2),D1.ŠMULUƒ#SECSZE,D1‰D1=NO.�OF�BYTES�IN�DATA�BLOCK ŠCMP.L‚D1,D4ŠBCC.S‚FMRW18H%FMER2…BRA„IOSER2�INVALID�DATA�BBUFFERŠENDCƒFMSLEVEL-1"FMRW18HƒMOVE.L�D6,FATSBS(A4)†STARTŠMOVE.L�D7,FATSBE(A4)†ENDC*SET UP TO DETERMINE CLS BASED ON NEXT, PRIOR, CURRENT, RANDOM REQ. FMRW190ƒMOVE.L�FATCLS(A4),D1†CLS*ŠMOVE.L�FATBCT(A4),D2†VALUE�TO�ADD�IF�NEXTŠIFGTƒFMSLEVEL-12*IF NON-CONTIGUOUS FILE, NO. OF SECTORS TO ADD FOR1*…NEXT�IS�DETERMINED�BY�CURRENT�DATA�BLOCK'S�SIZE ŠTST.W‚D5 ŠBMI.S‚FMRW19CŒCONTIGUOUS/VOLUME-ŠMOVE.L�FATCFP(A4),A1†GET�CURRENT�FAB�POINTER"ŠCMP.L‚#0,A1ŽIS�THERE�CURRENT�FAB?"ŠBEQ.S‚FMRW19CŒNO-USE�FATBCT�VALUE ŠCLR.L‚D29ŠMOVE.B�FABSGS(A1),D2†GET�NO.�OF�SECTORS�IN�CURRENT�BLOCKŠENDCƒFMSLEVEL-1FMRW19CƒBSR„CALRECŠBCS„FMER4ŽINVALID�FUNCTIONŠIFGTƒFMSLEVEL-1*4*IF BLOCK WRITE FOR NON-CONTIGUOUS, MAKE SURE DB NOT2*…CHANGED�OR�IF�IT�IS,�BLOCK�WRITE�MUST�GO�TO�SAME*…DB ŠTST.W‚D5ŠBMI.S‚FMRW22�CONTIGUOUS/VOLUME ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)ŠBNE.S‚FMRW22�NOT�WRITEŠBTSTW‚#FAFLDB,FATFLG(A4)ŠBEQ.S‚FMRW22�DB�NOT�CHANGEDŠCMP.L‚FATSLS(A4),D1,ŠBNE„FMER4ŽBAD�DB�REQUESTED-INVALID�FUNCTIONŠENDC FMRW22„EQU„***CHECK TO MAKE SURE CLS IS IN VALID RANGE.*…IF�READ�REQUEST8*…CLS�MUST�BE�.LE.�EOF.‚IF�WRITE,�CLS�MUST�BE�.LE.�EOF+1&*…(UNLESS�CONTIGUOUS�WRITE�AND�EOF=FE)?*…IF�VOLUME�READ/WRITE,�CLS�MUST�BE�.LT.�NO.�OF�SECTORS�ON�DISK*…D1=CLS�VALUEŠTST.B‚D5‘GET�ASSIGN.�TYPEŠBPL.S‚PROS01�FILE�ASSIGNMENT-*DON'T ALLOW VOLUME I/O UNLESS RANDOM REQUESTŠMOVE.W�FATIOS+IOSOPT(A4),D0ŠAND.W‚#IOPPOS,D0ŠCMP.W‚#IOPRAN,D0ŠBNE„FMER4ŽINVALID�FUNCTION9*CAN'T DO VOLUME I/O UNLESS USER OWNS VOLUME OR USER ID=0ŠMOVE.L�FATLUT(A4),A0"ŠMOVE.W�LUTUNM(A0),D0†GET�USER�NO.ŠBEQ.S‚FMRW22BŠCMP.W‚VDTVID+VIDUSN(A6),D0ŠBNE„IOSER1�PROTECT�CODE�ERROR FMRW22BƒEQU„*ŠMOVE.L�VDTDCB(A6),A3'ŠMOVE.L�DCBSEC(A3),D0†VOLUME�ASSIGNMENT&ŠSUB.L‚#1,D0ŽGET�MAX.�NO.�OF�SECTORS-1 ŠCMP.L‚D1,D0*‰BCS„IOSER6�Removed�3/15/840ŠBCS„IOSER8�Invalid�Random�Record�number�3/15/84 ŠBRA.S‚PROS08*ŠIFEQƒFMSLEVEL-1FMER4…BRA„IOSER4ŠENDC* PROS01„EQU„*ŠIFEQƒFMSLEVEL-1*CONTIGUOUS-USE PHYSICAL EOFŠMOVE.L�FCBDIR+DIRFE(A2),D0ŠENDCŠIFGTƒFMSLEVEL-1"ŠCMP.B‚#DATCON,D5‰CONTIGUOUS�FILE?ŠBNE.S‚PROS01CŒNO*YES-USE PHYSICAL EOFŠMOVE.L�FCBDIR+DIRFE(A2),D0 ŠBRA.S‚PROS05 PROS01CƒEQU„*/*IF WRITE REQUEST, POINT ONE BEYOND END OF FILE,ŠMOVE.L�FCBDIR+DIREOF(A2),D0�GET�LOGICAL�EOF+ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)�WRI TE�REQ?ŠBNE.S‚PROS05�NO#*YES-MAKE EOF+1 UPPER BOUND FOR CLS ŠADD.L‚#1,D0ŠENDCƒFMSLEVEL-1 PROS05„CMP.L‚D1,D0ŽCLS�IN�RANGE?ŠBCS„IOSER7�NO-END�OF�FILE*DON'T ALLOW READ IF EOF=-1 ŠCMP.L‚#-1,D0 ŠBEQ„IOSER7)*CALCULATE MAXIMUM NO. OF SECTORS OF DATA*…=(SBE-SBS+1)/SECSZE�FOR�READ *…=((SBL-SBS+1)/SECSZE�FOR�WRITE#PROS08„MOVE.L�FATSBE(A4),D4†GET�SBE/ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)�WRITE�REQUEST?ŠBNE.S‚PROS10�NO!ŠMOVE.L�FATSBL(A4),D4†YES-GET�SBLPROS10„SUB.L‚FATSBS(A4),D4"ŠADD.L‚#1,D4ŽD4=TOTAL�NO.�OF�BYTES3ŠDIVUƒ#SECSZE,D4‰D4.W=NO.�OF�SECTORS�IN�DATA�BUFFER2ŠBCLRW‚#FAFLLB,FATFLG(A4)�CLEAR�DELETE�RECORD�FLAG-*NOW MUST DETERMINE PSN CORRESPOINGING TO CLS ŠTST.B‚D5ŠBMI.S‚PROS15�VOLUME�READ/WRITEŠIFGTƒFMSLEVEL-1ŠCMP.B‚#DATCON,D5ŠBNE„PROS70�NOT�CONTIGUOUSŠENDC(*FOR CONTIGUOUS FILE, PSN=FILE START+CLSŠMOVE.L�FCBDIR+DIRFS(A2),A3ŠADD.L‚D1,A3ŽA3=PSN%*CALCULATE NO. OF SECTORS TO TRANSFER+*ERROR IF WRITE REQUEST WOULD GO BEYOND END1*CALCULATE NO. OF SECTORS TO END OF FILE=FE-CLS+1ŠMOVE.L�FCBDIR+DIRFE(A2),D6PROS12„SUB.L‚D1,D6 ŠADD.L‚#1,D6/ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)�WRITE�REQUEST?ŠBNE.S‚PROS44�NO@*YES-MAKE SURE NO. OF SECTORS REQUESTED FOR TRANSFER .LE. NO. OF*…SECTORS�REMAINING�IN�FILE ŠCMP.L‚D4,D6ŠBCC.S‚PROS44�OKAY*TOO MANY SECTORS TO WRITE(*GIVE EOF ERROR UNLESS VOLUME ASSIGNMENT ŠTST.B‚D5ŠBPL„IOSER7�NOT�VOLUMEŠBRA„IOSER6�END�OF�VOLUME*VOLUME READ/WRITE-PSN=CLS&*…D0=LARGEST�SECTOR�REFERENCE�FOR�DISKPROS15„MOVE.L�D1,A3+ŠMOVE.L�D0,D6ŽD6=PSN�OF�LAST�SECTOR�ON�DISK ŠBRA.S‚PROS12ŠPAGE*…D1=CLS�VALUE"*…D4=NO.�OF�SECTORS�LEFT�IN�BUFFER(*…D6=NO.�OF�SECTORS�LEFT�IN�THIS�SEGMENTPROS44„MOVE.L�D4,D3(ŠMOVE.L�D1,FATCLS(A4)†SAVE�NEW�CLS�VALUE ŠCMP.L‚D6,D3 ŠBCS.S‚PROS45 ŠMOVE.L�D6,D3*D3=NO. OF SECTORS TO TRANSFER *…A3=PSN�OF�SECTOR�TO�START�WITH*SET UP I/O CONTROL BLOCK PROS45„EQU„***SET�UP�READ�AND�OPTIONS�FOR‚IMAGE,�RANDOM&ŠSETFO‚IOREAD,IOPIMG+IOPRAN,VDTIOS(A6),ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)�WRITE�REQ.?ŠBNE.S‚PROS50�NO+ŠMOVE.W�#IOWRIT,VDTIOS+IOSFCT(A6)�SET�WRITE6PROS50„MOVE.L�A3,VDTIOS+IOSRRN(A6)�SET�STARTING�SECTOR3ŠMOVE.L�FATSBS(A4),VDTIOS+IOSSAD(A6)�STARTING�ADDR.$ŠMOVE.L�FATSBS(A4),VDTIOS+IOSEAD(A6)*CALCULATE ENDING ADDR. ŠMOVE.L�D3,D0ŠMULUƒ#SECSZE,D0‰NO.�OF�BYTESŠSUB.L‚#1,D0Ž-1(ŠADD.L‚D0,VDTIOS+IOSEAD(A6)�ENDING�ADDR.<*FOR CONTIGUOUS FILES, TRANSFER ALWAYS GOES TO USER'S BUFFER$*SET UP TO DO CALL ON BEHAVE OF USER.ŠMOVE.L�FATTSK(A4),VDTIOS+IOSTSK(A6)�USER�TASK1ŠMOVE.L�FATSES(A4),VDTIOS+IOSSES(A6)�USER�SESSION(*SET OPTION TO INDICATE TASK ID SUPPLIED!ŠBSETW‚#IOPTSKB,VDTIOS+IOSOPT(A6)I*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 10/08/84 >>>2*IF USER REQUESTS SECONDARY MEMORY MAP, SET OPTION"*‰BTSTW‚#IOPSMPB,FATIOS+IOSOPT(A4)*‰BEQ.S‚PROS55"*‰BSETW‚#IOPSMPB,VDTIOS+IOSOPT(A6) *PROS55„EQU„*I*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 10/08/84 >>>ŠBSR„DOIO�START�I/O0*SAVE�NO.�OF�SECTORS�TRANSFERRED‚(EVEN�IF�ERROR)ŠMOVE.L�D3,FATBCT(A4)ŠTST.L‚D0‘CLEAR�CC'S.ŠBNE.S‚PROS68�I/O�ERROR-CHECK�FOR�VOLUME�WRITE9*IF INPUT REQUEST, SET SBL TO INDICATE END OF ACTUAL DATA ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)ŠBEQ.S‚PROS60�WRITEŠMOVE.L�IOSEAD(A0),FATSBL(A4)6PROS65„CMP.W‚#IOFRMT,FATIOS+IOSFCT(A4)�FORMAT�REQUEST?ŠBEQ„IOSGRT�YES-DONE ŠBRA„FMRW25PROS60„TST.B‚D5‘VOLUME?ŠBPL.S‚PROS65�NO5*VOLUME WRITE SHOULD CAUSE ANY TABLES SAVED IN MEMORY*…TO�BE�READ�BACK�IN�NEXT�TIME*…FILE�I/O�DONE*…ALSO�CALLED�AFTER�FORMAT?*…(SHOULDN'T�BE�ANY�INFO.�IN�MEMORY�NOT�ALREADY�UPDATED�ON�DISK*…SINCE�WRITE�IS�EXCLUSIVE%PROS66„MOVE.L�D0,D2ŽSAVE�ERROR�STATUS ŠBSR„ZERPTR/ŠBSETW‚#FCFLWB,FCBFLG(A2)�INDICATE�VOLUME�WRITE7*IF VOLUME WRITE TO SECTOR 0, MUST READ VOLUME ID AGAIN(ŠCMP.W‚#IOFRMT,FATIOS+IOSFCT(A4)�FORMAT?ŠBEQ.S‚PROS66AŠTST.L‚FATCLS(A4)ŠBNE.S‚PROS67�NOT�SECTOR�0PROS66AƒBSR„GETVID=*DON'T CHECK ERROR AFTER GETVID SINCE COULD BE INVALID VOLUME!PROS67„MOVE.L� D2,D0ŽRESTORE�ERROR ŠBEQ.S‚PROS65PRERR…BRA„IOSERR�I/O�ERROR0*I/O ERROR OCCURRED-CHECK TO SEE IF VOLUME WRITE&PROS68„CMP.W‚#IOWRIT,FATIOS+IOSFCT(A4) ŠBNE.S‚PRERR ŠTST.B‚D5 ŠBMI.S‚PROS66ŠBRA.S‚PRERRŽNOT�VOLUME�WRITEŠPAGEŠIFGTƒFMSLEVEL-1*&*DO PROCESSING FOR NON-CONTIGUOUS FILE*…D1=NEW�CLS�VALUE***INDENTED LIST0* PROS70 DOES BLOCK I/O FOR NON-CONTIGUOUS FILES*PROS70* READ REQUEST? *‚YES,GET�FAB,DATA�BLOCK�$GETFDB*‚NO,GET�FAB�$GETFDB*ƒEND-OF�FILE?*„YES,ALLOC.�FILE-SPACE�$FSALLC(* RANDOM-REQ. NOT-AT BEGINNING OF-BLOCK?&*‚YES,RETURN�LOG.SEC.�OF-START�IF-READ*ƒSET-UP�FOR�INVALID�RRN*‚NO,WRITE�REQUEST?*ƒYES,WRITE�DATA-TO�DISK*„$DBCHG,�$PUTDAT* CALCULATE BYTES TRANSFERRED*‚GO-TO�I/O�COMPLETION�$FMRW31*INDENTED LIST END* PROS70„EQU„*$ŠMOVE.L�D1,FATCLS(A4)†SAVE�CLS�VALUEŠMOVE.L�D1,D0ŽD0=CLS�VALUEŠMOVE.L�#LSNFDB,D1/ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)�WRITE�REQUEST?ŠBEQ.S‚PROS72�YES.ŠBSETW‚#RDBFLGB,D1ˆNO-SETUP�TO�READ�DATA�BLOCKPROS72„BSR„GETFDB ŠBEQ.S‚PROS75$ŠCMP.B‚#ISTAEOF,D0ˆCLS�OUT�OF�RANGE?ŠBNE.S‚PRERRŽMUST�BE�FATAL#*SHOULD ONLY GET EOF IF DOING WRITE ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)ŠBNE.S‚PRERRŽREAD�BEYOND�EOF3*OUT OF RANGE MUST HAVE BEEN CAUSED BY WRITE BEYOND.*…END�OF�FILE-ALLOCATE�DISK�SPACE�AND�CONTINUE ŠBSR„FSALLC ŠBNE.S‚PRERR1*SET CURRENT LOG. RECORD=STARTING RECORD OF BLOCK PROS75„EQU„*ŠMOVE.L�FATSLR(A4),FATCLR(A4)ŠMOVE.L�FATSLS(A4),D1,*IF RANDOM RECORD REQUEST, MAKE SURE CLS=SLSŠMOVE.W�FATIOS+IOSOPT(A4),D0ŠAND.W‚#IOPPOS,D0ŠCMP.W‚#IOPRAN,D0ŠBEQ.S‚PROS76�RANDOM*NOT RANDOM-SET CLS=SLSŠMOVE.L�D1,FATCLS(A4) ŠBRA.S‚PROS80PROS76„CMP.L‚FATCLS(A4),D1ŠBEQ.S‚PROS80�OKAY*ERROR-BUT SET CLS=SLS ANYWAYŠMOVE.L�D1,FATCLS(A4)=*RETURN STARTING LOGICAL SECTOR OF DATA BLOCK TO USER IF READŠCMP.W‚#IOWRIT,FATFCB(A4)1ŠBEQ„IOSER8�WRITE-MAKE�INVALID�RANDOM�REC.�RETURN ŠBSR„SMOVE4ŠLEA„FATCLS(A4),A1ŠMOVE.L�A1,MVSADD(A0)ŠMOVE.L�FATUPB(A4),MVDADD(A0)ŠADD.L‚#IOSRRN,MVDADD(A0)ŠMOVE.L�#4,MVLENG(A0)<*MOVE LOGICAL SECTOR NO. CORRESPONDING TO 1ST SECTOR IN DATA*†BLOCK�TO�USER'S�RRN ŠBSR„MOVE2U ŠBNE.S‚FMRER3:ŠBSETW‚#FAFLBB,FATFLG(A4)�INDICATE�BLOCK�TRANSFER�COMPLETEŠMOVE.L�FATSBL(A4),D0ŠSUB.L‚FATSBS(A4),D0(ŠADD.L‚#1,D0ŽD0=NO.�OF�BYTES�TRANSFERRED;ŠMOVE.L�#NL+ISTARR,D2†D2=ERROR�CODE�FOR�INVALID�RANDOM�REC. ŠBRA.S‚FMRW31&PROS80„CMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)&ŠBNE.S‚FMRW25�DONE�IF�READ�OR�POSITION.*FINISH WRITE REQUEST-MUST UPDATE INFO. IN FABŠBCLRW‚#FAFLCB,FATFLG(A4)ŠBSETW‚#FAFLUB,FATFLG(A4)ŠBSR„DBCHGŽSET�DB�CHANGED$ŠMOVE.L�#1,D0ŽUPDATE�LAST�KEY�IN�FAB ŠBSR„PUTDAT�UPDATE�BLOCK�ON�DISK ŠBEQ.S‚FMRW25ŠENDCFMERR…BRA„IOSERR�I/O�ERROR;FMRW25„BSETW‚#FAFLBB,FATFLG(A4)�INDICATE�BLOCK�I/O�TRANSFER*-*REQUEST WAS COMPLLTED-CALCULATE ACUAL NO. OF *…BYTES�TRANSFERRED�(=SBL-SBS+1)ŠMOVE.L�FATSBL(A4),D0ŠSUB.L‚FATSBS(A4),D0(ŠADD.L‚#1,D0ŽD0=NO.�OF�BYTES�TRANSFERRED%ŠCLR.B‚D2‘INDICATE�NO�BUFFER�OVERFLOW*A*SET UP TO MOVE LENGTH OF DATA TRANSFER TO USER'S PARAMETER BLOCK?*…D0.L=NO.�OF�BYTES�TRANSFERRED�OR�OFFSET�TO�RECORD�IF�POSITIONA*…D2.B=0�OR�ERROR�CODE�FOR�BUFFER�OVERFLOW�OR�INVALID�RANDOM�REC.*…D5.W=TYPE�OF�ASSIGNMENT**INDENTED LIST* FMRW31 DOES I/O COMPLETION*FMRW31* POSITION REQUEST?&*‚YES,RETURN�REC.OFFSET�IN-LEN�$MOVELL!*ƒRETURN�CLR-IN�RRN-FIELD�.MOVELL#*‚NO,RETURN�TRANSFER�LENGTH�.MOVELL* BUFFER.OVF OR-INVALID RRN?*‚YES,MAKE�ERROR�RETURN*‚NO,CLEAR�I/O�PENDING�$CLRIOP*ƒMAKE�GOOD�RETURN�$FMSRTN*INDENTED LIST END* FMRW31„EQU„*ŠBSR„SMOVE4�SET�UP�L-L�MOVEŠMOVE.L�D0,FATIOS+IOSLEN(A4)ŠLEA„FATIOS+IOSLEN(A4),A1ŠMOVE.L�A1,MVSADD(A0)ŠMOVE.L�FATUPB(A4),MVDADD(A0)ŠADD.L‚#IOSLEN,MVDADD(A0)(ŠMOVE.L�#4,MVLENG(A0)†LENGTH�OF�TRANSFER ŠBSR„MOVE2U%FMRER3„BNE„IOSER3�INVALID�PARM.�BLOCK@*IF POSITION REQUEST, RETURN CURRENT LOGICAL RECORD IN RRN FIELD ŠCMP.W‚#IOPOST,FATIOS+IOSFCT(A4)ŠBNE.S‚FMRW34�NOT�POSITION@ŠMOVE.L�FATCLR(A4),FATIOS+IOSLEN(A4)�SAVE�CURR ENT�LOGICAL�RECORDŠMOVE.L�FATUPB(A4),MVDADD(A0)ŠADD.L‚#IOSRRN,MVDADD(A0) ŠBSR„MOVE2U ŠBNE.S‚FMRER3?*IF NOT BUFFER OVERFLOW OR INVALID RANDOM RECORD NO., MAKE GOOD*…RETURNFMRW34„MOVE.B�D2,D05ŠBNE.S‚FMERRŽBUFFER�OVERFLOW�OR�INVALID�RANDOM�RECORDŠBRA„IOSGRT�MAKE�GOOD�RETURNŠIFGTƒFMSLEVEL-1ŠPAGE**PROCESSING FOR RECORD I/O*…D4=USER�BUFFER�LENGTH*…D5.W=TYPE�OF�ASSIGNMENT *…D6=IOSSAD *…D7=IOSEAD*…A6=VDT�ADDR.*…A4=FAT�ADDR.*…A2=FCB�ADDR.**INDENTED LIST!* FREC DOES RECORD I/O PROCESSING*FREC* RECORD I/O VALID?*‚NO,�INVALID�FUNCTION* VALID USER BUFFER?*‚NO,INVALID�DATA�BUFFER* SPOOLER FILE?*‚YES-ADD�2-TO�RECORD�LENGTH* SPACES COMPRESSED?*‚YES,COUNT�COMPRESSED�DATA*ƒ$MVEREC,�$CMPSPC* RANDOM RECORD REQUEST?*‚YES,GO�TO�$FREC150* DETERMINE CLR $CALREC*‚ERROR-IF�OUT-OF�RANGE* READ-FAB, DATA-BLOCK $GETFDB* END-OF FILE-ON WRITE?*‚YES,ALLOC.�FILE-SPACE�$FSALLC*ƒPOSITION�TO-BEG.�OF-DB*‚NO,POS.�TO-CORRECT�RECORD* POSITION REQUEST? *‚YES,SETUP�TO-RETURN�REC.OFFSET*ƒDO-I/O�COMPLETION�$FMRW31&*‚NO,GO�FINISH�READ,WRITE,�UPDATE,DEL.*INDENTED LIST END* FREC†EQU„***CAN'T SWITHC BETWEEN RECORD AND BLOCK I/O/*…UNLESS�SHARED�BUFFER�REQUESTED�AT�ASSIGN�TIME&ŠBTSTW‚#FOPABFB,FATASN(A4)�SHARED�REQ?ŠBEQ.S‚FREC08�NOC*IF POSITION OR DELETE REQUEST, DON'T CHECK BUFFER ADDRESSES UNLESS*…RANDOM�KEY�POSITION ŠCMP.W‚#IODELR,FATIOS+IOSFCT(A4) ŠBEQ.S‚FREC01 ŠCMP.W‚#IOPOST,FATIOS+IOSFCT(A4)ŠBNE.S‚FREC04�NOT�POSITION3FREC01„BTSTW‚#IOPLRNB,FATIOS+IOSOPT(A4)�RANDOM�KEY?"ŠBEQ.S‚FREC10�NO-SKIP�BUFFER�CHECK FREC04„EQU„*8*FOR SHARED BUFFER, MAKE SURE USER'S RECORD ADDR. IS NOT%*…IN�CONFLICT�WITH�SHARED�BUFFER�ADDR3ŠMOVE.L�FATSLA(A4),D0†USER'S�SEGMENT�STARTING�ADDR. ŠCLR.W‚D1ŠMOVE.B�FCBDIR+DIRDAT(A2),D1ŠMULUƒ#SECSZE,D1 ŠSUB.L‚#1,D10ŠADD.L‚D0,D1ŽD1=USER�ENDING�ADDR.�OF�SHARED�SEG. ŠCMP.L‚D6,D0 ŠBHI.S‚FREC06 ŠCMP.L‚D6,D1ŠBCS.S‚FREC10�OKAYFRER2…BRA„IOSER2FREC06„CMP.L‚D7,D0ŠBLS.S‚FRER2ŽERROR ŠBRA.S‚FREC10 FREC08„EQU„*.*SEE IF A BLOCK I/O HAS ALREADY BEEN PROCESSEDŠBTSTW‚#FAFLBB,FATFLG(A4) ŠBNE„IOSER4�YES-INVALID�FUNCTION(*DELETE REQUEST NOT VALID UNLESS INDEXEC0*IF RANDOM RECORD I/O, FILE TYPE MUST BE INDEXED'FREC10„BTSTW‚#IOPLRNB,FATIOS+IOSOPT(A4)ŠBEQ.S‚FREC12�NOT�RANDOMBŠTST.B‚FCBDIR+DIRKEY(A2)‚NO�RANDOM�KEY�ACCESS�TO�FILES�W/NULL�KEYS!ŠBNE.S‚FREC17�OK�UNLESS�SEQ.�FILEŠBRA.S‚FREC18�ERROR.FREC12„CMP.W‚#IODELR,FATIOS+IOSFCT(A4)�DELETE?ŠBNE.S‚FREC20�NO-OKAYFREC17„CMP.B‚#DATSEQ,D5/FREC18„BEQ„IOSER4�SEQUENTIAL�-�INVALID�FUNCTION/*FOR WRITE/UPDATE RECORD REQUEST, RECORD LENGTH)*…PASSED�CANNOT�BE�BIGGER�THAN�DATA�BLOCK,*…SIZE�IF�VRL�OR�MUST�=�RECORD�LENGTH�IF�FRL5* FOR INDEXEC FILES, RECORD LENGTH MUST BE BIG ENOUGH*…TO�ACCOMODATE�KEY�SIZE FREC20„EQU„*/ŠCLR.L‚D1‘0�D1�IN�PREPARATION�FOR�RECORD�LENGTH+*FOR RANDOM RECORD I/O, USER BUFFER MUST BE!*…BIG�ENOUGH�TO�CONTAIN�KEY�FIELD+ŠMOVE.W�FATIOS+IOSFCT(A4),D0�D0=IO�FUNCTIONŠIFEQƒFMSLEVEL-3!ŠBTSTW‚#IOPLRNB,FATIOS+IOSOPT(A4)"ŠBNE.S‚FREC20AŒKEYED‚RECORD‚ACCESSŠENDCŠCMP.W‚#IOWRIT,D0ŠBEQ.S‚FREC20BŠCMP.W‚#IOUPDR,D0 ŠBNE.S‚FREC24 FREC20BƒEQU„*ŠIFEQƒFMSLEVEL-3ŠCMP.B‚#DATSEQ,D5ŠBNE.S‚FREC20AŠENDC)*UPDATE/WRITE REQUEST FOR SEQUENTIAL FILE(*…ADD�2�TO�RECORD�LENGTH�IF�SPOOLER�FILE ŠCMP.B‚#SPOOLF,FCBDIR+DIRFIL(A2)ŠBNE.S‚FREC21�NOT�SPOOLER ŠADD.L‚#2,D4ŠIFEQƒFMSLEVEL-3ŠBRA.S‚FREC21�SEQUENTIAL�FILE;*INDEXED FILE-MAKE SURE RECORD LENGTH ACCOMODATES KEY FIELD2FREC20AƒMOVE.B�FCBDIR+DIRKEY(A2),D1�GET�KEY�LENGTH ŠCMP.L‚D1,D4<ŠBCS.S‚FRER2‰RECORD�TOO�SMALL-GIVE�INVALID�DATA�BUFFER�ERRORŠCMP.W‚#IOWRIT,D0 ŠBEQ.S‚FREC21ŠCMP.W‚#IOUPDR,D0!ŠBNE.S‚FREC24�NOT�WRITE�OR�UPDATEŠENDC$*MAKE SURE RECORD BUFFER NOT TOO BIG"FREC21„MOVE.W�FCBDIR+DIRLRL(A2),D1 ŠBEQ.S‚FREC221ŠCMP.L‚D1,D4ŽFRL�BUFFER�SIZE�MUST�=�RECORD�LENGTH&ŠBNE.S‚FRER2ŽINVALID�DATA�BUFFER�ADDR. ŠBRA.S‚FREC24 FREC22„EQU„*/*FOR VRL, RECORD BUFFER LENGTH CANNOT BE BIGGER+*…THAN�DB�SIZE-2�(TO�ACCOMOD ATE�BYTE�COUNT)ŠMOVE.B�FCBDIR+DIRDAT(A2),D1ŠMULUƒ#SECSZE,D1ŠSUB.L‚#BCTFLD,D1 ŠCMP.L‚D1,D4:ŠBHI„FRER2‰RECORD�BUFFER�TOO�BIG-INVALID�DATA�BUFFER�ADDR.*:*IF WRITE OR UPDATE REQUEST FOR VRL ASCII, FORMATTED, MOVE4*…RECORD�TO�TEMPORARY�BUFFER�SO�ACTUAL�RECORD�LENGTH*…CAN�BE�CALCULATED&FREC24„MOVE.L�D4,D7ŽSAVE�RECORD�LENGTH ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)ŠBEQ.S‚FREC26AŒWRITE�REQUEST ŠCMP.W‚#IOUPDR,FATIOS+IOSFCT(A4)"ŠBNE.S‚FREC26MŒNOT�WRITE�OR�UPDATE$FREC26AƒTST.W‚FCBDIR+DIRLRL(A2)‚VRL?ŠBNE.S‚FREC26MŒNO*FORCE IMAGE IF SPOOLER FILE ŠCMP.B‚#SPOOLF,FCBDIR+DIRFIL(A2)ŠBEQ.S‚FREC26MŒSPOOLER-ŠBTSTW‚#IOPFORB,FATIOS+IOSOPT(A4)�FORMAT�REQ?ŠBNE.S‚FREC26MŒNO(ŠBTSTW‚#IOPASCB,FATIOS+IOSOPT(A4)�ASCII? ŠBNE.S‚FREC26MŒNO-DON'T�COMPRESS+*ASCII FORMAT-MOVE DATA TO TEMPORARY BUFFER+*…SO�ACTUAL�RECORD�LENGTH�CAN�BE�DETERMINED/*RECORD MUST BE ABLE TO FIT IN TEMPORARY BUFFERŠCMP.L‚#SECSZE,D44ŠBHI„IOSER2�RECORD�TOO�BIG-INVALID�DATA�BUFFER�ADDR.ŠMOVE.L�VDTTMA(A6),A1%ŠBSR„MVEREC�MOVE�DATA�TO�TEMP.�BUFFERŠBNE„FREC71�L-L�MOVE�ERROR2ŠBCLRW‚#VDFLTB,VDTFLG(A6)�INDICATE�IN�TEMP.�BUFFER&*RECORD HAS BEEN MOVED TO TEMP. BUFFER$*…CALCULATE�COMPRESSED�RECORE�LENGTHŠMOVE.L�VDTTMA(A6),A0*ŠCLR.B‚D0‘INDICATE�DATA�SHOULDN'T�BE�MOVED ŠBSR„CMPSPC*…D7=COMPRESSED�RECORD�LENGTH ŠEXG„D4,D7 *NOW D4=COMPRESSED RECORD LENGTH*…D7=USER�REOCRD�LENGTH FREC26MƒEQU„*ŠIFEQƒFMSLEVEL-3!ŠBTSTW‚#IOPLRNB,FATIOS+IOSOPT(A4)"ŠBNE„FREC150ŒRANDOM�RECORD�REQUESTŠENDC*NOW DETERMINE CLR VALUEŠMOVE.L�FATCLR(A4),D1†D1=CLRŠMOVE.W�FATIOS+IOSOPT(A4),D6ŠAND.W‚#IOPPOS,D6,*IF REQUEST IS WRITE PRIOR, DON'T CHANGE CLR ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)ŠBNE.S‚FREC27�NOT�WRITEŠCLR.B‚D3‘D3=0�IF�WRITE�AT�END;*IF SEQUENTIAL FILE, WRITE NEXT IS ALWAYS TREATED AS APPEND*„AND�CLR�IS�SET�TO�EOR�VALUEŠIFEQƒFMSLEVEL-3ŠCMP.B‚#DATSEQ,D5ŠBNE.S‚FREC26PŠENDCŠCMP.W‚#IOPNXT,D6‰NEXT�REQUEST?ŠBNE.S‚FREC26PŒNOŠMOVE.L�FCBDIR+DIREOR(A2),D1ŠADD.L‚#1,D1ŽD1=CLR+1 ŠBRA.S‚FREC28 FREC26PƒEQU„* ŠCMP.W‚#IOPPRV,D6‰PRIOR�REQUEST?ŠBNE.S‚FREC27�NO#ŠMOVE.B�#-1,D3�D3=-1�IF�WRITE�PRIOR!ŠBRA.S‚FREC28�YES-LEAVE�CLR�ALONE FREC27„EQU„*#ŠMOVE.L�#1,D2ŽD2=AMT�TO�ADD�IF�NEXT ŠBSR„CALRECŠBCS„IOSER4�INVALID�FUNCTION2*NOW DETERMINE IF CLR IS IN CORRECT RANGE FOR FILE*„D1=CLR"FREC28„MOVE.L�FCBDIR+DIREOR(A2),D06*FOR READ/UPDATE/DELETE REQUESTS, CLR MUST BE .LE. EOR/ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)�WRITE�REQUEST?ŠBEQ.S‚FREC30�YESFREC29„CMP.L‚#-1,D0�EOR=-1?ŠBEQ„IOSER7�YES-GIVE�EOF�ERROR ŠCMP.L‚D1,D0ŠBCS„IOSER7�OUT�OF�RANGE-EOF ŠBRA.S‚FREC35(*FOR WRITE REQUEST, CLR MUST EQUAL EOR+1FREC30„TST.B‚D3‘WRITE�PRIOR?ŠBMI.S‚FREC31�YESŠSUB.L‚#1,D1ŽD1=CLR-1 ŠCMP.L‚D0,D1ŠBEQ.S‚FREC35�OKAY�TO�WRITE4*OKAY TO HAVE NEXT, PRIOR WRITE REQUEST TO DUPLICATE&*…INDEXED�FILE�THAT�IS�ACTUALLY�INSERT FREC31„EQU„*ŠIFEQƒFMSLEVEL-3ŠCMP.B‚#DATISD,D5 ŠBNE.S‚FREC33ŠTST.B‚D3‘WRITE�PRIOR?ŠBMI.S‚FREC29�YES*…D6=POSITION�BITS�OF�OPTIONS$ŠCMP.W‚#IOPNXT,D6‰WRITE�NEXT�REQUESTŠBNE.S‚FREC33�MUST�BE�ERROR%ŠMOVE.B�#1,D3ŽD3=1�IF�WRITE�IN�MIDDLE ŠBRA.S‚FREC29 FREC33„EQU„*ŠENDC.*CAN'T DO WRITE TO EXISTING RECORD-GIVE RECORD*…ALREADY�EXISTS�ERRORŠCMP.L‚#-1,D0�EOF�IF�EOR=-1 ŠBEQ„IOSER7&*IF CLR-1=-1, GIVE RECORD EXISTS ERROR ŠCMP.L‚#-1,D1ŠBEQ„IOSER10ŒRECORD�EXISTSŠCMP.L‚D0,D1ŽCLR�.GT.�EOR?%ŠBCS„IOSER10ŒNO-RECORD�ALREADY�EXISTSŠBRA„IOSER7�CLR�TOO�BIG-EOF FREC35„EQU„*<*FOR WRITE AT END REQUEST, USE CLR-1 VALUE FOR RECORD TO GETŠMOVE.L�D1,FATCLR(A4)*CLEAR DELETE RECORD FLAGŠBCLRW‚#FAFLLB,FATFLG(A4)ŠMOVE.L�D1,D0ŽD0=RECORD�TO�GETŠMOVE.L�#NL+LRNFDB+RDBFLG,D1 ŠBSR„GETFDB"ŠBEQ.S‚FREC50�DB�EXISTS�FOR�RECORD#ŠCMP.B‚#ISTAEOF,D0ˆCLR�OUT�OF�RANGE ŠBNE„IOSERR�NO-MUST�BE�I/O�ERROR#*SHOULD ONLY GET EOF IF DOING WRITE ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)"ŠBNE„IOSERR�READ/UPDATE�BEYOND�EOF,*OUT OF RANGE MUST HAVE BEEN CAUSED BY WRITE *…BEYOND�EOF-ALLOCATE�DISK�SPACE ŠBRA„FREC100(*SET CURRENT LSN=STARTING LSN OF SEGMENT#FREC50„MOVE.L�FATSLS(A4),FATCLS( A4)ŠPAGE"*FIND POSITION OF REQUESTED RECORD**FOR FRL FILES, POSITION CAN BE CALCULATED*…D3.B=TYPE�OF�WRITE*…D4=USER�RECORD�LENGTH*…D5.W=TYPE�OF�FILEŠMOVE.L�FATSBS(A4),A1+ŠMOVE.L�FATCLR(A4),D1†CALCULATE�CLR-1ST�LOG ŠCLR.L‚D0ŠMOVE.W�FCBDIR+DIRLRL(A2),D0ŠBEQ.S‚FREC55�VRLŠSUB.L‚FATSLR(A4),D1(ŠMULUƒD0,D1ŽD1=OFFSET�TO�START�OF�RECORDŠADD.L‚D1,A1ŽA1=START�OF�RECORD ŠBRA.S‚FREC60*FIND START OF RECORD FOR VRL9FREC55„MOVE.L�FATSLR(A4),D2†GET�1ST�LOG.�RECORD�OF�BUFFER!FREC57„CMP.L‚D2,D1ŽFOUND�CLR�YET?ŠBEQ.S‚FREC59�YES ŠCLR.L‚D0/ŠMOVE.W�(A1)+,D0‹ADJUST�A1�FOR�BYTE�COUNT�FIELD ŠBTSTW‚#0,D0 ŠBEQ.S‚FREC58-ŠADD.L‚#1,D0ŽFORECE�BYTE�COUNT�EVEN�SINCE�NOT'FREC58„ADD.L‚D0,A1ŽPOINT�TO�NEXT�RECORD/*INTERNAL ERROR IF GO BEYOND END OF DATA BUFFERŠCMP.L‚FATSBL(A4),A1 ŠBHI„IOSER11 ŠADD.L‚#1,D2 ŠBRA.S‚FREC57'FREC59„MOVE.W�(A1),D0ŒGET�RECORD�LENGTH6ŠBEQ„IOSER11ŒINTERNAL�ERROR�IF�FOUND�REC.�HAS�LENGTH=0*…D0.L=RECORD�LENGTHC*…A1=POINTER�TO�BEGINNING�OF�RECORD�(POINTS�TO�BYTE�COUNT�IF�THERE)*…D4=�USER�RECORD�BUFFER�LENGTH*FREC60„CLR.B‚D2‘D2=0�IF�NO�BUFFER�OVERFLOW ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)ŠBEQ„FREC90�WRITE�IN�MIDDLEŠIFEQƒFMSLEVEL-3 ŠCMP.W‚#IODELR,FATIOS+IOSFCT(A4)ŠBEQ„FREC120ŒGO�PROCESS�DELETEŠENDC ŠCMP.W‚#IOPOST,FATIOS+IOSFCT(A4)ŠBEQ„FREC69�POSITION-DONE ŠCMP.W‚#IOREAD,FATIOS+IOSFCT(A4)ŠBNE„FREC70�MUST�BE�UPDATE/*THIS IS READ RQUEST-MOVE DATA TO USER'S BUFFER**INDENTED LIST* COMPLETE RECORD READ REQUEST#*ALREADY POINTING AT-RECORD TO-READ* EXPAND SPACES?*‚YES,EXPAND�IN-TEMP.�BUFFER$*„SET-FOR�BUFFER�OVERFLOW�IF-TOO-BIG* SHOULD KEY-BE RETURNED?*‚NO,POINT�PAST�KEY* WILL-REC. FIT-IN USER BUFFER? *‚NO,RETURN�NO.OF�BYTES�THAT-FIT*ƒSET-UP�FOR�BUFFER�OVERFLOW*‚YES,�RETURN�ENTIRE�RECORD* GO-TO I/O COMPLETION $FMRW31*INDENTED LIST END*ŠTST.W‚FCBDIR+DIRLRL(A2)‚VRL?ŠBNE.S‚FREC62�NO*ŠADD.L‚#BCTFLD,A1‰YES-SKIP�OVER�BYTE�COUNT(*IF READ IS FOR ASCII, FORMATTED, EXPAND4*…SPACES�BEFORE�TRANSFERRING�TO�USER'S�RECORD�BUFFER.ŠCMP.B‚#SPOOLF,FCBDIR+DIRFIL(A2)�SPOOLER�FILE? ŠBEQ.S‚FREC62�YES-FORCE�TO�IMAGE-ŠBTSTW‚#IOPFORB,FATIOS+IOSOPT(A4)�FORMAT�REQ?ŠBNE.S‚FREC62�NO(ŠBTSTW‚#IOPASCB,FATIOS+IOSOPT(A4)�ASCII?ŠBNE.S‚FREC62�NO-DON'T�EXPAND3*ASCII FORMAT-EXPAND SPACES BY MOVING DATA TO TEMP. *…BUFFER�1ST*…D0=COMPRESSES�RECORD�LENGTH!*…A1=START�OF�DATA�IN�DATA�BUFFER ŠCLR.L‚D3ŠMOVE.B�FCBDIR+DIRKEY(A2),D3(ŠSUB.L‚D0,D3ŽD3=RECORD�LENGTH-KEY�LENGTH ŠNEG.L‚D3ŠMOVE.L�VDTTMA(A6),A07ŠBSETW‚#VDFLTB,VDTFLG(A6)�INDICATE�TEMP.�BUFFER�CHANGED%FREC60AƒMOVE.B�(A1)+,D1‹GET�DATA�BYTE ŠBMI.S‚FREC60CŒSPACE�COMPRESSION7*CHAR. IS NOT SPACE-MOVE TO TEMP. BUFFER IF IT WILL FITFREC60AA‚CMP.L‚VDTTME(A6),A04ŠBHI.S‚FREC61�TEMP.�BUFFER�FULL-GIVE�BUFFER�OVERFLOWŠMOVE.B�D1,(A0)+/FREC60BƒSUB.L‚#1,D0ŽADJUST�NO.�OF�BYTES�TO�MOVEŠBNE.S‚FREC60AŠBRA.S‚FREC61CŒALL�BYTS�MOVED6*SPACE-COMPRESSION CHAR FOUND-EXPAND INTO TEMP. BUFFER FREC60CƒEQU„*&ŠCMP.L‚D3,D0ŽDON'T�DO�EXPANSION�IF�KEYŠBHI.S‚FREC60AAŠAND.W‚#$7F,D1ŠBEQ.S‚FREC60BŒ0�SPACESFREC60EƒCMP.L‚VDTTME(A6),A0ŠBHI.S‚FREC61�BUFFER�OVERFLOWŠMOVE.B�#'�',(A0)+ŠDCNTƒD1,FREC60E"ŠBRA.S‚FREC60BŒALL�SPACES�EXPANDED-*ALL DATA CANNOT BE MOVED TO TEMPORARY BUFFER*…MUST�GIVE�BUFFER�OVERFLOWFREC61„MOVE.L�#NL+ISTABO,D2'*CALCULATE NO. OF BYTES IN TEMP. BUFFERFREC61CƒMOVE.L�VDTTMA(A6),A1 ŠSUB.L‚A1,A0ŠMOVE.L�A0,D0ŽD0=LENGTH�OF�DATA FREC62„EQU„*ŠIFEQƒFMSLEVEL-33*IF INDEXED SEQUENTIAL FILE AND READ RECORD WITHOUT6*…KEY�OPTIONS�SET,�ADJUST�POINTERS�SO�KEY�NOT�RETURNEDŠCMP.B‚#DATSEQ,D5ŠBEQ.S‚FREC63�SEQQUENTIAL�FILE-ŠBTSTW‚#IOPNOKB,FATIOS+IOSOPT(A4)�RETURN�KEY?ŠBNE.S‚FREC63�YES*DON'T RETURN KEY ŠCLR.L‚D1+ŠMOVE.B�FCBDIR+DIRKEY(A2),D1�GET�KEY�LENGTH%*SUBTRACT KEY SIZE FROM RECORD LENGTH#ŠADD.L‚D1,A1ŽADD�TO�START�OF�RECORD ŠSUB.L‚D1,D0 ŠBCC.S‚FREC63(*IF FEWER BYTES IN FILE THAN KEY LENGTH,*…SET�LENGTH�TO�0 ŠCLR.L‚D0ŠENDCFREC63„CMP.L‚D0,D4ŠBCC.S‚F REC65�BUFFER�BIG�ENOUGH**ENTIRE RECORD WILL NOT FIT IN USER BUFFER'*…RETURN�WHAT�WILL�WITH�BUFFER�OVERFLOW*ŠMOVE.L�D4,D0ŽD0=NO.�OF�CHARS.�TO�TRANSFER.ŠMOVE.L�#NL+ISTABO,D2†INDICATE�BUFFER�OVERFLOW!FREC65„BSR„SMOVE4�SET�UP�L-L�MOVE2ŠMOVE.L�D0,MVLENG(A0)†D0=NO.�OF�CHARS.�TO�TRANSFER ŠMOVE.L�D0,D4ŠBEQ.S‚FREC68�NO�DATA�TO�MOVE#ŠMOVE.L�A1,MVSADD(A0)†START�OF�REC.0ŠMOVE.L�FATIOS+IOSSAD(A4),MVDADD(A0)�USER�BUFFERŠERQ.MOVELL�(A0)!ŠBEQ.S‚FREC68�MOVE�WAS�SUCCESSFUL#ŠCMP.B‚#RTCDADR2,D0‡WRITE�PROECTED?#ŠBEQ„IOSER2�YES-INVALID�DATA�BUFFER ŠBSR„FTL.T*…D2.B=1�IF�RECORD�OVERFLOW'*…D4.L=NO.�OF�BYTES�TRANSFERRED/DELETED/FREC68„MOVE.L�D4,D0ŽD0=NO.�OF�BYTES�TRANSFERRED;FREC68BƒBSETW‚#FAFLRB,FATFLG(A4)�INDIDATE�REC.�I/O�COMPLETE)ŠBRA„FMRW31�GO�UPDATE�USER'S�LENGTH�FIELD8*FOR POSITION REQUEST, RETURN OFFSET TO RECORD IN BUFFERFREC69„MOVE.L�A1,D0ŠSUB.L‚FATSBS(A4),D0*…D0=OFFSET�TO�RECORDŠBRA.S‚FREC68BŠPAGE**RECORD SHOULD BE UPDATED*„D0=OLD�RECORED�LENGTH*…D4=NEW�RECORD�LENGTH6*…D7=USER�RECORD�LENGTH�(.GT.�D4�IF�SPACE�COMPRESSION)*…D5.B=FILE�TYPE#*…A1=POINTER�TO�BEGINNING�OF�RECORD**INDENTED LIST(* FREC70 COMPLETES RECORD UPDATE REQUEST*FREC70* SEQUENTIAL FILE? *‚YES,RECORDS�MUST-BE�SAME-.LEN.*‚NO,KEYS�MUST�BE�SAME* NEW-REC. LENGTH= OLD?*‚YES,UPDATE�RECORD�$MVEDTA*ƒGO�FINISH-I/O�REQUEST�$FMRW31!*‚NO,NEW�RECORD�SMALLER�THAN-OLD?*ƒYES,�UPDATE�RECORD�$MVEDTA*„REMOVE�EXTRA�SPACE�$CMPRDB"*…NO,GO�FINISH-I/O�REQUEST�$FMRW31*ƒGO-TO�RECORD�INSERT�$FREC175*INDENTED LIST END* FREC70„EQU„*ŠIFEQƒFMSLEVEL-3ŠCMP.B‚#DATSEQ,D5ŠBNE.S‚FREC705ŒMUST�BE�INDEXEDŠENDC *************-*MAKE SURE FILE ASSIGNED EREW IF DOING UPDATEŠMOVE.W�FATASN(A4),D1ŠAND.W‚#FAPBIT,D1ŠCMP.B‚#FOPEREW,D1ŠBNE„IOSER4�INVALID�FUNCTION ŠCMP.L‚D0,D45ŠBNE„IOSER2�NOT�SAME�LENGTH-INVALID�DATA�BUFFER�ADDR. ŠBRA.S‚FREC75ŠIFEQƒFMSLEVEL-3'*INDEXED FILE-MAKE SURE NEW KEY=OLD KEY"*…MOVE�NEW�KEY�TO�FMS�TEMP.�BUFFER0*FOR INDEXED FILE, NEW RECORD LENGTH NEED NOT BE*…SAME�AS�OLD�RECORD�LENGTH FREC705ƒEQU„*$ŠMOVE.L�D0,D1ŽSAVE�OLD�RECORD�LENGTHŠMOVE.L�VDTTMA(A6),A0 ŠBSR„MVEKEY*…D2=KEY�LENGTH*…A0=START�OF�KEY#ŠBEQ.S‚FREC72�KEY�MOVED�TO�FMS�AREAŠENDCFREC71„CMP.B‚#RTCDADR1,D0*ŠBEQ„IOSER2�BUFFER�NOT�IN�USER�ADDR.�SPACE ŠBSR„FTL.TŠIFEQƒFMSLEVEL-3?*OKAY TO MOVE KEY TO TEMP. BUFFER AND NOT FLAG SINCE IT IS ONLY(*…OVERLAYING�ITSELF�IF�SPACE�COMPRESSIONFREC72„BSR„CMPKEYŠBNE„IOSER12ŒKEYS�DON'T�MATCH*…D2�AND�A0�ALTERED ŠBTSTW‚#0,D1 ŠBEQ.S‚FREC74,ŠADD.L‚#1,D1ŽFORCE�RECORD�LENGTH�EVEN�IF�NOT)FREC74„MOVE.L�D4,D6ŽGET�NEW�RECORD�LENGTH ŠBTSTW‚#0,D6ŠBEQ.S‚FREC745ŠADD.L‚#1,D6ŽFORCE�EVENFREC745ƒCMP.L‚D1,D6,ŠBEQ.S‚FREC75�NOW�REC.�LENGTH=OLD�REC�LENGTH(ŠBHI.S‚FREC80�NEW�RECORD�BIGGER�THAN�OLD**NEW RECORD SMALLER THAN OLD-MOVE NEW DATA)*…TO�DATA�BLOCK�AND�COMPRESS�UNUSED�BYTES ŠBSR„MVEDTAŠBNE.S‚FREC71�ERROR�ON�L-L�MOVE&*CALCULATE NO. OF BYTES TO BE RELEASED ŠMOVE.L�D1,D0&ŠSUB.L‚D6,D0ŽD0=NO.�OF�BYTES�TO�DELETEŠADD.L‚#1,A1ŽPOINT�1�PAST�EORŠBRA„FREC125ŒGO�COMPRESS)*OKAY TO UPDATE RECORD-MOVE TO DATA BLOCKŠENDCFREC75„BSR„MVEDTAŠBNE.S‚FREC71�ERROR�ON�L-L�MOVE*INDICATE FAB SHOULD BE CHECKEDFREC78„BSETW‚#FAFLCB,FATFLG(A4)+ŠBCLRW‚#FAFLUB,FATFLG(A4)�CLEAR�UPDATE�FLAGŠCLR.B‚D2‘NO�BUFFER�OVERFLOW ŠBRA„FREC68ŠIFEQƒFMSLEVEL-32*NEW RECORD BIGGER THAN OLD-MUST EXPAND DATA BLOCK FREC80„EQU„* ŠMOVE.L�D6,D00ŠSUB.L‚D1,D0ŽD0=NO.�OF�ADDITIONAL�BYTES�REQUIRED(*MUST CALCULATE BEGINNING OF NEXT RECORD ŠMOVE.L�A1,A0ŠTST.W‚FCBDIR+DIRLRL(A2) ŠBNE.S‚FREC82ŠADD.L‚#BCTFLD,D1*FREC82„ADD.L‚D1,A0ŽA0=START�OF�NEXT�RECORD ŠBRA„FREC175ŠENDCŠPAGE*(*RECORD WRITE REQUEST-SEE IF RECORD WILL*…FIT�IN�EXISTING�DATA�BLOCK$*…A1=POINTER�TO�START�OF�LAST�RECORD*…D0=RECORD�LENGTH*…D3.B=TYPE�OF�WRITE*…D4=RECORD�LENGTH*†D5.W=TYPE�OF�FILE6*…D7=USER�RECORD�LENGTH�(.GT.�D4�IF�SPACE�COMPRESSION)2*CALCULATE NO. OF AVAILABLE BYTES IN DB (=SBE-SBL)+*MUST MAKE  SURE KEYS ARE IN ASCENDING ORDER**INDENTED LIST'* FREC90 COMPLETES RECORD WRITE REQUEST*FREC90* INDEXED SEQUENTIAL FILE?*‚YES,WRITE�AT-END�OF-FILE?*ƒYES,KEYS�MUST-BE�ASCENDING*„$MVEKEY,�$CMPKEY*…GO-TO�RECORD�INSERT�$FREC175*ƒNO,KEYS�MUST�BE�SAME *„WRITE�NEXT?*…YES,POINT�TO-NEXT�RECORD*†GO-TO�RECORD�INSERT�$FREC175*‚NO,SUFF.�ROOM-FOR�RECORD?*ƒNO,ALLOC.�MORE-SPACE�$FSALLC*‚MOVE-REC.�TO-BUFFER�$MVEDTA*ƒZERO-2�BYTES�AFTER�RECORD*‚GO�COMPLETE�REC.-I/O�$FMRW31*INDENTED LIST END* FREC90„EQU„*ŠIFEQƒFMSLEVEL-3ŠCMP.B‚#DATSEQ,D5‰SEQUENTIAL?ŠBEQ.S‚FREC91BŒYES-NO�KEYŠMOVE.L�VDTTMA(A6),A0 ŠBSR„MVEKEY*…D2=KEY�LENGTH*…A0=START�OF�MOVED�KEYŠBNE„FREC71�L-L�MOVE�ERRORH*KEY MOVED TO TEMP. BUFFER BUT JUST OVERLAYS RECORD IS DOING SPACE COMP. ŠTST.B‚D3ŠBNE„FREC190ŒWRITE�IN�MIDDLE6*FOR WRITE AT END, MAKE SURE NEW KEY .GT. EXISTING KEYŠCMP.B‚#DATISD,D5ŠBEQ.S‚FREC91�DUPLICATE�INDEX ŠBSR„CMPKEY ŠBCC„IOSER12ŒKEY�OUT�OF�SEQUENCEŠBRA.S‚FREC91B3*OKAY IF NEW KEY .GE. OLD KEY FOR DUPLICATE INDEXEDFREC91„BSR„CMPKEY ŠBHI„IOSER12ŠENDC FREC91BƒEQU„*B*FOR SEQUENTIAL FILE, MUST DETERMINE IF ENOUGH SPACE IN DATE BLOCK*…TO�ADD�RECORDŠCMP.B‚#DATSEQ,D5ŠBNE.S‚FREC92AŠMOVE.L�FATSBE(A4),D0ŠSUB.L‚FATSBL(A4),D0ŠBEQ.S‚FREC100ŒNO�SPACE�LEFT.*IF VRL, ADJUST FOR LENGTH OF BYTE COUNT FIELDŠTST.W‚FCBDIR+DIRLRL(A2) ŠBNE.S‚FREC92ŠSUB.L‚#BCTFLD,D0FREC92„CMP.L‚D4,D0-ŠBCS.S‚FREC100ŒNOT�ENOUGH�ROOM�IN�DATA�BUFFER FREC92AƒEQU„*ŠMOVE.L�FATSBL(A4),A1)FREC93„ADD.L‚#1,A1ŽA1=START�OF�NEW�RECORD2ŠADD.L‚#1,FATCLR(A4)†ADJUST�CLR�FOR�RECORD�WRITTENŠIFEQƒFMSLEVEL-3"ŠCMP.B‚#DATSEQ,D5‰SEQUENTIAL�FILE?ŠBNE„FREC173ŒNOŠENDC+*YES-RECORD WILL FIT IN DATA BUFFER-MOVE IN*…A1=WHERE�TO�STORE�RECORD*…D4=COMPRESSED�RECORD�LENGTH*…D7=USER�RECORD�LENGTH ŠBSR„MVEDTAŠBNE„FREC71�L-L�MOVE�ERROR0*ZERO 2 BYTES BEYOND END OF RECORD UNLESS AT ENDŠCMP.L‚FATSBE(A4),A1ŠBCC.S‚FREC97�AT�END'ŠCLR.W‚1(A1)ŽA1�POINTS�TO�END�OF�RECORD&FREC97„MOVE.L�A1,FATSBL(A4)†UPDATE�SBL*UPDATE END OF FILE INFO. ŠMOVE.L�#1,D0 ŠBSR„UPDEOR ŠBSR„UPDEOF*D0 ALTERED ON RETURN ŠBRA„FREC78<*NOT ENOUGH ROOM IN EXISTING DATA BLOCK-ALLOCATE ANOTHER ONEFREC100ƒBSR„FSALLC ŠBNE„IOSERR4ŠMOVE.L�FATSLS(A4),FATCLS(A4)�SET�CLS=START�OF�BLOCKŠMOVE.L�FATSBS(A4),A1 ŠSUB.L‚#1,A1ŠMOVE.L�A1,FATSBL(A4)†INIT.�SBLŠBRA„FREC93�MOVE�RECORD�TO�DBŠPAGEŠIFEQƒFMSLEVEL-3**DELETE LOGICAL RECORD REQUEST*…D0.L=RECORD�LENGTH*…A1=POINTER�TO�START�OF�RECORD:*SET UP TO REMOVE SPACE WHERE RECORD TO BE DELETED RESIDED**INDENTED LIST)* FREC120 COMPLETES DELETE RECORD REQUEST*FREC120* SUBTRACT ONE-FROM EOR $UPDEOR!* REMOVE SPACE FOR-RECORD $CMPRDB* GO-TO I/O COMPLETION $FMRW31*INDENTED LIST END* FREC120ƒEQU„*ŠMOVE.L�D0,D4ŽSAVE�BYTE�COUNT+ŠMOVE.L�#-1,D0�SUBTRACT�1�FROM�RECORD�INFO. ŠBSR„UPDEOR1ŠBSETW‚#FAFLLB,FATFLG(A4)�INDICATE�RECORD�DELETED$*ACCOUNT FOR BYTE COUNT FIELD IF VRL ŠMOVE.L�D4,D0ŠTST.W‚FCBDIR+DIRLRL(A2)ŠBNE.S‚FREC125ŒFRLŠADD.L‚#BCTFLD,D0<*COMMON PROCESSING FOR DELETE AND UPDATE WITH SHORTER RECORD0FREC125ƒBSR„CMPRDB�REMOVE�RECORD�FROM�DATA�BLOCK ŠBNE.S‚FRERR ŠBRA„FREC78ŠPAGE*1*RANDOM RECORD REQUEST-FIND POSITION OF REQUESTED*…RECORD�BASED�ON�KEY)*…FUNCTION�VALID�ONLY�FOR�KEY�SIZE�.GE.�20*USER RECORD LENGTH ALREADY CHECKED TO MAKE SURE*…BIG�ENOUGH�TO�HOLD�KEY*…MOVE�KEY�TO�TEMPOARY�BUFFER*…D4=RECORD�LENGTH*…D5.W=TYPE�OF�ASSIGNEMTN**INDENTED LIST)* FREC150 COMPLETES RANDOM RECORD REQUEST*FREC150* FIND-POS. FOR RECORD $FNDKEY* WRITE REQUEST?"*‚NO,ERROR�IF-RECORD�DOESN'T�EXIST**ƒGO-COMPLETE�READ,UPDATE�POSITION,�DELETE *‚YES,�EOF? *ƒYES,�MUST-ALLOC.�SPACE�$FSALLC*ƒNO,�RECORD�EXIST?*„YES,ERROR�UNLESS�DUPLICATES*‚GO�FINISH�INSERT�$FREC175*INDENTED LIST END* FREC150ƒEQU„*.*MOVE KEY TO EXTRA SECTOR AT END OF DATA BLOCKŠMOVE.L�FATSBE(A4),A0 ŠADD.L‚#1,A0 ŠBSR„MVEKEY*…D2=KEY�LENGTHŠBNE„FREC71�BAD�MOVEŠMOVE.L�A0,A3ŽA3=ADDR.�OF�KEY ŠBSR„F NDKEY�FIND�RECORD�WITH�KEY#*…A1=POINTER�TO�BEGINNING�OF�RECORD2* IF READ/DELETE/UPDATE REQUEST, RECORD MUST EXIST'ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)�WRITE?ŠBEQ.S‚FREC170ŒYES;*SET CLR 1ST SO THAT IF RECORD DOESN'T EXIST, CLR POINTS TO*…NEXT�RECORD�IN�SEQUENCEŠMOVE.L�FATSLS(A4),FATCLS(A4)ŠMOVE.L�D1,FATCLR(A4)†SAVE�CLR0ŠBCLRW‚#FAFLLB,FATFLG(A4)�CLEAR�REC.�DELETE�FLAGŠCMP.B‚#ISTARE,D0‰RECORD�EXIST?ŠBNE.S‚FRERRŽNO-MAKE�I/O�ERROR**GO PROCESS READ/UPDATE/ OR DELETE REQUEST ŠCLR.L‚D0.ŠMOVE.W�FCBDIR+DIRLRL(A2),D0�GET�RECORD�LENGTHŠBEQ„FREC59�VRL ŠBRA„FREC60ŠPAGE=*RANDOM WRITE REQUEST-MAKE SURE RECORD WITH GIVEN KEY DOESN'T)*…ALREADY�EXIST�UNLESS�DUPLICATES�ALLOWED*…D4=COMPRESSED�RECORD�LENGTH*…D5.W=TYPE�OF�ASSIGNMENT*…D7=USER�RECORD�LENGTH#*…A1=POINTER�TO�BEGINNING�OF�RECORDFREC170ƒCMP.B‚#ISTAEOF,D00ŠBEQ„FREC100ŒNOTHING�IN�FILE-MUST�ALLOCATE�SPACEŠCMP.B‚#ISTARE,D0‰RECORD�EXIST?ŠBNE.S‚FREC171ŒNO#*YES:OKAY IF DUPLICATE KEYS ALLOWEDŠCMP.B‚#DATISD,D5ŠBEQ.S‚FREC172ŒDUPLICATES�OKAY FREC171ƒEQU„*ŠCMP.B‚#ISTARN,D0ŠBEQ.S‚FREC172FRERR…BRA„IOSERR4FREC172ƒMOVE.L�D1,FATCLR(A4)†SAVE�CLR�FOR�NEW�RECORDŠMOVE.L�FATSLS(A4),FATCLS(A4)0ŠBCLRW‚#FAFLLB,FATFLG(A4)�CLEAR�REC.�DELETE�FLAG5*COMMON PROCESSING FOR WRITE RANDOM AND WRITE LOGICAL*FREC173ƒMOVE.L�A1,A0ŽA1,A0=INSERT�POSITION ŠMOVE.L�D4,D0ŠTST.W‚FCBDIR+DIRLRL(A2)‚VRL?ŠBNE.S‚FREC175'ŠADD.L‚#BCTFLD,D0‰ADJUST�FOR�BYTE�COUNT?*COMMON PROCESSING FOR RECORD WRITE AND UPDATE IF BIGGER RECORD*…D0=NO.�OF�BYTES�TO�EXPAND*…A0=POINT�OF�EXPANSION*…A1=START�OF�RECORD**INDENTED LIST0* FREC175 COMPLETES RECORD INSERT/UPDATE REQUEST*FREC175* MAKE-ROOM FOR-RECORD $EXPNDB* MOVE-DATA TO-RECORD $MVEDTA* WRITE REQUEST?*‚YES,ADD�1-TO-EOR�$UPDEOR!* UPDATE KEY-IF NECESSARY $PUTKEY!* UPDATE FAB-IF NECESSARY $UPCFAB* DO-I/O COMPLETION $FMRW31*INDENTED LIST END* FREC175ƒEQU„* ŠBSR„EXPNDB*ŠBNE.S‚FRERRŽCOULDN'T�FIND�ROOM�FOR�RECORD*MOVE RECORD INTO DATA BLOCK ŠBSR„MVEDTAŠBNE„FREC71�ERROR�ON�L-L�MOVE.*ACCOUNT FOR ONE RECORD ADDED IF WRITE REQUEST ŠCMP.W‚#IOWRIT,FATIOS+IOSFCT(A4)ŠBNE.S‚FREC178ŒNOT�WRITE ŠMOVE.L�#1,D0 ŠBSR„UPDEOR(*DETERMINE TYPE OF UPDATE REQUIRED BASED*…ON�D1�RETURN�FROM�EXPNDB FREC178ƒEQU„*%ŠCLR.B‚D2‘INDICATE�NO�BUFFER�OVERFLOW ŠTST.L‚D1ŠBEQ„FREC78�UPDATE�DONE#ŠSUB.B‚#1,D1ŽCALL�PUTKEY?�(D1�=�1?)ŠBNE.S‚FREC179ŒNO*MUST CALL PUTKEY ŠBSR„PUTKEY ŠBNE.S‚FRERR ŠBRA„FREC78.FREC179ƒCLR.L‚D0‘UPDATE�DATA�BLOCK'S�LAST�KEY?ŠSUB.B‚#1,D1Ž.�(D1=2?)ŠBEQ.S‚FREC180ŒYES8ŠMOVE.L�#1,D0ŽNO,�FLAG�TO�LEAVE�KEY�FIELD�ALONE�(D1�=�3)7FREC180ƒBSETW‚#FAFLUB,FATFLG(A4)�SET�FLAG�TO�UPDATE�FABŠBCLRW‚#FAFLCB,FATFLG(A4) ŠBSR„UPCFAB ŠBNE.S‚FRERR ŠBRA„FREC68ŠPAGE*'*LOGICAL RECORD WRITE TO MIDDLE OF FILE*…CLR=POINTER�TO�CURRENT�RECORD>*…D0=RECORD�LENGTH�OF�EXISTING�RECORD�WHERE�INSERT�IS�TO�OCCUR*…D3.B=TYPE�OF�WRITE*…D4=NEW�RECORD�LENGTH#*…A1=POINTER�TO�BEGINNING�OF�RECORD2*MAKE SURE KEY IN NEW RECORD=KEY IN CURRENT RECORD FREC190ƒEQU„* ŠBSR„CMPKEYŠBNE„IOSER12ŒKEYS�DON'T�MATCH<*IF WRITE NEXT REQUEST, POSITION TO BEGINNING OF NEXT RECORD ŠCMP.B‚#1,D3 ŠBNE„FREC1732ŠADD.L‚#1,FATCLR(A4)†SET�CURRENT�RECORD�TO�NEW�ONE ŠCLR.L‚D0.ŠMOVE.W�FCBDIR+DIRLRL(A2),D0�GET�RECORD�LENGTHŠBNE.S‚FREC195ŒFRL7ŠMOVE.W�(A1)+,D0‹GET�RECORD�LENGTH-SKIP�OVER�BYTE�COUNT ŠBTSTW‚#0,D0ŠBEQ.S‚FREC195$ŠADD.L‚#1,D0ŽFORCE�EVEN�NO.�OF�BYTES(FREC195ƒADD.L‚D0,A1ŽPOINT�TO�NEXT�RECORD ŠBRA„FREC173ŠPAGEŠENDCƒFMSLEVEL-3ŠENDCƒFMSLEVEL-1*.*IREWIND-REWIND FILE-SET POINTERS TO BEGINNING*…A2=FCB�ADDR.*…A4=FAT�ADDR.*…A6=VDT�ADDR.(*…A5=ADDR.�OF�USER�IOS�BLOCK�IN�FMS�AREA**INDENTED LIST* IREWIND REWINDS FILE*IREWIND"* UPDATE ALL-INFO. ON-DISK $PUTALL$* SET-FILE PTRS.TO BEGINNING $SETBEG*INDENTED LIST END* IREWINDƒEQU„*ŠIFGTƒFMSLEVEL-1ŠBSR„ATTIOB�ATTACH�TO�SEGMENTŠENDC%ŠBSR„PUTALL�UPDATE�EVERYTHING�ON�DISK ŠBNE.S‚IOSERR**SET FILE POINTERS TO BEGINNING* ŠBSR„SETBEG*…D0=1�ON�RETURNŠBRA.S‚IOSGRT� MAKE�GOOD�RETURNŠNOPŠPAGE$*SET UP TO MAKE GOOD RETURN FROM IOS*…A2=FCB�ADDR.*…A4=FAT�ADDR.*…A6=VDT�ADDR. IOSGRT„EQU„* ŠCLR.L‚D1#*COMMON GOOD/BAD PROCESSING FOR IOS(IOSRTN„BSR„CLRIOP�CLEAR�I/O�PENDING�FLAG*…A0�AND�D0�ARE�ALTEREDŠMOVE.L�FATTSK(A4),D2ŠMOVE.L�FATSES(A4),D3ŠMOVE.L�#IOSTIN,D4ŠMOVE.L�FATUPB(A4),A1,ŠMOVE.B�FATIOS+IOSSTA(A4),D5�SAVE�OLD�STATUSE*IF PROCEED I/O, STATUS MUST BE UPDATED SO SET TO $81 TO FORCE UPDATE!ŠBTSTW‚#IOPWATB,FATIOS+IOSOPT(A4)ŠBEQ.S‚IOSRT10ŒWAIT�I/O&ŠMOVE.L�#NL+$81,D5‰FORCE�STATUS�UPDATE.IOSRT10ƒBRA„FMSRTN�GO�FINISH�RETURN�PROCESSINGŠPAGE*-*SET UP TO MAKE ERROR RETURN FROM IOS REQUEST*…A2=FCB�ADDR.*…A4=FAT�ADDR.*…A6=VDT�ADDR.*.IOSER1„MOVE.L�#NL+ISTAPC,D0†PROTECT�CODE�ERRORIOSERR„CLR.L‚D1 ŠMOVE.B�D0,D1 ŠBRA.S‚IOSRTN4IOSER2„MOVE.L�#NL+ISTAADD,D0…INVALID�DATA�BUFFER�ADR ŠBRA.S‚IOSERR9IOSER3„MOVE.L�#NL+ISTAIP,D0†INVALID�PARAMETER�BLOCK�ADDR. ŠBRA.S‚IOSERR,IOSER4„MOVE.L�#NL+ISTAIF,D0†INVALID�FUNCTION ŠBRA.S‚IOSERR*IOSER6„MOVE.L�#NL+ISTAEOV,D0…END�OF�VOLUME ŠBRA.S‚IOSERR(IOSER7„MOVE.L�#NL+ISTAEOF,D0…END�OF�FILE ŠBRA.S‚IOSERR1IOSER8„MOVE.L�#NL+ISTARR,D0†INVALID�RANDOM�RECORD ŠBRA.S‚IOSERR2IOSER10ƒMOVE.L�#NL+ISTARE,D0†RECORD�ALREADY�EXISTS ŠBRA.S‚IOSERR#IOSER11ƒBSR„ISTAIERR‹INTERNAL�ERROR ŠBRA.S‚IOSERR&IOSER12ƒMOVE.L�#NL+ISTAKY,D0†KEY�ERROR ŠBRA.S‚IOSERR2IOSER13ƒMOVE.L�#NL+ISTASC,D0†DEVICE�STATUS�CHANGED ŠBRA.S‚IOSERR5IOSER14ƒMOVE.L�#NL+ISTAUF,D0†UNRECOVERABLE�FILE�ERROR ŠBRA.S‚IOSERRŠENDééééé**ˆCONDITIONAL�ASSEMBLY*FMSLEVEL EQU 3 ALL FILE TYPESééé éééé”=/* =/*†FUTY.AF=/*"=/* Chain file to assemble FUTY.SA=/*:=/* If no output argument is specified for the listing the&=/* chain file will default to FUTY.LS=/*=/IFC \1 ƒ=ARG�FUTY.LS=/ENDIF=/*&=ASM FMSI.SA/FUTY.SA,FUTY.RO,\1;RZ=186=/*{ Included files are:=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.EXE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.TR1.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.FME.EQ=/*ƒ9995.&.FMI.EQ=/*ƒ9995.&.UTILITY.MC=/*}=/*=ENDéééééé�ŠPAGE**ˆMODIFICATION�HISTORY* *ˆ03/05/84>*ˆMade�an�extra�entry�point�(DOIO2)�in�the�DOIO�routine.‚DOIO2@*ˆwill�not�force�the�proceed�bit�on,�it�will�leave�the�bit�as�it=*ˆwas�when�the�call�was�made.‚After�the�call,�the�proceed�bitC*ˆit�tested.‚If�conditions�indicate�that�I/O�wait�was�desired,�thenA*ˆreturn�is�made�immediately�to�point�of�call�instead�of�stacking=*ˆregisters�and�waiting�for�event�as�is�done�for�I/O�proceed.* *ˆ08/31/84A*ˆModifications�required�to�convert�FMS�into�a �Real�Time�Task.‚In?*ˆthe�case�of�FUTY,�the�changes�required�are�the�removal�of�the.*ˆWTEVNT�directive�from�the�DEVBSY�subroutine.*ŠPAGEŠNOLISTŠINCLUDE�9995.&.IOE.EQŠINCLUDE�9995.&.EXE.EQŠINCLUDE�9995.&.NIO.EQŠINCLUDE�9995.&.TR1.EQŠINCLUDE�9995.&.TR1RTCD.EQŠINCLUDE�9995.&.FME.EQŠINCLUDE�9995.&.FMI.EQŠINCLUDE�9995.&.UTILITY.MCŠLIST*‰INCLUDE�9995.&.IOE.EQ*‰INCLUDE�9995.&.EXE.EQ*‰INCLUDE�9995.&.NIO.EQ*‰INCLUDE�9995.&.TR1.EQ*‰INCLUDE�9995.&.TR1RTCD.EQ*‰INCLUDE�9995.&.FME.EQ*‰INCLUDE�9995.&.FMI.EQ*‰INCLUDE�9995.&.UTILITY.MC***FMS UTILITIES* ŠSECTION�0 ŠDC.Bƒ'FUTY'ŠDC.Lƒ'031584�4'UTY‡IDNTƒ4,2�FMS�UTILITIES ŠXDEFƒACKREQ ŠXDEFƒCALREC ŠXDEFƒCHKAP ŠXDEFƒCHKASC ŠXDEFƒCHKASN ŠXDEFƒCHKMA ŠXDEFƒCHKPRM ŠXDEFƒCHKRC ŠXDEFƒCHKSPL ŠXDEFƒCHKWAP ŠXDEFƒCHKWC ŠXDEFƒCHKWPD ŠXDEFƒCLRIOP ŠXDEFƒDEVBSY ŠXDEFƒDEVFRE ŠXDEFƒDMOVE ŠXDEFƒDOIO ŠXDEFƒDOIO2 ŠXDEFƒFMSASN ŠXDEFƒGENNME ŠXDEFƒGETATT ŠXDEFƒGETDCQ ŠXDEFƒGETFAT ŠXDEFƒGETFCB ŠXDEFƒGETFCBS ŠXDEFƒGETLUT ŠXDEFƒMOVE2UŠXDEFƒMOVENAME ŠXDEFƒMVEFNM ŠXDEFƒRELAPF ŠXDEFƒRELFAT ŠXDEFƒRELFCB ŠXDEFƒRELLUN ŠXDEFƒRELLUNR ŠXDEFƒSETBEG ŠXDEFƒSETPTR ŠXDEFƒSMOVE4 ŠXDEFƒSMOVEA ŠXDEFƒSRCDV ŠXDEFƒSRCFCB ŠXDEFƒSUASQ ŠXDEFƒUSNCHK ŠXDEFƒVALFNM ŠXDEFƒVALUSN ŠXDEFƒVALVOL ŠXDEFƒZERPTR ŠXREFƒACKBLK ŠXREFƒDTABLK ŠXREFƒDVEND ŠXREFƒDVSTR ŠXREFƒEXTSTR ŠXREFƒFATEND ŠXREFƒFATSTR ŠXREFƒFCBEND ŠXREFƒFCBSTR ŠXREFƒFHSFLG ŠXREFƒFHSQUE ŠXREFƒFMSAP ŠXREFƒFMSASQ ŠXREFƒFMSASQ1Ÿ¦h¯g·J¿UÇJÏR×VßHçHïY÷aÿ]ZZEJ'F/Q7V?NGVOZWK_Qg0o:w@K‡D�O ŠXREFƒFMSASR ŠXREFƒFMSBLK ŠXREFƒFMSBLK1 ŠXREFƒFMSFCBA ŠXREFƒFMSREV ŠXREFƒFMSSEG ŠXREFƒFTL.EQ ŠXREFƒFTL.HI ŠXREFƒFTL.NE ŠXREFƒFTL.T ŠXREFƒGETVID ŠXREFƒGPTSEC ŠXREFƒIOCEVT ŠXREFƒIOCOMS ŠXREFƒMOVBLK ŠXREFƒQIOBLK ŠXREFƒSAVESP ŠXREFƒSEGBLK ŠXREFƒSEGBLK2 ŠXREFƒSEGBLK3 ŠXREFƒSEGBLKO ŠXREFƒSEGBLKS ŠXREFƒSYSPACE ŠXREFƒTDBLK ŠXREFƒVDTEND ŠXREFƒVDTSTR ŠXREFƒWUBLKŠIFGTƒFMSLEVEL-1 �XDEFƒATTIOB �XDEFƒATTIOBO �XDEFƒCALSEC �XDEFƒCMPSPC �XDEFƒGETIOB �XDEFƒMVEDTA �XDEFƒMVEREC �XDEFƒRELIOB �XDEFƒUPDEOF �XDEFƒUPDEOR �XREFƒDBCHG �XREFƒFABCHGŠENDCŠIFEQƒFMSLEVEL-3 �XDEFƒCMPKEY �XDEFƒMVEKEYŠENDCŠPAGE* *SRCDV 1.00 12/4/79 L. STEINHOFF*,*SRCDV SEARCHES FOR REQUESTED DEFAULT VOLUME* *ON CALL:*…D1=REQUESTED�DEFAULT�VOLUME*‡('SYST'�->�SYSTEM*ˆ'SPOL'�->�SPOOLER�FILE*ˆ'TEMP'�->�TEMPORARY�FILE *ˆSESSION�NO. *…BSR�SRCDV* *ON RETURN:*…CARRY=0�IF�ENTRY�FOUND*Š=1�IF�DEFAULT�NOT�FOUND*…D0=FOUND�VOLUME�ID*…D1=UNCHANGED*…A0=ADDR.�FOR�FOUND�ENTRY&*…A0=ADDR.�OF�EMPTY�ENTRY�IF�NOT�FOUND*‡=0�IF�NO�AVAILABLE�ENTRY*INDENTED LIST-* SRCDV SEARCHES FOR REQUESTED DEFAULT VOLUME*SRCDV* REQUESTED DEFAULT FOUND?&*‚YES,RETURN�VOLUME-ID�AND-ENTRY�ADDR.*‚NO,EMPTY�ENTRY�FOUND? *ƒYES,RETURN�ADDR.OF�EMPTY�ENTRY*ƒNO,RETURN�NO-EMPTY�ENTRIES*INDENTED LIST END SRCDV…EQU„*ŠMOVE.L�A1,-(A7)&ŠSUB.L‚A1,A1ŽINIT.�EMPTY�ENTRY�POINTER-ŠMOVE.L�DVSTR,A0‹GET�START�OF�DEFAULT�VOLUMES$SRCD05„TST.L‚DEFVOL(A0)‰EMPTY�ENTRY?ŠBNE.S‚SRCD10�NOŠMOVE.L�A0,A1ŽYES-SAVE�ADDR. ŠBRA.S‚SRCD20SRCD10„CMP.L‚DEFTYP(A0),D1ŠBNE.S‚SRCD20�NO�MATCH*DEFAULT FOUND-RETURN INFO.ŠMOVE.L�DEFVOL(A0),D0ŠAND.B‚#$FE,SRŒCLEAR�CARRYSRCDRT„MOVE.L�(A7)+,A1ŠRTSSRCD20„ADD.L‚#DVLEN,A0ŠCMP.L‚DVEND,A0‹DONE?ŠBLS„SRCD05�NO*YES-MAKE ERROR RETURN$ŠMOVE.L�A1,A0ŽA0=ADDR.OF�EMTPRY�SLOT ŠOR.Bƒ#1,SR ŠBRA.S‚SRCDRTŠPAGE *VALVOL 1.00 7-6-79 L. STEINHOFF*,*VALVOL CHECKS TO SEE IF SPECIFIED VOLUME ID*„IS�DEFINED�IN�A�VDT?*…AFTER�LOOKING�UP�DEFAULT�VALUE�IF�VOLUME�PASSED�IS�ALL�SPACES<*IF DEFAULT IS TEMP. OR SPOOLER VOLUME AND IT DOESN'T EXIST, *TRY TO DEFAULT TO SYSTEM VOLUME3*…DEFAULTS�TO�USER�VOLUME�IF�NO�FILE�NAME�SPECIFIEDB*DEFAULTS TO SYSTEM VOLUME IF USER NO. =0 UNLESS USER IS SUPERVISOR?*…IN�WHICH�CASE�DEFAULTS�TO�USER�VOLUME�1ST,�THEN�SYSTEM�VOLUME* *ON CALL:*…A5=FHS�PARAMETER�BLOCK/*…A1=FMSASQ�ADDR.�WITH�EVTSES�AND�EVTUNM�SET�UP *„BSR�VALVOL* *ON RETURN*„Z=1�IF�VALID�VOLUME�ID*…=0�IF�INVALID�VOLUME�ID*„D0.B=0�IF�VALID�VOLUME�ID*ˆ=FSTAVDL�IF�VOLUME�NAME�ERROR*…A5=UNCHANGED+*…FHSVOL(A5)=VOLUME�ID�IF�DEFAULT�REQUESTED*…A6=VDT�ADDR.�(=0�IF�NONE)***INDENTED LIST5* VALVOL VERIFIES THAT SPECIFIED VOLUME ID IS DEFINED*VALVOL* PASSED VOLUME-ID= SPACES?"*‚YES,GET�DEFAULT�VOLUME-ID�$SRCDV* VOLUME-ID IN-VDT?*‚YES,RETURN�VDT-ADDR.*‚NO,RETURN�VOLUME�NAME-ERROR*INDENTED LIST END* *‰FHS�I/O�EVENT�MESSAGE�(VALVOL)**‰----------------------*‰*”**‰----------------------**ƒ24„*‡EVTSES‡*‡REQUESTOR'S�SESSION�NUMBER*‰*…(4�BYTES)†**‰----------------------*ƒ28„*‡EVTUNM‡*‡USER�NUMBER*‰----------------------*‡FHS�PARAMETER�BLOCK�(VALVOL)*‰----------------------*‰*”**‰----------------------*ƒ6…*‡FHSVOL‡*‡VOLUME�NAME*‰*…(4�BYTES)†**‰----------------------*ƒ10„*‡FHSUSN‡*‡USER�NUMBER*‰----------------------*‰*”**‰----------------------*ƒ20„*‡FHSFIL‡*‡FILE�NAME*‰*…(8�BYTES)†**‰----------------------* VALVOL„EQU„*ŠMOVEM.L�A0/D1,-(A7)ŠMOVE.L�FHSVOL(A5),D0ŠBEQ„VALV20�ERROR�IF�VOLUME=0ŠCMP.L‚#'„',D0ŠBNE.S‚VALV04A-*VOLUME IS ALL SPACES-MUST FIND DEFAULT VALUE#ŠCMP.B‚#'�',FHSFIL(A5)„VOLUME�ASSN?#ŠBEQ.S‚VALV01BŒYES-USE�USER�DEFAULT'ŠCMP.B‚#TEMPF,FHSFIL(A5)‚TEMPORARY�FILEŠBNE.S‚VALV01�NO2ŠMOVE.L�#TMPDEF,D1‰YES-SET�UP�TO�FIND�TEMP.�VOLUMEVALV00„BSR„SRCDV*ŠBCS.S‚VALV01CŒNOT�FOUND-USE�SYSTEM�VOLUME ŠBRA.S‚VALV04-VALV01„CMP.B‚#SPOOLF,FHSFIL(A5)�SPOOLER�FILE?ŠBNE.S‚VALV01AŒNO2ŠMOVE.L�#SPLDEF,D1‰YES-SET�UP�TO�FINE�SPOOLER�VOL. ŠBRA.S‚VALV00$VALV01AƒTST.W‚FHSUSN(A5)‰USER�NO.=0?ŠBNE.S‚VALV01B+*USE DEFAULT SESSION NO. IF TASK USER NO.=0ŠTST.W‚EVTUNM(A1)ŠBEQ.S‚VALV01B0VALV01CƒMOVE.L�#SYSDEF,D1‰YES-USE�SYSTEM�DEFAULTŠBSR„SRCDVŽFIND�SYSTEM�DEFAULT ŠBCS.S‚VALV20 ŠBRA.S‚VALV04)VALV01BƒMOVE.L�EVTSES(A1),D1†FIND�DEFAULTŠBSR„SRCDVŽFIND�DEFAULT ŠBCC.S‚VALV04=*USER DEFAULT NOT FOUND-USE SYSTEM DEFAULT IF TASK USER NO.=0ŠTST.W‚EVTUNM(A1)!ŠBEQ.S‚VALV01CŒTRY�SYSTEM�DEFAULTŠBRA.S‚VALV20�NO�DEFAULT-ERROR*RETURN DEFAULT VALUE TO USERVALV04„MOVE.L�D0,FHSVOL(A5) VALV04AƒEQU„*$ŠMOVE.L�VDTSTR,A6ŠGET�START�OF�VDT'S2VALV05„CMP.L‚VDTVID+VIDVOL(A6),D0�VOLUME�ID�FOUND?ŠBNE.S‚VALV10�N0*YES-MAKE GOOD RETURN ŠCLR.B‚D0VALVRT„MOVEM.L�(A7)+,D1/A0ŠRTSVALV10„LEA„VDTLEN(A6),A6!ŠCMP.L‚VDTEND,A6ŠAT�END�OF�TAB.E?ŠBLS.S‚VALV05�NO*YES = MAKE ERROR RETURNVALV20„MOVE.L�#FSTAVOL,D0ŠSUB.L‚A6,A6ŽINDICATE�NO�VDT ŠBRA.S‚VALVRTŠPAGE *VALUSN 1.00 8/6/79 L. STEINHOFF*.*VALUSN SUBSTITUTES THE USERS LOGGED ON NUMBER'*„IF�THE�USER�NO.�PASSED�IS�-�1.‚IF�THE$*„USER�NO.�PASSED�IS�-2,�AN�ERROR�IS *„RETURNED* *ON CALL:$*…A1=FMSASQ�ADDR.�WITH�EVTUNM�SET�UP*„A5=FHS�BLOCK�POINTER *„BSR�VALUSN* *ON RETURN:*„Z=1�IF�NO�ERROR *…=0�IF�ERROR*‚D0.B=0�IF�NO�ERROR5*…=FSTAFD�IF�INVALID�USER�NO.�(FILE�DESCRIPTOR�ERROR)*„A5=UNCHANGED4*…FHSUSN(A5)=USER�LOGGED�ON�NO.�IF�DEFAULT�REQUESTED* *‰FHS�I/O�EVENT�MESSAGE�(VALUSN)**‰----------------------*‰*”**‰----------------------*ƒ28„*‡EVTUNM‡*‡USER�NUMBER*‰----------------------*‡FHS�PARAMETER�BLOCK�(VALUSN)*‰----------------------*‰*”**‰----------------------*ƒ10„*‡FHSUSN‡*‡USER�NUMBER*‰----------------------** VALUSN„EQU„*ŠMOVE.W�FHSUSN(A5),D0 ŠCMP.W‚#-1,D0 ŠBNE.S‚VALU10ŠMOVE.W�EVTUNM(A1),FHSUSN(A5)VALURT„CLR.B‚D0ŠRTSVALU10„CMP.W‚#-2,D0 ŠBNE.S‚VALURT*USER NO. =-2 IS AN ERRORŠMOVE.L�#FSTAFD,D0ŠRTSŠPAGE*D*USNCHK MAKES SURE FILE CAN BE ALLOCATED, WRITE ASSIGNED, OR DELETED*…OR�RENAMED�FILE<*…BASED�ON�VOLUME�USER�NO.,�TASK�USER�NO.,�AND�FILE�USER�NO.* *RULES ARE:1*…1.‚IF�VOLUME�USER�NO.=0,�OKAY�IF�FILE�USER�NO.="*‡TASK�USER�NO.�OR�TASK�USER�NO. =05*…2.‚IF�VOLUME�USER�NO.�.NE.�0�OKAY�IF�TASK�USER�NO.=8*‡VOLUME�USER�NO.�OR�TASK�USER�NO.=0�AND�FILE�USER�NO.=0*‡OR�VOLUME�USER�NO.* *ON CALL:*…D1.W=TASK�USER�NO.*…A5=POINTER�TO�FHS�BLOCK*…A6=POINTER�TO�VDT *…BSR�USNCHK* *ON RETURN:*…Z=1�IF�IF�NO�ERROR *†=0�IF�ERROR*…D0.B=0�IF�NO�ERROR*‰=FSTAPC�IF�PROTECT�ERROR*…D1,A5,A6=UNCHANGED**INDENTED LIST>* USNCHK MAKES SURE USER CAN ALLOCATE FILE ON VOLUME SPECIFIED*USNCHK* VOLUME USER NO.=0?*‚YES,OKAY�IF-TASK�USER-NO.�=0*ƒFILE-USER�NO.=TASK�USER�NO.?*„NO,RETURN�PROTECT�CODE-ERROR*‚NO,OKAY�IF-TASK�USER-NO.�=0!*ƒVOLUME�USER-NO.=�TASK-USER�NO.?*„NO,RETURN�PROTECT�CODE-ERROR*„YES,OKAY�IF-FILE�USER-NO.�=0*…FILE-USER�NO.=TASK�USER-NO.?*†NO,RETURN�PROTECT�CODE-ERROR*INDENTED LIST END**‡FHS�PARAMETER�BLOCK�(USNCHK)**‰----------------------*‰*”**‰----------------------*ƒ10„*‡FHSUSN‡*‡USER�NUMBER*‰----------------------* USNCHK„EQU„*/ŠMOVE.W�VDTVID+VIDUSN(A6),D0�D0=VOLUME�USER�NO. ŠBNE.S‚USNC058*VOLUME USER NO.=0--TASK 0 CAN PUT ANYTHING ON VOLUME 0.'*…OTHER�USERS�CAN�PUT�THEIR�FILES�ON�ITŠTST.W‚D1‘TASK�USER�NO.=0?ŠBEQ.S‚USNGRT�YES-OKAY)ŠCMP.W‚FHSUSN(A5),D1†FILE�USER=TASK�USER?ŠBEQ.S‚USNGRT�YES-OKAYŠBRA.S‚USNERT�NO-MUST�BE�ERROR3*VOLUME USER NO. .NE. 0--TASK USER NO. MUST BE 0 OR/*…=VOLUME�USER�NO.�AND�FILE�USER�NO.�MUST�=0�OR*…VOLUME�USER�NO.USNC05„TST.W‚D1ŠBEQ.S‚USNC10�TASK�USER�NO.=0ŠCMP.W‚VDTVID+VIDUSN(A6),D1!ŠBNE.S‚USNERT�NOT�OWNER�OF�VOLUMEUSNC10„TST.W‚FHSUSN(A5)%ŠBEQ.S‚USNGRT�FILE�USER�NO.=0�->�OKAY3ŠCMP.W‚FHSUSN(A5),D0†FILE�USER�NO.=VOLUME�USER�NO.?ŠBNE.S‚USNERT�NO�-�NOT�OWNERUSNGRT„CLR.B‚D0ŠRTSUSNERT„MOVE.L�#FSTAPC,D0ŠRTSŠPAGE*-*MVEFNM MOVES USERNO. CATALOG, FILE NAME, AND!*„EXTENSION�FROM�FHS�BLOCK�TO�FCB* *ON CALL:*„A2=FCB�ADDR.*„A5=FHS�ADDR. *„BSR�MVENME* *ON RETURN:*„A2,A5=UNCHANGED**‡FHS�PARAMETER�BLOCK�(MVEFNM)**‰----------------------*‰*”**‰----------------------*ƒ10„*‡FHSUSN‡*‡USER�NUMBER*‰----------------------*ƒ12„*‡FHSCLG‡*‡CATALOG�NMAE*‰*…(8�BYTES)†**‰----------------------*ƒ20„*‡FHSFIL‡*‡FILE�NAME*‰*…(8�BYTES)†**‰----------------------*ƒ28„*‡FHSEXT‡*‡EXTENSION*‰----------------------** MVEFNM„EQU„*$ŠMOVE.W�FHSUSN(A5),FCBSDB+SDBUSN(A2)$ŠMOVE.L�FHSCLG(A5),FCBSDB+SDBCLG(A2)(ŠMOVE.L�FHSCLG+4(A5),FCBSDB+SDBCLG+4(A2)$ŠMOVE.L�FHSFIL(A5),FCBDIR+DIRFIL(A2)(ŠMOVE.L�FHSFIL+4(A5),FCBDIR+DIRFIL+4(A2)$ŠMOVE.W�FHSEXT(A5),FCBDIR+DIREXT(A2)ŠRTSŠPAGE *VALFNM 1.00 7-6-79 L. STEINHOFF*-*VALFNM CHECKS THE FILE NAME/EXTENSION FIELDS1*…FOR�VALIDITY.‚BOTH�FIELDS�MUST�BE�ALPHA-NUMERIC*…AND,�NOT�ALL�SPACES,*1ST CHAR OF FILE NAME MUST BE ALPHA,@, OR &$*1ST CHAR OF EXTENSION MUST BE ALPHA6*AND NO EMBEDDED SPACES (ONLY TRAILING SPACES ALLOWED)*8*CATALOG NAME IS ALSO CHECKED TO MAKE SURE ALPHA-NUMERIC*…ALL�SPACES�IS�VALID*…FIRST�CHAR.�MUST�BE�ALPHA�A-Z* *ON CALL:*„A5=FHS�BLOCK�POINTER*„(DEFAULTS�ALREADY�FILLED�IN) *„BSR�VALFNM* *ON RETURN*„Z=1�IF�NO�ERROR *…=0�IF�ERROR*„D0.B=0�IF�NO�ERROR*ˆ=FSTAFD�IF�SYNTAX�ERROR*…A5=UNCAHNGED**INDENTED LIST;* VALFNM CHECKS FOR LEGAL CATALOG, FILE NAME, AND EXTENSION*VALFNM* CHECK FOR VALID CATALOG*‚CATALOG�ALL�SPACES?*ƒYES,GOOD�CATALOG*ƒNO,1ST�CHAR�ALPHA?�$CHKALP*„NO,RETURN�FILE-DESC.�ERROR%*„YES,CAT.�ALL-ALPHA�NUMERIC?�$CHKASC*…NO,RETURN�FILE-DESC.�ERROR* CHECK FOR VALID FILE-NAME"*‚1ST-CHAR=�TEMP.-OR�SPOOLER�FILE?*ƒYES,MAKE�GOOD�RETURN*ƒNO,1ST�CHAR.�ALPHA?�$CHKALP*„NO,RETURN�FILE-DESC.�ERROR%*„YES,FILE�NAME-ALL�ALPHANUM?�$CHKASC*…NO,RETURN�FILE-DESC.�ERROR* CHECK-FOR VALID EXTENSION*‚1ST-CHAR.�ALPHA?�$CHKALP*ƒNO,RETURN�FILE-DESC.�ERROR%*ƒYES,EXT.�ALL-ALPHA�NUMERIC?�$CHKASC*„NO,RETURN�FILE-DESC.�ERROR*INDENTED LIST END***‡FHS�PARAMETER�BLOCK�(VALFNM)**‰----------------------*‰*”**‰----------------------*ƒ12„*‡FHSCLG‡*‡CATALOG�NMAE*‰*…(8�BYTES)†**‰---------- ------------*ƒ20„*‡FHSFIL‡*‡FILE�NAME*‰*…(8�BYTES)†**‰----------------------** VALFNM„EQU„*ŠMOVE.L�A1,-(A7)ŠLEA„FHSCLG(A5),A1+ŠMOVE.W�#CLGLEN,D0‰NO.�OF�BYTES�FOR�CATALOGŠCMP.B‚#'�',(A1)ŠBEQ.S‚VALF04CŒ1ST�CHAR=SPACE ŠBSR„CHKALP�1ST�CHAR�MUST�BE�A-Z ŠBRA.S‚VALF03VALF02„CMP.B‚#'�',(A1)ŠSPACE?ŠBEQ.S‚VALF04CŒYES ŠBSR.S‚CHKASCVALF03„BCS.S‚VALFERŠDCNTƒD0,VALF02ŠBRA.S‚VALF04EVALF04CƒCMP.B‚#'�',(A1)+ ŠBNE.S‚VALFERŠDCNTƒD0,VALF04C VALF04EƒEQU„*ŠLEA„FHSFIL(A5),A1,ŠMOVE.W�#FILLEN,D0‰NO.�OF�BYTES�IN�FILE�NAME*VALIDATE 1ST CHAR OF FILE NAMEŠCMP.B‚#SPOOLF,(A1)ŠBEQ.S‚VALFRT�OKAYŠCMP.B‚#TEMPF,(A1)5ŠBEQ.S‚VALFRT�OKAY-DON'T�CHECK�ANYMORE�FOR�TEMP.�FILEŠBSR.S‚CHKALP�MUST�BE�A-Z ŠBRA.S‚VALF18'VALF10„CMP.B‚#'�',(A1)ŠIS�CHAR�A�SPACE?ŠBEQ.S‚VALF25�YES#ŠBSR.S‚CHKASC�MAKE�SURE�VALID�ASCIIVALF18„BCS.S‚VALFER�ERROR)ŠDCNTƒD0,VALF10ŠFINISH�CHECKING�FILE�NAME ŠBRA.S‚VALF30�GO�CHECK�EXTENSION'VALF25„CMP.B‚#'�',(A1)+‰CHECK�FOR�SPACE&ŠBNE.S‚VALFER�ERROR�IF�NOT�REST�SPACESŠDCNTƒD0,VALF25*NOW CHECK EXTENSION FIELDVALF30„MOVE.W�#EXTLEN,D0"ŠBSR.S‚CHKALP�1ST�CHAR�MUST�BE�A-Z ŠBRA.S‚VALF40VALF35„CMP.B‚#'�',(A1) ŠBEQ.S‚VALF45 ŠBSR.S‚CHKASCVALF40„BCS.S‚VALFERŠDCNTƒD0,VALF35**FILE NAME/EXTENSION OKAY-MAKE GOOD RETURNVALFRT„CLR.B‚D0VALFR0„MOVE.L�(A7)+,A1ŠRTS*SPACE FOUND IN EXTENSION'VALF45„CMP.B‚#'�',(A1)+‰CHECK�FOR�SPACE ŠBNE.S‚VALFERŠDCNTƒD0,VALF45ŠBRA.S‚VALFRT�MAKE�GOOD�RETURN"*MAKE FILE DESCRIPTOR ERROR RETURNVALFER„MOVE.L�#FSTAFD,D0 ŠBRA.S‚VALFR0ŠPAGE*8*CHKASC CHECKS TO SEE IF CHARACTER IS SPACE, 0-9, OR A-Z*CHKALP ALLOWS ONLY A-Z *ON CALL:*„A1=POINTER�TO�CHARACTER*„BSR�CHKASC�OR�CHKALP* *ON RETURN:*„CARRY=O�IF�NO�ERROR *‰=1�IF�ERROR*„A1=A1+1�IF�NO�ERROR* CHKASC„EQU„*ŠCMP.B‚#'�',(A1)ŠBEQ.S‚CHKAS0�SPACE-OKŠCMP.B‚#'0',(A1)Š0-9?ŠBCS.S‚CHKAS1�NO-ERRORŠCMP.B‚#'9',(A1)ŠBLS.S‚CHKAS0�GOODCHKALP„CMP.B‚#'A',(A1)ŠA-Z?ŠBCS.S‚CHKAS1�ERRORŠCMP.B‚#'Z',(A1)ŠCHECK�LIMITŠBHI.S‚CHKAS1�ERROR(CHKAS0„TST.B‚(A1)+ŽSET�UP�FOR�NEXT�CHAR.*ŠAND.B‚#$FE,SRŒCLEAR�CARRY�FOR�GOOD�RETURNŠRTS%CHKAS1„OR.Bƒ#1,SRŽSET�CARRY�FOR�ERRORŠRTSŠPAGE *CHKAP 1.00 7/10/79 L. STEINHOFF*1*CHKAP CHECKS ACCESS PERMISSION PASSED AND EITHER)*„ASSIGNS�ACCESS�PERMISSION�OR�DE-ASSIGNS* *ON CALL:*„A6=ADDRESS�OF�VDT *„(ONLY�IF�ASSIGN/DE-ASSIGN�REQ)*…A2=ADDRESS�OF�FCB *„(ONLY�IF�ASSIGN/DE-ASSIGN�REQI*„D1.B=ACCESS�PERMISSION�CODE*„BIT�7=0->�ASSIGN*‰=1->�DE-ASSIGN*…BIT�6=0->ASSIGN,�DE-ASSIGN*Š=1->GET�READ/WRITE�TYPES�ONLY *„BSR‚CHKAP* *ON RETURN:1*„Z=1�IF�ACCESS�PERMISSION�GRANTED�OR�DE-ASSIGNED*…=0�IF�INVALID�REQUEST*„D0.B=0�IF�SUCCESSFUL$*ˆ=FSTAAP�IF�ACCESS�PERMISSION�ERROR'*…D1.B=UNCHANGED�(BITS�6�AND�7�CLEARED)5*…D2.L=READ�TYPE�(BITS�31-16),�WRITE�TYPE�(BITS�15-0)*+*CHKAP MAKES SURE THAT THE REQUESTED ACCESS,*„PERMISSION�IS�VALID;�ON�AN�ASSIGN�REQUEST,)*„IT�IS�CHECKED�TO�MAKE�SURE�IT�IS�NOT�IN)*„CONFLICT�WITH�EXISTING�VOLUME�AND�FFILE*…PROTECTION.‚IF�THE�ACCESS,*„PERMISSION�IS�VALID,�THE�WRITE/READ�COUNTS *…IN�THE�VDT�AND�FCB�ARE�UPDATEDD*IF A VOLUME NAME ONLY IS PASSED IN FCB (FILE NAME FIELD IS SPACES),6*…A�VOLUME�ASSIGNMENT/DE-ASSIGNMENT�IS�BEING�PROCESSED(*WRITE/READ COUNT HAS FOLLOWING MEANING:*„=-1->�EXCLUSIVE*„=0->�NOT�IN�USE*„=N->�NO.�OF�SHARED�ACCESSES-*ON REQUEST TO DE-ASSIGN, READ/WRITE COUNT IS*„SET�TO�0�IF�IT�HAD�BEEN�AN,*„EXCLUSIVE�ASSIGNMENT;�COUNT�IS�DECREMENTED**„(UNLESS�ALREADY�0)�FOR�PUBLIC�ASSIGNMENT**INDENTED LIST,* CHKAP ASSIGNS/DE-ASSIGNS ACCESS PERMISSION*CHKAP* VALID ACCESS PERM?*‚NO,RETURN�ACCESS�PERM.ERROR* ASSIGN/ DEASSIGN AP?*‚NO,RETURN�READ/WRITE�TYPES* EXCLUSIVE FILE ASSN?*‚YES,MAKE�PUBLIC�VOLUME�ASSN. * ASSIGN? *‚NO,DEASSN.�AP-FOR�FILE,�VOLUME*‚YES,CAN�AP-BE�ASSIGNED?*ƒNO,RETURN�AP-ERROR,*ƒYES,UPDATE�READ/WRITE�COUNTS-FOR�FILE/VOL.*INDENTED LIST END* CHKAP…EQU„*&ŠMOVEM.L�D3-D7/A1,-(A7)„SAVE�REGISTERS6ŠMOVE.L�#APTBL,A1ŠGET�START�OF�ACCESS�PERMISSI ON�TABLEŠMOVE.W�D1,-(A7)‹SAVE�D1#ŠAND.B‚#$3F,D1ŒMASK�OFF�BIT�6�AND�7,*SEARCH TABEL FOR MATCH ON ACCESS PERMISSION#CHKA05„CMP.B‚#-1,(A1)‹END�OF�TABLE?ŠBNE.S‚CHKA10�NO!ŠTST.W‚(A7)+ŽREMOVE�D0�FROM�STACK.*INVALID ACCESS PERMISSION - MAKE ERROR RETURNCHKAER„MOVE.L�#FSTAAP,D0+CHKART„MOVEM.L�(A7)+,A1/D3-D7„RESTORE�REGS.ŠRTS(CHKA10„CMP.B‚(A1)+,D1‹ACCESS�PERM.�MATCHŠBEQ.S‚CHKA15�YESŠTST.B‚(A1)+ŽSKIP�OVER�UNUSED ŠTST.L‚(A1)+ŽPOINT�TO�NEXT�ENTRY ŠBRA.S‚CHKA05*SAVE READ/WRITE TYPES#CHKA15„TST.B‚(A1)+ŽSKIP�OVER�UNUSED%ŠMOVE.L�(A1),D2ŒSAVE�READ/WRITE�TYPESŠBTSTW‚#6,(A7)ŒASSIGN/DE-ASSIGNŠBEQ.S‚CHKA14�YESŠTST.W‚(A7)+ŽCLEAN�UP�STACKŠBRA„CHKANR�RETURN�D2 CHKA14„EQU„*ŠMOVE.W�(A1)+,D6‹FILE�READ�TYPEŠMOVE.W�(A1),D7ŒFILE�WRITE�TYPE%ŠCLR.B‚D5‘D5=0�IF�NO�FILE�NAME�PASSEDŠCMP.B‚#'�',FCBDIR+DIRFIL(A2) ŠBEQ.S‚CHKA16ŠMOVE.L�#1,D5ŽFILE�NAME�PASSED CHKA16„EQU„*"ŠMOVE.W�D6,D3ŽSAVE�FOR�VOLUME�READ ŠBPL.S‚CHKA17/*IF EXCLUSIVE READ FOR FILE, MAKE PUBLIC VOLUME *„ASSIGNMENT ŠTST.B‚D5!ŠBEQ.S‚CHKA17�NOT�FILE�ASSIGNMENT ŠNEG.W‚D3CHKA17„MOVE.W�D7,D4 ŠBPL.S‚CHKA20,*IF EXCLUSIVE WRITE FOR FILE, VOLUME MUST BE*„ASSIGNED�PUBLIC�WRITE ŠTST.B‚D5!ŠBEQ.S‚CHKA20�NOT�FILE�ASSIGNMENT ŠNEG.W‚D4*D2=READ TYPE, WRITE TYPE*D6=READ TYPE FOR FILE*D7=WRITE TYPE FOR FILE*D3=READ TYPE FOR VOLUME*D4=WRITE TYPE FOR VOLUME"CHKA20„MOVE.W�(A7)+,D1‹RETRIEVE�D1ŠBCLRW‚#7,D1ŽDE-ASSIGN�REQUEST?ŠBNE„CHKA60�YES*CHECK FOR FILE READ ACCESS ŠTST.W‚D6 ŠBEQ.S‚CHKA30�NO�FILE�ASSIGNMENT1*FILE CANNOT CURRENTLY BE ASSIGNED EXCLUSIVE READŠCMP.W‚#-1,FCBRCT(A2)ŠBEQ.S‚CHKAER�ERROR�RETURNŠTST.W‚D6‘EXCLUSIVE�REQUESTED?1*IF EXCLUSIVE ASSIGNMENT, CURRENT COUNT MUST BE 0ŠBPL.S‚CHKA27�NOŠTST.W‚FCBRCT(A2) ŠBNE„CHKAER ŠBRA.S‚CHKA30 CHKA27„EQU„* *NO-SAVE VALUE OF NEW READ COUNTŠADD.W‚FCBRCT(A2),D6*CHECK FOR FILE WRITE ACCESSCHKA30„TST.W‚D7"ŠBEQ.S‚CHKA35�NO�FILE�WRITE�ACCESSŠCMP.W‚#-1,FCBWCT(A2)ŠBEQ„CHKAER�YES-ERRORŠTST.W‚D7‘EXC.�REQUESTEDŠBPL.S‚CHKA33�NOŠTST.W‚FCBWCT(A2) ŠBNE„CHKAER ŠBRA.S‚CHKA35 CHKA33„EQU„*)ŠADD.W‚FCBWCT(A2),D7†SAVE�NEW�WRITE�COUNT*CHECK FOR VOLUME READ ACCESSCHKA35„TST.W‚D3#ŠBEQ.S‚CHKA40�NO�VOLUME�READ�ACCESSŠCMP.W‚#-1,VDTRCT(A6)#ŠBEQ„CHKAER�ALREADY�EXCLUSIVE�ERRORŠTST.W‚D3‘EXCLUSIVE�REQUESTED?ŠBPL.S‚CHKA37�NOŠTST.W‚VDTRCT(A6) ŠBNE„CHKAER ŠBRA.S‚CHKA40 CHKA37„EQU„*'ŠADD.W‚VDTRCT(A6),D3†NO-SAVE�READ�COUNT**CHECK FOR VOLUME WRITE ACCESS*CHKA40„TST.W‚D4$ŠBEQ.S‚CHKA45�NO�VOLUME�WRITE�ACCESSŠCMP.W‚#-1,VDTWCT(A6)ŠBEQ„CHKAER�ALREADY�EXCLUSIVEŠTST.W‚D4‘EXCLUSIVE�REQUESTED? ŠBPL.S‚CHKA42ŠTST.W‚VDTWCT(A6) ŠBNE„CHKAER ŠBRA.S‚CHKA45 CHKA42„EQU„*(ŠADD.W‚VDTWCT(A6),D4†NO-SAVE�WRITE�COUNT*:*ACCESS PERMISSION CAN BE GRANTED-UPDATE READ/WRITE COUNTSCHKA45„TST.W‚D6 ŠBEQ.S‚CHKA47ŠMOVE.W�D6,FCBRCT(A2)†FILE�READCHKA47„TST.W‚D7 ŠBEQ.S‚CHKA50 ŠMOVE.W�D7,FCBWCT(A2)†FILE�WRITECHKA50„TST.W‚D3 ŠBEQ.S‚CHKA52!ŠMOVE.W�D3,VDTRCT(A6)†VOLUME�READCHKA52„TST.W‚D4 ŠBEQ.S‚CHKANR"ŠMOVE.W�D4,VDTWCT(A6)†VOLUME�WRITE CHKANR„CLR.B‚D0‘MAKE�GOOD�RETURN ŠBRA„CHKARTŠPAGE*+*DE-ASSIGN REQUEST-ADJUST READ/WRITE COUNTS*!CHKA60„TST.W‚D6‘FILE�READ�ACCESS?ŠBEQ.S‚CHKA65�NO ŠBPL.S‚CHKA62'*IT WAS EXCLUSIVE READ ACCESS; SET TO 0ŠCLR.W‚FCBRCT(A2) ŠBRA.S‚CHKA654*IT WAS PUBLIC READ ACCESS; DECREMENT COUNT UNLESS 0CHKA62„TST.W‚FCBRCT(A2)ŠBEQ.S‚CHKA65�ALREADY�0ŠSUB.W‚#1,FCBRCT(A2)*CHECK FOR FILE WRITE ACCESSCHKA65„TST.W‚D7 ŠBEQ.S‚CHKA75 ŠBPL.S‚CHKA72ŠCLR.W‚FCBWCT(A2) ŠBRA.S‚CHKA75CHKA72„TST.W‚FCBWCT(A2) ŠBEQ.S‚CHKA75ŠSUB.W‚#1,FCBWCT(A2)*CHECK FOR VOLUME READ ACCESSCHKA75„TST.W‚D3 ŠBEQ.S‚CHKA80 ŠBPL.S‚CHKA77ŠCLR.W‚VDTRCT(A6) ŠBRA.S‚CHKA80CHKA77„TST.W‚VDTRCT(A6) ŠBEQ.S‚CHKA80ŠSUB.W‚#1,VDTRCT(A6)*CHECK FOR VOLUME WRITE ACCESSCHKA80„TST.W‚D4 ŠBEQ.S‚CHKA85 ŠBPL.S‚CHKA82ŠCLR.W‚VDTWCT(A6) ŠBRA.S‚CHKA85CHKA82„TST.W‚VDTWCT(A6) ŠBEQ.S‚CHKA85ŠSUB.W‚#1,VDTWCT(A6)$CHKA85„BRA„CHKANR�MAKE�NORMAL�RETURNŠPAGE*  *ACCESS PERMISSION TABLE*"*EACH ENTRY IS 6 BYTES AS FOLLOWS:*„1=ACCESS�PERMISSION�CODE *…2=UNUSED*„3-4=READ�TYPE*„5-6=WRITE�TYPE**„TY@E=0�IF�NONE*ˆ=1�IF�PUBLIC*ˆ=-1�IF�EXCLUSIVE* APTBL…EQU„*ŠDC.BƒFOPPR,0ŒPUBLIC�READ ŠDC.Wƒ1,0ŠDC.BƒFOPER,0ŒEXCLUSIVE�READ ŠDC.Wƒ-1,0ŠDC.BƒFOPPW,0ŒPUBLIC�WRITE ŠDC.Wƒ0,1ŠDC.BƒFOPEW,0ŒEXCLUSIVE�WRITE ŠDC.Wƒ0,-1(ŠDC.BƒFOPPRPW,0ŠPUBLIC�READ/PUBLIC�WRITE ŠDC.Wƒ1,1&ŠDC.BƒFOPPREW,0ŠPUBLIC�READ/EXC.�WRITE ŠDC.Wƒ1,-1,ŠDC.BƒFOPERPW,0ŠEXCLUSIVE�READ/PPUBLIC�WRITE ŠDC.Wƒ-1,1"ŠDC.BƒFOPEREWŒEXC.�READ/EXC.�WRITE ŠDC.Wƒ-1,-1ŠDC.Bƒ-1,0�END�OF�TABLEŠPAGE!*GETFCB 1.00 7/15/79 L. STEINHOFF*B*GETFCB SEARCHES FOR AN EMPTY FCB AND RETURNS ITS ADDRESS IF FOUND* *ON CALL:*…A6=VDT�ADDR. *…BSR�GETFCB* *ON RETURN:*…Z=1�IF�FCB�FOUND*†=0�IF�NONE�AVAILABLE*…D0.B=0�IF�FCB�FOUND*‰=FSTASS�IF�NON�FCB�AVAILABLE5*…A2=FCB�ADDRESS�IF�FOUND�(VDT�ADDR.�INSERTED�IN�FCB)*…A6=UNCHANGED* GETFCB„EQU„*ŠMOVE.L�FCBSTR,A2GETF10„TST.L‚(A2)�EMPTY�FCB?ŠBEQ.S‚GETF20�YES-RETURN�ADDR.&ŠLEA„FCBLEN(A2),A2†POINT�TO�NEXT�ENTRY%ŠCMP.L‚FCBEND,A2ŠCHECKED�ALL�ENTRIES?ŠBLS.S‚GETF10�NO*YES-MAKE ERROR RETURN‰PUT_ADDR‚*,SYSPACE*œSET�DIAGNOSTIC!*¡OUT�OF�FILE�CONTROL�BLOCK�SPACE,ŠMOVE.L�#FSTASS,D0‰INSUFFICIENT�SYSTEM�SPACEŠRTS*GETF20„MOVE.L�A6,FCBVDT(A2)†SAVE�VDT�ADDR.ŠCLR.B‚D0‘MAKE�GOOD�RETURNŠRTSŠPAGE!*RELFCB 1.00 7/15/79 L. STEINHOFF*8*RELFCB RETURNS FCB TO AVAILABLE BY ZEROING ENTIRE ENTRY)*…FAB�MEMORY�IS�RELEASED�1ST�IF�IT�EXISTS* *ON CALL:*…A2=FCB�ADDR. *…BSR�RELFCB* *ON RETURN: *…A2�CHANGED* RELFCB„EQU„*ŠMOVE.W�D0,-(A7) ŠMOVE.W�#FCBLEN/2,D0‡NO.�OF�WRDSRELF10„CLR.W‚(A2)+ŠDCNTƒD0,RELF10ŠMOVE.W�(A7)+,D0ŠRTSŠPAGE!*GETFAT 1.00 7/19/79 L. STEINHOFF*-*GETFAT SEARCHES FOR AN EMPTY FAT AND RETURNS*…ADDRESS�IF�FOUND.* *ON CALL:*…A2=FCB�ADDR. *…BSR�GETFAB* *ON RETURN:*…Z=1�IF�FAT�FOUND*†=0�IF�NONE�AVAILABLE*…D0.B=0�IF�FAT�FOUND*‰=FSTASS�IF�NO�FAT�AVAILABLE*…A2=UNCHANGED3*…A4=FAT�ADDR.�IF�FOUND�(FCB�ADDR.�INSERTED�IN�FAT)* GETFAT„EQU„*$ŠMOVE.L�FATSTR,A4ŠGET�START�OF�FAT'SGETFA1„TST.L‚(A4)�EMPTY�FAT?ŠBEQ.S‚GETFA5�YES)ŠLEA„FATLEN(A4),A4†NO-POINT�TO�NEXT�ENTRYŠCMP.L‚FATEND,A4ŠCHECKED�ALL?ŠBLS.S‚GETFA1�NO‰PUT_ADDR‚*,SYSPACE*œSET�DIAGNOSTIC*¡FAT�SPACE�ALL�GONE(ŠMOVE.L�#FSTASS,D0‰YES-MAKE�ERROR�RETURNŠRTS*GETFA5„MOVE.L�A2,FATFCB(A4)†SAVE�FCB�ADDR. ŠCLR.B‚D0ŠRTSŠPAGE!*RELFAT 1.00 7/19/79 L. STEINHOFF*8*RELFAT RETURNS FAT TO AVAILABLE BY ZEROING ENTIRE ENTRY2*…DATA�BUFFER�SEGMENT�IS�RELEASED�1ST�IF�IT�EXISTS* *ON CALL:*…A4=FAT�ADDR. *…BSR�RELFAT* *ON RETURN:#*…A4=UNCHANGED�(FOR�EOT�PROCESSING)* RELFAT„EQU„*ŠMOVEM.L�D0/A4,-(A7)ŠIFGTƒFMSLEVEL-1)ŠBSR„RELIOB�RELEASE�SEGMENT�IF�ONE�EXISTSŠENDC!ŠMOVE.W�#FATLEN/2,D0‡NO.�OF�WORDSRELFA1„CLR.W‚(A4)+ŽZEROŠDCNTƒD0,RELFA1ŠMOVEM.L�(A7)+,D0/A4ŠRTSŠPAGE!*SRCFCB 1.00 7/15/79 L. STEINHOFF*=*SRCFCB SEARCHES FOR FCB FOR VOLUME, USER NO. FILE, EXTENSION*…PASSES* *ON CALL:*…A6=VDT�ADDRESS7*…A5=POINTER�TO�FHS�BLOCK�CONTAINING�USER�NO.�FILE�NAME*ˆAND�EXTENSION *…BSR�SRCFCB* *ON RETURN:*…CARRY=0�IF�FCB�FOUND*Š=1�IF�NOT�FOUND*…A6=UNCHANGED *…A5=UNCHAGED*…A2=FCB�ADDRESS�IF�FOUND**‡FHS�PARAMETER�BLOCK�(SRCFCB)**‰----------------------*‰*”**‰----------------------*ƒ10„*‡FHSUSN‡*‡USER�NUMBER*‰----------------------* SRCFCB„EQU„*ŠMOVEM.L�D0/A3-A4,-(A7)ŠMOVE.L�FCBSTR,A2+SRCF05„CMP.L‚FCBVDT(A2),A6†VDT�ADRS.�MATCH?!ŠBNE.S‚SRCF30�NO-GO�TO�NEXT�ENTRY)*VOLUME ID'S ARE SAME-CHECK USER NO. ETC.*…GET�START�OF�BOTH�USER�NOS.ŠLEA„FHSUSN(A5),A3ŠLEA„FCBSDB+SDBUSN(A2),A4ŠCMPM.W�(A3)+,(A4)+ŠBNE.S‚SRCF30�NOT�RIGHT�FCB$ŠMOVE.W�#(CLGLEN+FILLEN+EXTLEN)/2,D0SRCF20„CMPM.W�(A3)+,(A4)+ ŠBNE.S‚SRCF30ŠDCNTƒD0,SRCF20 *FCB FOUNDŠAND.B‚#$FE,SRŒCLEAR�CARRYSRCFRT„MOVEM.L�(A7)+,A3-A4/D0ŠRTS*SRCF30„LEA„FCBLEN(A2),A2†POINT�TO�NEXT�FCBŠCMP.L‚FCBEND,A2ŠDONE?ŠBLS.S‚S  RCF05�NO*YES-MAKE ERROR RETURNŠOR.Bƒ#1,SRŽSET�CARRY ŠBRA.S‚SRCFRTŠPAGE!*RELAPF 1.00 7/23/79 L. STEINHOFF*1*RELAPF DE-ASSIGNS ACCESS PERMISSION AND RELEASES*…FCB�IF�NECESSARY* *ON CALL:9*…FMSAP=ACCESS�PERMISSION�TO�BE�DE-ASSIGNED�(=-1�IF�NONE))*…FMSFCBA=FCB�TO�BE�RELEASED�(=0�IF�NONE)3*…A2=FCB�ASSOCIATED�WITH�AP�(ONLY�IF�FMSAP�.NE.�-1)3*…A6=VDT�ASSOCIATED�WITH�AP�(ONLY�IF�FMSAP�.NE.�-1) *…BSR�RELAPF* *ON RETURN: *…FMSAP=-1 *…FMSFCBA=0*…A2=UNCHANGED*…A6=UNCHANGED* RELAPF„EQU„*ŠMOVEM.L�D0-D2/A2,-(A7)-ŠMOVE.B�FMSAP,D1‹HAS�ACCESS�PERM.�BEEN�SETUP?ŠBMI.S‚RELA10�NOŠBSETW‚#7,D1ŽREQUEST�DE-ASSIGNŠBSR„CHKAPŽDE-ASSIGN+ŠMOVE.B�#-1,FMSAPŠINDICATE�NOTHING�ASSIGNED&RELA10„MOVE.L�FMSFCBA,A2‰GET�FCB�ADDR.ŠCMP.L‚#0,A2ŽFCB�TO�RELEASE?ŠBEQ.S‚RELART�NOŠBSR„RELFCB�YESŠCLR.L‚FMSFCBAŒINDICATE�NO�FCBRELART„MOVEM.L�(A7)+,D0-D2/A2ŠRTSŠPAGE*-*SETPTR INITIALIZES REGISTERS FOR VDT,FCB,AND *„FAT�TABLES* *ON CALL:*#*…FMSASQ1+EVTLUE=ADDR.�OF�LUN�ENTRY *„BSR�SETPTR** *ON RETURN:*„A6=VDT�ADDR.*„A4=FAT�ADDR.*„A2=FCB�ADDR.,*SETPTR GOES TO FMSFTL IF FAT DOES NOT EXIST* SETPTR„EQU„*ŠMOVEM.L�D0/A0,-(A7)ŠLEA„FMSASQ1,A0ŠMOVE.L�EVTLUE(A0),A2 ŠMOVE.L�A2,D0#ŠMOVE.L�LUTDCB(A2),A2†GET�FCB�ADDR.ŠMOVE.L�FATSTR,A4*LOOK FOR CORRECT FAT ADDR.SETP05„CMP.L‚FATLUE(A4),D0 ŠBNE.S‚SETP10*FAT HAS BEEN FOUNDŠMOVE.L�FCBVDT(A2),A6†VDT�ADDR.ŠMOVEM.L�(A7)+,D0/A0ŠRTSSETP10„LEA„FATLEN(A4),A4ŠCMP.L‚FATEND,A4 ŠBLS.S‚SETP05ŠBSR„FTL.TŽCAN'T�FIND�FATŠPAGE*.*RELLUN RELEASES LUN ENTRY BY DOING FOLLOWING:2*„LUT�-�COUNT�OF�ACTIVE�LU�ASSIGNMENTS�DECREMENTED-*„LUN�-�ACTIVE,�ASSIGNMENT�PENDING,�AND�CLOSE*†PENDING�BITS�CLEARED* *ON CALL:!*…FMSASQ+EVTLUT=ADDR.�OF�LU�TABLE"*…FMSASQ+EVTLUE=ADDR.�OF�LUN�ENTRY *„BSR�RELUN* *ON RETURN:*…REGISTERS�UNCHANGED* RELLUN„EQU„*ŠMOVEM.L�A0-A1/D0,-(A7)ŠMOVE.L�FMSASQ+EVTLUT,A0ŠMOVE.L�FMSASQ+EVTLUE,A1 RELL10„EQU„**DON'T DESTROY A0ŠMOVE.L�A0,-(A7)ŠBSR„GETLUT�GET�LUT�SEM.ŠMOVE.L�(A7)+,A0'ŠSUB.B‚#1,LUTCAS(A0)†ADJUST�CURRENT�NO.+ŠBCLRW‚#LUSFAC,LUTCAP(A1)�CLEAR�ACTIVE�FLAG.ŠBCLRW‚#LUSFAS,LUTCAP(A1)�CLEAR�ASSIGN�PENDING-ŠBCLRW‚#LUSFCP,LUTCAP(A1)�CLEAR�CLOSE�PENDINGŠMOVE.L�IOCOMS,A0ŠCLR.B‚SVTSLUT(A0)ŠMOVEM.L�(A7)+,A0-A1/D0ŠRTS**RELLUNR USED BY SEND LU*…D6=RECEIVER'S�LUT*…D7=RECEIVER'S�LUE RELLUNRƒEQU„*ŠMOVEM.L�A0-A1/D0,-(A7) ŠMOVE.L�D6,A0 ŠMOVE.L�D7,A1 ŠBRA.S‚RELL10ŠPAGE*)*CLRIOP CLEARS I/O PENDING FLAG AND WAKES"*…UP�FHS�IF�CLOSE�PENDING�FLAG�SET* *ON CALL:*…A4=FAT�ADDR.*…FATLUE=LU�ENTRY *…BSR�CLRIOP* *ON RETURN:*…A0,D0=CHANGED(*…GOES�TO�FMSFTL�IF�ERROR�ON�WAKEUP�CALL* CLRIOP„EQU„*ŠMOVE.L�FATLUE(A4),A0***************************2*…NO�NEED�TO�LOCK�LUT�HERE�SINCE�ONLY�CLEARING�BIT**********************+ŠBCLRW‚#LUSFIO,LUTCAP(A0)�CLEAR�I/O�PENDING(ŠBTSTW‚#LUSFCP,LUTCAP(A0)�CLOSE�PENDING?ŠBEQ.S‚CLRI10�NO#*MUST WAKE UP FHS TO COMPLETE CLOSEŠERQ.WAKEUP�WUBLK ŠBSR„FTL.NE CLRI10„RTSŠPAGE* *GETATT 1.00 10/9/79 L.STEINHOFF*(*GETATT FETCHES FILE ATTRIBUTES FROM FCB*…AND�MOVES�TO�FMS'S�FHS�BLOCK**…AND�SETS�UP�PARAMETER�BLOCK�FOR�MOVE�L-L* *ON CALL:*…A2=FCB�ADDR.*…A5=FHS�PARAMETER�BLOCK�ADDR.*…A6=VDT�ADDR.*…FMSASQ+EVTRA0=USER'S�A0�VALUE!*…EVTTSK,EVTSES=USER�TASK/SESSION *…BSR�GETATT* *ON RETURN:/*…A0=ADDR.�OF�L-L�MOVE�PARAMETER�BLOCK�(MOVBLK)$*‡SOURCE,�DEST,�AND�LENGTH�FILLED�IN2*…FOLLOWING�FIELDS�OF�FHS�BLOCK�HAVE�BEEN�ALTERED:*‡FHSOPT�(1ST�BYTE�ONLY)*‡FHSSIZ*‡FHSLRL**INDENTED LIST'* GETATT GETS FILE OR VOLUME ATTRIBUTES*GETATT* VOLUME ASSN? *‚YES,MOVE�NO.OF�SECTORS�TO-SIZE*ƒMOVE-SECT.�SIZE-TO�LRL*„MOVE-DEV.�TYPE-TO�OPTIONS*‚NO,MOVE�FILE-TYPE�TO-OPT*ƒCONTIGUOUS�FILE?*„YES,MOVE�SECTOR�SIZE-TO�LRL*…MOVE�FILE�SIZE�TO-SIZE*„NO,MOVE�RECORD�LENGTH-TO�LRL*…MOVE-FAB,�DB,KEY�SIZE-TO�SIZE*INDENTED LIST END***‡FHS�PARAMETER�BLOCK�(GETATT)**‰----------------! ------*‰*”**‰----------------------*ƒ2…*‡FHSOPT‡*‡OPTIONS*‰----------------------*‰*”**‰----------------------%*ƒ34„*‡FHSLRL‡*‡LOGICAL�RECORD�LENGTH*‰----------------------$*ƒ36„*‡FHSSIZ‡*‡CONTIGUOUS�FILE�SIZE*‰*…(4�BYTES)†**‰----------------------* GETATT„EQU„*ŠMOVEM.L�D0-D1/A1,-(A7) ŠCLR.L‚D1*ŠCMP.B‚#'�',FCBDIR+DIRFIL(A2)�VOLUME�ASSN?ŠBEQ.S‚GETA30�YES*ASSIGNMENT FOR FILE+ŠMOVE.B�FCBDIR+DIRATT(A2),D0�GET�ATTRIBUTES1*ATTRIBUTES RETURNED IN 1ST BYTE OF OPTIONS FIELDŠMOVE.B�D0,FHSOPT(A5)1*RECORD LENGTH OF FILE IS DETERMINED BY FILE TYPEŠAND.B‚#DFTBIT,D0"ŠCMP.B‚#DATCON,D0‰CONTIGUOUS�FILE?ŠBNE.S‚GETA22�NO3ŠMOVE.W�#SECSZE,FHSLRL(A5)�YES-REOCRD�LENGTH�IS�256!*SET SIZE FIELD TO LENGTH OF FILE(ŠMOVE.L�FCBDIR+DIRFE(A2),D1�GET�FILE�END ŠADD.L‚#1,D1ŠMOVE.L�D1,FHSSIZ(A5) ŠBRA.S‚GETA40-*FOR OTHER FILE TYPES, SETUP SIZE FIELD WITH,)*„FAB�SIZE,�DATA�BLOCK�SIZE,�AND�KEY�SIZE*GETA22„MOVE.L�FCBDIR+DIRRS2(A2),FHSSIZ(A5)$ŠMOVE.W�FCBDIR+DIRLRL(A2),FHSLRL(A5) ŠBRA.S‚GETA40@*VOLUME ASSIGNMENT-SET UP DEVICE TYPE AND NO. OF SECTORS ON DISK)GETA30„MOVE.L�VDTDCB(A6),A1†GET�DCB�ADDR.,ŠMOVE.L�DCBSEC(A1),FHSSIZ(A5)�NO.�OF�SECTORS'ŠMOVE.W�DCBLEN(A1),FHSLRL(A5)�REC.�LEN.)ŠMOVE.B�DCBFLG(A1),FHSOPT(A5)�DEVICE�TYPE*SET UP PARAMETERS FOR L-L MOVE!GETA40„BSR„SMOVEA�SET�UP�L-L�MOVE&ŠLEA„FHSOPT(A5),A1†GET�START�OF�SOURCEŠMOVE.L�A1,MVSADD(A0)2ŠMOVE.L�FMSASQ+EVTRA0,A1ƒGET�START�OF�USER'S�BLOCK#ŠLEA„FHSOPT(A1),A1†POINT�TO�OPTIONS ŠMOVE.L�A1,MVDADD(A0)†DEST�ADDR..ŠMOVE.L�#FHSBLN-FHSOPT,MVLENG(A0)�NO.�OF�BYTESŠMOVEM.L�(A7)+,D0-D1/A1ŠRTSŠPAGEŠIFGTƒFMSLEVEL-1* *GETIOB 1.00 10/9/79 L.STEINHOFF*/*GETIOB ALLOCATES A SEGMENT FOR DATA BUFFER/FAB<*…AND�THEN�MAKES�SEGMENT�PERMANENT�AND�SHARABLE�IF�REQUESTED* *ON CALL:*„A2=FCB�ADDRESS*…A4=FAT�ADDRESS*…A6=VDT�ADDRESS.*…D0-BIT�7=0/1�->�ALLOCATE�DB�AND�FAB/FAB�ONLY6*ˆBIT�6=0/1�->�NOT�GLOBALLY�SHARABLE/GLOABLLY�SHARABLE *…BSR�GETIOB* *ON RETURN:*…Z=1�IF�NO�ERROR *†=0�IF�ERROR*…D0.B=0�IF�NO�ERROR&*‰=FSTASS�IF�INSUFFICIENT�SYSTEM�SPACE*5*GETIOB GOES TO FMSFTL IF UNEXPECTED ERROR ON SEGMENT&*…DIRECTIVEES�OR�BITS�6�AND�7�BOTH�SET0*IF SUCCESSFUL, FAT HAS BEEN UPDATED AS FOLLOWS: *…SBS=START�OF�DB�(IF�ALLOCATED)*…SBE�AND�SBL=END�OF�DB*…FAA=START�OF�FAB*…FAE=END�OF�FAB*…BSN=SEGMENT�NAME*…FAFLSB=1�IF�DB�ALLOCATED5*…FMSSEG�(SEGMENT�NAME)�INCREMENTED�BEFORE�GTSEG�CALL7*…SEGNAM�IN�SEGBLK2=ALLOCATED�AND�ATTACHED�SEGMENT�NAME!*…SEGNAM=0�IF�INSUFFICIENT�MEMORY%*SEGMENT IS ATTACHED TO FMS ON RETURN*0*GETIOB USES DTABLK AND SEGBLK2 PARAMETER BLOCKS**INDENTED LIST** GETIOB ALLOCATES A SEGMENT FOR FILE DATA*GETIOB"* DEATTACH EXISTING SEGMENT .DESEG* ALLOCATE NEW SEGMENT .GTSEG* SAVE-FAB, DB-ADDRS. IN-FAT * MAKE SEGMENT PERMANENT .DCLSHR*INDENTED LIST END* GETIOB„EQU„**SET UP TO ALLOCATE SEGMENTŠMOVEM.L�A0/D1-D3,-(A7)ŠMOVE.B�D0,D3ŽSAVE�OPTIONS-*ERROR IF SHARED SEGMENT REQUEST FOR FAB ONLY ŠBTSTW‚#6,D3ŠBEQ.S‚GETI05�NOT�SHARED ŠBTSTW‚#7,D3ŠBNE.S‚GETER1�FATAL�ERROR GETI05„EQU„*8*IF ANOTHER SEGMENT IS ALLOCATED, IT MUST BE DE-ATTACHEDŠLEA„SEGBLK2,A0ŠTST.L‚SEGNAM(A0)ŠBEQ.S‚GETI07�NONE�ATTACHED%ŠCLR.W‚SEGOPT(A0)‰SET�UP�TO�DE-ATTACHŠERQ.DESEG�(A0)ŠCLR.L‚SEGNAM(A0) GETI07„EQU„*$ŠLEA„DTABLK,A0ŠGET�PARM.�BLOCK�ADDR.'ŠADD.L‚#1,FMSSEGŠINCREMENT�SEGMENT�NAME%*CALCULATE LENGTH OF SEGMENT REQUIRED ŠCLR.W‚D1%ŠMOVE.B�FCBDIR+DIRFAB(A2),D1�FAB�SIZEŠBTSTW‚#7,D3ŽALLOCATE�DB?ŠBNE.S‚GETI10�NO*YES-ADD DB SIZE TO FAB SIZE ŠCLR.W‚D2ŠMOVE.B�FCBDIR+DIRDAT(A2),D22*ADD 1 TO DB SIZE TO ACCOUNT FOR INSERT PROCESSING ŠADD.W‚#1,D2ŠADD.W‚D2,D1ŽD1=NO.�OF�SECTORS&GETI10„MULUƒ#SECSZE,D1‰D1*NO.�OF�BYTESŠMOVE.L�D1,SEGLEN(A0)ŠERQ.GTSEG�(A0)!ŠBEQ.S‚GETI20�ALLOCATE�SUCCESSFUL0*DETERMINE IF ERROR CAUSED BY UNAVAILABLE MEMORYŠCMP.B‚#RTCDNMEM,D0 ‰BEQ‡GETI45*MUST BE UNEXPECTED ERROR!GETER1„BSR„FTL.TŽMAKE�FATAL�ABORT2GETER2„MOVE.L�#FSTASS,D0‰INSUFFICIENT�SYSTEM�SPACE! GETRTN„MOVEM.L�(A7)+,A0/D1-D3ŠRTS*SEGMENT WAS ALLOCATED*…A0=PHYSICAL/LOGICAL�ADDR.(*SAVE INFO. IN FAT BEFORE TRYING TO MAKE*…SEGMENT�PERMANENT/SHARABLE GETI20„EQU„*ŠBTSTW‚#7,D3ŽFAB�ONLY?ŠBNE.S‚GETI30�YES-*DB WAS ALLOCATED-SAVE BUFFER START/END ADDR.ŠMOVE.L�A0,FATSBS(A4) ŠCLR.W‚D2ŠMOVE.B�FCBDIR+DIRDAT(A2),D2'ŠMULUƒ#SECSZE,D2‰CALCULATE�LENGTH�OF�DB ŠSUB.L‚#1,D2 ŠADD.L‚D2,A06*ENDING ADDR. DOES NOT INCLUDE EXTRA SECTOR FOR INSERT'ŠMOVE.L�A0,FATSBE(A4)†SAVE�ENDING�ADDR.ŠMOVE.L�A0,FATSBL(A4)#ŠADD.L‚#SECSZE+1,A0‡A0=START�OF�FAB/ŠBSETW‚#FAFLSB,FATFLG(A4)�INDICATE�DB�ALLOCATED(GETI30„MOVE.L�A0,FATFAA(A4)†START�OF�FAB ŠCLR.W‚D2ŠMOVE.B�FCBDIR+DIRFAB(A2),D2ŠMULUƒ#SECSZE,D2 ŠSUB.L‚#1,D2 ŠADD.L‚D2,A0 ŠMOVE.L�A0,FATFAE(A4)†END�OF�FAB&ŠMOVE.L�FMSSEG,FATBSN(A4)‚SEGMENT�NAME'*NOW MAKE SEGMENT PERMANET AND SHARABLEŠLEA„SEGBLK2,A0*ŠMOVE.L�FMSSEG,SEGNAM(A0)‚GET�SEGMENT�NAME)ŠMOVE.W�#SGOPSP,SEGOPT(A0)�MAKE�PERMANENT4ŠMOVE.W�#SGATSS,SEGATT(A0)�INDICATE�SESSION�SHARABLE&ŠBTSTW‚#6,D3ŽSHOULD�SEGMENT�BE�GLOBAL?ŠBEQ.S‚GETI35�NOŠMOVE.W�#SGATGS,SEGATT(A0)�YES$*MAKE SEGMENT PERMANENT AND SHARABLEGETI35„ERQ.DCLSHR�(A0)ŠBEQ„GETRTN�SUCCESSFUL#ŠCMP.B‚#RTCDDPRQ,D0‡DUPLICATE�NAME?ŠBEQ.S‚GETI40�YESŠBSR.S‚RELIOB�RELEASE�SEGMENT-ŠCMP.B‚#RTCDTFUL,D0‡GLOBAL�SYMBOL�TABLE�FULL?$‰BEQ.S…GETI50�YES-TREAT�AS�NO�MEMORY$ŠBRA„GETER1�MUST�BE�UNEXPECTED�ERROR'*GOT DUPLICATE NAME WHEN MADE PERMANENT#GETI40„BSR.S‚RELIOB�RELEASE�SEGMENTŠBRA„GETI05�GO�TRY�AGAINGETI45:‰PUT_ADDR‚*,SYSPACE*œSET�DIAGNOSTIC.*¡INSUFFICIENT�SPACE�TO�OBTAIN�DATA�BUFFER/FAB ‰BRA‡GETER2 GETI50:‰PUT_ADDR‚*,SYSPACE*œSET�DIAGNOSTIC**¡TRIED�TO�MAKE�SEGMENT�ALLOCATED�GLOBALLY'*¡SHARABLE�BUT�GLOBAL�SYMBOL�TABLE�FULL ‰BRA‡GETER2ŠPAGE* *RELIOB 1.00 10/9/79 L.STEINHOFF*&*RELIOB DE-ALLOCATES AN FMS I/O BUFFER* *ON CALL:*…A4=FAT�ADDRESS2*…FATBSN=SEGMENT�NAME�(=0�IF�NO�SEGMENT�ALLOCATED)* *ON RETURN:.*…POSSIBLE�ERRORS�FROM�DESEG�IGNORED�(COULD�BE0*‡ATTEMPT�TO�DE-ATTACH�FROM�NON-ATTACHED�SEGMENT *…FATBSN=0*…SEGNAM=0�IN�SEGBLK2*$*RELIOB USES SEGBLK2 PARAMETER BLOCK**INDENTED LIST,* RELIOB DEALLOCATES A SEGMENT FOR FILE DATA*RELIOB* SEGMENT EXIT? *‚NO,RETURN(*‚YES,ATTACH�TO-SEG.IF�NECESSARY�$ATTIOB*ƒDEALLOCATE�SEGMENT�.DESEG*INDENTED LIST END RELIOB„EQU„*ŠMOVEM.L�D0/A0,-(A7)ŠLEA„SEGBLK2,A0ŠMOVE.L�FATBSN(A4),D0#ŠBEQ.S‚RELRTN�NO�SEGMENT�TO�RELEASE/ŠBSR.S‚ATTIOB�MAKE�SURE�ATTACHED�TO�SEGMENT�1ST4*SET BIT IN OPTIONS FIELD TO REMOVE PERMANENT STATUSŠMOVE.W�#SGOPRP,SEGOPT(A0)'ŠCLR.L‚FATBSN(A4)‰0�SEGMENT�NAME�IN�FATŠERQ.DESEG�(A0).ŠCLR.L‚SEGNAM(A0)‰INDICATE�NO�SEGMENT�ATTACHEDRELRTN„MOVEM.L�(A7)+,A0/D0ŠRTSŠPAGE*"*ATTIOB 1.00 10/12/79 L. STEINHOFF*4*ATTIOB ATTACHES FMS TO AN I/O BUFFER IF IT OWNS ONE1*…IF�SEGMENT�IS�ALREADY�ATTACHED,�NOTHING�IS�DONE9*…IF�DIFFERENT�SEGMENT�IS�ATTACHED,�IT�IS�DE-ATTACHED�1ST* *ON CALL:*…A4=FAT�ADDRESS!*…FATBSN=SEGMENT�NAME�(0�IF�NONE)* *ON RETURN:*…A4=UNCHANGED)*…SEGNAM�IN�SEGBLK2=ATTACHED�SEGMENT�NAME*+*ATTIOB GOES TO FMSFTL IF ERROR FROM ATTSEG*$*ATTIOB USES SEGBLK2 PARAMETER BLOCK**INDENTED LIST** ATTIOB ATTACHES FMS TO FILE DATA SEGMENT*ATTIOB* SEGMENT ALREADY ATTACHED? *‚YES,RETURN%*‚NO,DEATTACH�EXISTING�SEGMENT�.DESEG*ƒATTACH�SEGMENT�.ATTSEG*INDENTED LIST END* ATTIOB„EQU„*ŠMOVEM.L�A0/D0,-(A7)ŠLEA„SEGBLK2,A0ŠMOVE.L�FATBSN(A4),D0ŠBEQ.S‚ATTIRT�NO�SEGMENTŠCMP.L‚SEGNAM(A0),D0ŠBEQ.S‚ATTIRT�ALREADY�ATTACHEDŠCLR.W‚SEGOPT(A0)-ŠTST.L‚SEGNAM(A0)‰DIFFERENT�SEGMENT�ATTACHED?ŠBEQ.S‚ATTI05�NO%*YES-MUST DE-ATTACH OTHER SEGMENT 1STŠERQ.DESEG�(A0)4ATTI05„MOVE.L�FATBSN(A4),SEGNAM(A0)�GET�SEGMENT�NAME5ŠMOVE.W�#SGATSS,SEGATT(A0)�SET�UP�AS�SESSION�SHARABLE*ŠBTSTW‚#FOPABFB,FATASN(A4)�SHARED�SEGMENT?ŠBEQ.S‚ATTI10�NO8ŠMOVE.W�#SGATGS,SEGATT(A0)�YES-SEG.�IS�GLOBALLY�SHARABLE!*SET LOGICAL ADDR.=PHYSICAL ADDR. ATTI10„MOVE.W�#SGOPPA,SEGOPT(A0)ŠERQ.ATTSEG�(A0)*…A0=LOGICAL�ADDR.ŠBSR„FTL.NE�FATAL�ERROR" ATTIRT„MOVEM.L�(A7)+,A0/D0ŠRTS*B*ATTIOBO ATTACHES TEMPORARILY TO OTHER SEGMENT TO DO DATA TRANSFER*…FROM�FAB�OR�DATA�BLOCK ATTIOBOƒEQU„*ŠMOVEM.L�A0/D0,-(A7)ŠLEA„SEGBLKO,A0 ŠBRA.S‚ATTI05ŠPAGEŠENDCƒFMSLEVEL-1*"*CHKASN 1.00 10/12/79 L. STEINHOFF*?*CHKASN DETERMINES TYPE OF ASSIGNMENT AND SETS FLAG ACCORDINGLY* *ON CALL:*…A2=FCB�ADDR. *…BSR�CHKASN* *ON RETURN:/*…CONDITION�CODE�SET�ACCORDING�TO�VALUE�IN�D5.W$*…D5.W�(MSB)=-1�IF�CONTIGUOUS/VOLUME *�0�IF�OTHER*…D5.B=-1�IF�VOLUME�ASSIGNEMTN*‰=FILE�TYPE�OTHERWISE* CHKASN„EQU„*ŠMOVE.W�#-1,D58*GOES TO FMSFTL IF UNEXPECTED ERROR FROM ASSIGN OR CLOSE*ŠCMP.B‚#'�',FCBDIR+DIRFIL(A2)�VOLUME�ASSN?ŠBEQ.S‚CHKASN4ŒYESŠMOVE.B�FCBDIR+DIRATT(A2),D5"ŠAND.B‚#DFTBIT,D5‰RETURN�FILE�TYPEŠCMP.B‚#DATCON,D5‰CONTIGUOUS?ŠBEQ.S‚CHKASN4ŒYES'*ZERO HIGH BYTE FOR NON=CONTIGUOUS FILEŠAND.W‚#$FF,D5CHKASN4ƒTST.W‚D5ŠRTSŠPAGE*!*CALREC 1.00 10/23/79 L.STEINHOFF*5*CALREC DETERMINES IF I/O REQUEST IS FOR NEXT, PRIOR,-*…CURRENT�OR�RANDOM�AND�ADJUSTS�CLS/CLR�VALUE*…PASSED�ACCORDINGLY* *ON CALL:*…A2=FCB�ADDR.*…A4=FAT�ADDR.*…D1=CLS�OR�CLR�VALUE,*…D2=AMOUNT�TO�ADD�TO�GET�TO�NEXT�BLOCK/REC. *…BSR�CALREC* *ON RETURN:*…CARRY=0�IF�NO�ERROR*Š=1�IF�INVALID�FUNCTION*…D1=UPDATED�VALUE*…ALL�OTHER�REGISTERS�UNCHANGED***INDENTED LIST,* CALREC DETERMINES NEW VALUE FOR CLR OR CLS*CALREC* CURRENT REQUEST?"*‚YES,1ST�I/O-OR�LAST-REQ.�DELETE?*ƒYES,MAKE�ERROR�RETURN*ƒNO,KEEP�CURRENT�POINTER*‚NO,NEXT�REQUEST?*ƒYES,LAST�REQUEST�DELETE?*„YES,KEEP�CURRENT�POINTER*„NO,UPDATE�POINTER�FOR-NEXT*ƒNO,�PREVIOUS�REQUEST?*„YES,AT�BEGINNING?*…YES,ERROR�RETURN*…NO,POINTER�=POINTER�MINUS-1*„NO,RANDOM�RECORD�REQUEST*…POSITION�REQUEST�FOR�MINUS-1?*†YES,�POINTER=�LOG.�EOR*†NO,�POINTER�=RRN*INDENTED LIST END* CALREC„EQU„*ŠMOVEM.L�D0,-(A7)ŠMOVE.W�FATIOS+IOSOPT(A4),D0ŠAND.W‚#IOPPOS,D0"ŠCMP.W‚#IOPCUR,D0‰CURRENT�REQUEST? ŠBNE.S‚CALR10#*YES-DON'T ALLOW IF THIS IS 1ST I/O*…OR�LAST�I/O�WAS�DELETEŠBTSTW‚#FAFLLB,FATFLG(A4)ŠBNE.S‚CALRER�LAST�WAS�DELETEŠBTSTW‚#FAFLBB,FATFLG(A4)ŠBNE.S‚CALGRT�NOT�1ST�I/OŠBTSTW‚#FAFLRB,FATFLG(A4)ŠBNE.S‚CALGRT�NOT�1ST�I/O#*INVALID FUNCTION-MAKE ERROR RETURNCALRER„OR.Bƒ#1,SRCALRTN„MOVEM.L�(A7)+,D0ŠRTS%CALGRT„AND.B‚#$FE,SRŒMAKE�GOOD�RETURN ŠBRA.S‚CALRTN%CALR10„CMP.W‚#IOPNXT,D0‰NEXT�REQUEST?ŠBNE.S‚CALR20�NO.*YES-SET RECORD POSITION AHEAD BASED ON NO. OF,*…BLOCKS/�RECORD�TRANSFERRED�ON�LAST�REQUEST9*IF LAST REQUEST WAS DELETE, CLR ALREADY POINTING AT NEXTŠBTSTW‚#FAFLLB,FATFLG(A4) ŠBNE.S‚CALGRT ŠADD.L‚D2,D1 ŠBRA.S‚CALGRT)CALR20„CMP.W‚#IOPPRV,D0‰PREVIOUS�REQUEST?ŠBNE.S‚CALR30�NO*YES-DON'T ALLOW IF D1=0 OR -1 ŠTST.L‚D1ŠBEQ.S‚CALRER�MAKE�ERROR�RETURN ŠCMP.L‚#-1,D1 ŠBEQ.S‚CALRER$ŠSUB.L‚#1,D1ŽSUBTRACT�1�FROM�CLS/CLR ŠBRA.S‚CALGRT5CALR30„MOVE.L�FATIOS+IOSRRN(A4),D1�RANDOM�RECORD�REQ.3*IF FUNCTION IS POSITION AND RRN=-1 AND RECORD I/O, *…PICK�UP�EOR ŠCMP.W‚#IOPOST,FATIOS+IOSFCT(A4)ŠBNE.S‚CALGRT�NOT�POSITION ŠCMP.L‚#-1,D1ŠBNE.S‚CALGRT�NOT�-1�RRN!ŠBTSTW‚#IOPRECB,FATIOS+IOSOPT(A4)ŠBNE.S‚CALGRT�BLOCK�I/O$ŠMOVE.L�FCBDIR+DIREOR(A2),D1�GET�EOR ŠBRA.S‚CALGRTŠPAGEŠIFGTƒFMSLEVEL-1*!*UPDEOF 1.00 11/7/79 L. STEINHOFF*2*UPDEOF INCREMENTS/DECREMENTS NO. OF SECTORS INFO.*…ASSOCIATED�WITH�FILE�AND�FAB* *ON CALL:*…A2=FCB�ADDR.*…A4=FAT�ADDR.*…FATSBS=START�OF�DATA�BUFFER+*…FATSBL=POINTER�TO�LAST�DATA�BYTE�IN�BLOCK *…BSR�UPDEOF* *ON RETURN:*…A2,A4=UNCHANGED(*…D0.W=REMAINDER�FROM�SECTOR�CALCULATION$*ˆ(=0�IF�SBL�FALLS�AT�END�OF�SECTOR),*…Z=1�IF�EXACTLY�FILLS�SECTOR�(NO�REMAINDER)"*†=0�IF�PARTIAL�SECTOR�(REMAINDER)*…DIREOF=DIREOF+N*…FATLLS=FATLLS+N*…FABSGS=FABSGS+N'*‡WHERE�N=NEW�CALCULATED�NO.�OF�SECTORS.*�OLD�NO.�OF�SECTORS�IN�USE�(OLD�FABSGS�VALUE)0*…FAB�AND�FCB�CHANGED�FLAGS�SET�IF�INFO.�CHANGED**INDENTED LIST&* UPDEOF UPDATES SECTOR INFO. FOR FILE*UPDEOF*‚GET�SECTORS�IN-USE�$CALSEC*‚GET�CHANGE�I" N-SECTORS�IN-USE*‚UPDATE�DIREOF,�FATLLS,�FABSGS*INDENTED LIST END* UPDEOF„EQU„*ŠMOVEM.L�D1-D2/A3,-(SP) ŠBSR.S‚CALSECŠMOVE.L�FATCFP(A4),A3 ŠCLR.L‚D2>ŠMOVE.B�FABSGS(A3),D2†D1=NEW�NO.�OF�SECTORS-OLD�NO.�OF�SECTORS ŠSUB.L‚D2,D1ŠBEQ.S‚UPDE20�NO�CHANGEŠADD.L‚D1,FCBDIR+DIREOF(A2)ŠADD.L‚D1,FATLLS(A4)ŠADD.B‚D1,FABSGS(A3)<ŠBSETW‚#FCFLDB,FCBFLG(A2)�INDICATE�DIR.�INFO.�IN�FCB�CHANGED ŠBSR„FABCHG�INDICATE�FAB�CHANGEDUPDE20„MOVEM.L�(A7)+,D1-D2/A3#ŠTST.W‚D0‘SET�CC�BASED�ON�REMAINDERŠRTSŠPAGE*!*UPDEOR 1.00 11/7/79 L. WTEINHOFF*,*UPDEOR INCREMENTS/DECREMENTS NO. OF RECORDS$*…INFO.�ASSOCIATED�WITH�FILE�AND�FAB* *ON CALL:*…A2=FCB�ADDR.*…A4=FAT�ADDR.*…D0.L=1�IF�INCREMENT*‰=-1�IF�DECREMENT *…BSR�UPDEOR* *ON RETURN:*…ALL�REGISTERS�UNCHANGED*…DIREOR=DIREOR+1�(-1)*…FATLLR=FATLLR+1�(-1)*…FABREC=FABREC+1�(-1)'*…FAB�CHANGED�AND�FCB�CHANGED�FLAGS�SET* UPDEOR„EQU„*ŠADD.L‚D0,FCBDIR+DIREOR(A2)ŠADD.L‚D0,FATLLR(A4)ŠMOVE.L�A3,-(SP)ŠMOVE.L�FATCFP(A4),A3ŠADD.W‚D0,FABREC(A3)ŠMOVE.L�(SP)+,A3<ŠBSETW‚#FCFLDB,FCBFLG(A2)�INDICATE�DIR.�INFO.�IN�FCB�CHANGED ŠBSR„FABCHG�INDICATE�FAB�CHANGEDŠRTSŠPAGE*!*CALSEC 1.00 11/8/79 L. STEINHOFF*(*CALSEC CALCULATES NO. OF SECTORS IN USE* *ON CALL:*…A4=FAT�ADDR.*…FATSBS=START�OF�BUFFER'*…FATSBL=POINTER�TO�LAST�BYTE�IN�BUFFER *…BSR�CALSEC* *ON RETURN:*…D1=NO.�OF�SECTORS�IN�USE(*…D0.W=REMAINDER�FROM�SECTOR�CALCULATION* CALSEC„EQU„*ŠMOVE.L�FATSBL(A4),D1ŠSUB.L‚FATSBS(A4),D1ŠADD.L‚#1,D1ŽGET�NO.�OF�BYTES#ŠDIVUƒ#SECSZE,D1‰GET�NO.�OF�SECTORS/*IF THERE IS A REMAINDER, ADD 1 TO SECTOR COUNT!ŠSWAPƒD1‘REMAINDER�IN�LOW�16�BITSŠMOVE.W�D1,D0ŽD0.W=REMAINDER ŠCLR.W‚D1ŠSWAPƒD1‘D1.L=NO.�OF�SECTORS ŠTST.W‚D0ŠBEQ.S‚CALS10�NO�REMAINDER(ŠADD.L‚#1,D1ŽD1.L=CORRECT�NO.�OF�SECTORS CALS10„RTSŠPAGEŠIFEQƒFMSLEVEL-3*"*MVEKEY 1.00 11/20/79 L. STEINHOFF*5*MVEKEY MOVES KEY FROM USER BUFFER TO TEMPOARY BUFFER*…PASSED* *ON CALL:*…A0=ADDR.�OF�TEMPORARY�BUFFER*…A2=FCB�ADDR.*…A4=FAT�ADDR.#*…FATRSB=ADDR�OF�USER�RECORD�BUFFER *…BSR�MVEKEY* *ON RETURN:*…Z=1�IF�NO�ERROR�ON�L-L�MOVE *†=0�IF�ERROR!*…D0=ERROR�STATUS�SET�FROM�MOVELL*…D2.L=NO.�OF�BYTES�MOVED*…A2,A4=UNCHANGED *…A0=STARTING�ADDR.�OF�MOVED�KEY* MVEKEY„EQU„* ŠCLR.L‚D0ŠMOVE.L�A0,MOVBLK+MVDADDŠBSR„DMOVEŽSET�UP�L-L�MOVE ŠCLR.L‚D2ŠMOVE.B�FCBDIR+DIRKEY(A2),D2ŠBEQ.S‚MVEK10�SKIP�IF�NULL�KEY7ŠMOVE.L�D2,MVLENG(A0)†PUT�KEY�LENGTH�IN�PARAMETER�BLOCK$ŠMOVE.L�FATIOS+IOSSAD(A4),MVSADD(A0)ŠERQ.MOVELL�(A0)%ŠMOVE.L�MVDADD(A0),A0†A0=ADDR.�OF�KEY ŠTST.L‚D0 MVEK10„RTSŠPAGE*"*CMPKEY 1.00 12/16/79 L. STEINHOFF*(*CMPKEY COMPARES RECORD KEYS AND RETURNS$*…AN�INDICATOR�OF�EQUAL�OR�NOT�EQUAL* *ON CALL:*…A0=POINTER�TO�KEY9*…A1=START�OF�RECORD�WHICH�INCLUDES�BYTE�COUNT�IF�PRESENT*…A2=FCB�ADDR.*…D2=KEY�LENGTH*…DIRLRL=DIR.�RECORD�LENGTH *…BSR�CMPKEY* *ON RETURN: *…A0=ALTERED*…A1=UNCHANGED*…A2=UNCHANGED *…D2=ALTERED<*…CONDITION�CODE�SET�ACCORDING�TO�COMPARE�VALUE�OF�LAST�BYTE*ŠOF�KEY‚A0:A1* CMPKEY„EQU„*ŠMOVE.L�A1,-(A7)ŠTST.B‚D2‘NULL�KEYSŠBEQ.S‚CMPK17�YES,�SKIP�CALLŠTST.W‚FCBDIR+DIRLRL(A2)‚VRL?ŠBNE.S‚CMPK15�NO*ŠADD.L‚#BCTFLD,A1‰YES-SKIP�OVER�BYTE�COUNT)CMPK15„CMPM.B�(A0)+,(A1)+ˆCHECK�FOR�MATCH ŠBNE.S‚CMPKRTŠDCNTƒD2,CMPK15*KEYS MATCH-MAKE GOOD RETURNCMPK17„CLR.L‚D0CMPKRT„MOVE.L�(A7)+,A1ŠRTSŠPAGEŠENDCƒFMSLEVEL-3*"*MVEREC 1.00 11/21/79 L. STEINHOFF*7*MVEREC MOVES USER RECORD TO DATA BLOCK OR TEMP. BUFFER*3*BEFORE CALLING MVEREC, DATA BLOCK HAS BEEN CHECKED3*…TO�GUARANTEE�SUFFICIENT�ROOM�IN�DB�FOR�RECORD�AND*…BYTE�COUNT�(IF�VRL)+*IF MOVING TO TEMP. BUFFER, ALREADY CHECKED/*…THAT�DATA�FITS�IN�TEMP.�BUFFER�W/O�BYTE�COUNT* *ON CALL:/*…A1=START�OF�AVAILABLE�SPACE�BEYOND�BYTE�COUNT*…A2=FCB�ADDR.*…A4=FAT�ADDR.*…D4=USER�RECORD�LENGTH)*‡(INCLUDES�OPTIONS�WORD�IF�SPOOLER�FILE)$*…FATIOS+IOSSAD=START�OF�USER�RECORD *…BSR�MVEREC* *ON RETURN:*…Z=1�IF�NO�ERROR*†=0�IF�ERRO# R�FROM�L-L�MOVE*…D0=STATUS�FROM�MOVELL*…D4=UNCHANGED6*…A1=LAST�BYTE�OF�RECORD�(NOT�ADJUSTED�FOR�EVEN�BYTES) *ˆIF�ODD)*…A2=FCB�ADDR.*…A4=FAT�ADDR.* MVEREC„EQU„*ŠMOVE.L�A0,-(A7)ŠBSR„DMOVEŽSET�UP�L-L�MOVEŠMOVE.L�D4,MVLENG(A0)$ŠMOVE.L�FATIOS+IOSSAD(A4),MVSADD(A0)ŠMOVE.L�A1,MVDADD(A0).ŠCMP.B‚#SPOOLF,FCBDIR+DIRFIL(A2)�SPOOLER�FILE?ŠBNE.S‚MVER10�NO;*YES-PUT OPTIONS FIELD IN RECORD AND ADJUST DATA BYTE COUNTŠMOVE.W�FATIOS+IOSOPT(A4),(A1).ŠSUB.L‚#2,MVLENG(A0)†ADJUST�LENGTH�FOR�OPTIONS3ŠADD.L‚#2,MVDADD(A0)†ADJUST�DEST.�ADDR.�FOR�OPTIONS MVER10„EQU„*ŠERQ.MOVELL�(A0) ŠBNE.S‚MVERRT$*UPDATE A1 TO POINT TO END OF RECORD)ŠADD.L‚D4,A1ŽPOINT�1�BEYOND�END�OF�RECORD'ŠSUB.L‚#1,A1ŽPOINT�TO�LAST�BYTE�OF�DATAMVERRT„MOVE.L�(A7)+,A0ŠRTS„CONDITIONŠCODE�NOT�CHANGEDŠPAGE*!*MVEDTA 1.00 1/18/80 L. STEINHOFF***MVEDTA MOVES USER'S RECORD TO DATA BLOCK,*…EITHER�DIRECTLY�OR�THROUGH<*…TEMP.�BUFFER�IF�SPACE�COMPRESSION�AND�TEMP.�BUFFER�ALTERED&*BEFORE CALLING MVEDTA, DATA BLOCK HAS1*…BEEN�CHECKED�TO�GUARANTEE�SUFFICIENT�ROOM�IN�DB"*…FOR�RECORD�AND�BYTE�COUNT�IF�VRL* *ON CALL:+*…A1=START�OF�AVAILABEL�SPACE�IN�DATA�BLOCK*…A2=FCB�ADDR.*…A4=FAT�ADDR.*…D4=COMPRESSED�RECORD�LENGTH+*‡(INDLUDES�2�BYTES�FOR�OPTIONS�IF�SPOOLER)*…D7=ACTUAL�USER�RECORD�LENGTH*‰D4=D7�IF�NO�SPACE�COMPRESSION%*…FATIOS+IOSSAD=STARTO�OF�USER�RECORD*…DIRLRL=FILE�RECORD�LENGTH *…BSR�MVEDTA* *ON RETURN:*…Z=1�IF�NO�ERROR*†=0�IF�ERROR�FROM�L-L�MOVE*…D0=STATUS�FROM�MOVE.LL *…D4=UNCHGNED*…D7=UNCHANGED0*…A1=END�OF�RECORD�(A�ZERO�BYTE�WAS�ADDED�TO�END*ˆOF�RECORD�IF�ODD)*…A2=FCB�ADDR.*…A4=FAT�ADDR."*…A5=START�OF�RECORD�IN�DATA�BLOCK*‡(BEYOND�BYTE�COUNT�IF�PRESET)#*…FAFLDB�SET�TO�INDICATE�DB�CHANGED*3* NOTE: CAN'T HAVE SPACE COMPRESION IF SPOOLER FILE**INDENTED LIST** MVEDTA MOVES USER'S RECORD TO DATA BLOCK*MVEDTA* VARIABLE LENGTH RECORD?*‚YES,SAVE�BYTE-COUNT* COMPRESS SPACES?&*‚NO,MOVE�RECORD-TO�DATA-BLOCK�$MVEREC$*‚YES,MOVE�DATA-TO�TEMP.BUF.�$MVEREC#*ƒCOMPRESS�SPACES,MVE�TO-DB�$CMPSPC* ADJUST FOR-ODD BYTE-COUNT*INDENTED LIST END* MVEDTA„EQU„*ŠMOVEM.L�A0/D4/D7,-(A7)ŠTST.W‚FCBDIR+DIRLRL(A2)‚VRL?ŠBNE.S‚MVED10�NO'ŠMOVE.W�D4,(A1)+‹YES-MOVE�IN�BYTE�COUNT MVED10„EQU„*"ŠMOVE.L�A1,A5ŽSAVE�START�OF�RECORDŠCMP.L‚D4,D7ŽSPACE�COMPRESSION?ŠBNE.S‚MVED25�YES=*RECORD IS NOT COMPRESSED-OKAY TO MOVE DIRECTLY TO DATA BLOCK ŠBSR„MVERECŠBNE.S‚MVED17�ERROR�ON�L-L�MOVE$MVED15„BSR„DBCHGŽINDICATE�DB�CHANGED7*ADJUST END OF RECORD POINTER IF NECESSARY FOR ODD BYTE *…A1�POINTS�TO�LAST�BYTE�OF�DATA ŠMOVE.L�A1,D0 ŠBTSTW‚#0,D0)ŠBNE.S‚MVED16�EVEN�NO.�OF�BYTES�IN�RECORD(ŠADD.L‚#1,A1ŽODD�NO.�OF�BYTES-ADD�0�BYTE ŠCLR.B‚(A1) MVED16„EQU„* ŠCLR.L‚D0MVED17„MOVEM.L�(A7)+,A0/D4/D7ŠRTS>*SET UP TO MOVE RECORD TO TEMP. BUFFER AND THEN SPACE COMPRESS&MVED25„EXG„D4,D7ŽD4=USER�RECORD�LENGTH+ŠBTSTW‚#VDFLTB,VDTFLG(A6)�RECORD�DESTROYED?ŠBEQ.S‚MVED28�NOŠMOVE.L�VDTTMA(A6),A1 ŠBSR„MVEREC ŠBNE.S‚MVED17MVED28„MOVE.L�VDTTMA(A6),A0 ŠMOVE.L�A5,A1 ŠMOVE.L�#1,D04ŠBSR„CMPSPC�COMPRESSES�SPACES�AND�MOVE�TO�DATA�BLOCK ŠBRA.S‚MVED15ŠPAGEŠENDCƒFMSLEVEL-1*/*SETBEG SETS FILE POINTERS AT BEGINNING OF FILE* *ON CALL:*…A4=FAT�ADDRESS *…BSR�SETBEG* *ON RETURN:*…D0=1 *…FATCLS=-1 *…FATCLR=-1 *…FATBCT=1 *…FATCFP=0* SETBEG„EQU„*ŠMOVE.L�#-1,D0ŠMOVE.L�D0,FATCLS(A4)ŠMOVE.L�D0,FATCLR(A4) ŠNEG.L‚D0ŠMOVE.L�D0,FATBCT(A4)ŠCLR.L‚FATCFP(A4)ŠRTSŠPAGE*"*FMSASN 1.00 12/12/79 L. STEINHOFF#*‡1.01�6/21/83‚M.�BRIEL¥6/24/83�MLB:*•Added�code�to�control�the�Write�Protect�flag�6/24/83�MLB5*•in�the�DCB�for�disk�devices�that�do�not†6/24/83�MLB7*•generate�a�status�change�event.�A�new�bit„6/24/83�MLB9*•was�also�defined�in�the�VDTFLG�field�of�the‚6/24/83�MLB4*•the�VDT�entry�for�the�device.�This�bit‡6/24/83�MLB8*•says�that�the�disk�is�not�writable�(thoughƒ6/24/83�MLB9*•not�necessarily�write�protected).‚FMSASN�is�6/24/83�MLB8*•called�to�assign�the# �device,�read�sector�0ƒ6/24/83�MLB7*•of�the�disk,�and�determine�if�sector�zero„6/24/83�MLB7*•contains�a�VERSADOS�Volume�Identification„6/24/83�MLB8*•Block.�If�the�subroutine�returns�either�noƒ6/24/83�MLB8*•error�or�an�Invalid�Volume�error,�sector�0ƒ6/24/83�MLB9*•was�readable�so�an�attempt�is�made�to�write‚6/24/83�MLB:*•sector�zero�back�to�the�disk�as�read.�If�any�6/24/83�MLB5*•error�occurs,�the�VDFLNW�bit�of�the�VDT†6/24/83�MLB7*•flags�is�set�to�indicate�that�the�disk�is„6/24/83�MLB6*•not�writable.�If�the�error�returned�is�a…6/24/83�MLB9*•Write�Protect�error,�the�write�protect�flag‚6/24/83�MLB4*•of�the�DCB�flags�(DFLGWP)�is�also�set.‡6/24/83�MLB9*•VDFLNW�and�DFLGSC�are�both�cleared�prior�to‚6/24/83�MLB*•calling�FMSASN.ž6/24/83�MLB2*•Once�the�VID�has�been�read�correctly,�the�DCB�is/*•flagged�to�indicate�disk�not�write�protected.*•(DFLGWP�cleared).** S. C. BALL 9/23/83E*ƒAdded�code�to�configure�disk�after�reading�VID.‚This�will�enable�usB*…boot�the�system�with�diskettes�in�the�drives.‚FMS�will�mount�theE*…diskettes�and�issue�a�configure�directive�to�configure�the�disketteH*…according�to�the�configuration�information�that�has�been�written�there>*…by�INIT�instead�of�the�default�sysgen�value�for�that�device.*.*FMSASN ASSIGNS DISK DEVICE TO FMS IF POSSIBLE1*…IF�VOLUME�ID�IS�NOT�VALID,�ASSIGNMENT�IS�CLOSED* *ON CALL:*…A6=VDT�ADDR. *…BSR�FMSASN* *ON RETURN:*…A6=UNCHANGED#*GOES TO FMSFTL IF UNEXPECTED ERROR**INDENTED LIST#* FMSASN ASSIGNS DISK DEVICE TO FMS*FMSASN* ATTEMP EREW ASSN.TO DISK-.FHS* CLEAR STATUS CHANGED FLAG *�Clear�VDFLNW‚flag®6/24/83�MLB** GET VOLUME-ID $GETVID&*�Could�Sector�0�be�read?ª6/24/83�MLB*N*‚Yes,�attempt�to�write�VID�back�to�disk.�If�any�error�occurs,�set�the�VDFLNW*F*†flag�in�the�VDT�entry�so�FMS�will�not�attempt�to�write�access�date…*E*†information�to�the�disk.�If�the�specific�error�returned�was�Write†*1*†Protect,�also�set�the�DFLGWP�flag�in�the�DCB.š**�Valid�Volume�ID?¼*J*‚Yes,�indicate�that�there�are�no�disk�structures�currently�in�memory�by…**†calling�subroutine�ZERPTR.­*A*‚No,‚close�the�device�assignment�via�a�call�to�FHS.�6/24/83�MLB**INDENTED LIST END**‡FHS�PARAMETER�BLOCK�(FMSASN)**‰----------------------*ƒ0…*‡FHSCMD‡*‡COMMAND*‰----------------------*ƒ2…*‡FHSOPT‡*‡OPTIONS*‰----------------------*‰*”**‰----------------------*ƒ6…*‡FHSVOL‡*‡VOLUME�NAME*‰*…(4�BYTES)†**‰----------------------*‰*”**‰----------------------*ƒ30„*‡FHSGEN‡*‡RESERVED*‰----------------------* FMSASN„EQU„*&ŠMOVEM.L�A0-A2/D0-D2,-(A7) 6/24/83�MLB*SET UP TO ASSIGN DEVICEŠLEA„FMSBLK1,A0+ŠMOVE.B�VDTIOS+IOSLUN(A6),FHSLUN(A0)�GET�LU!ŠMOVE.W�#FHASGN,FHSCMD(A0)�ASSIGN+ŠMOVE.W�#FOPEREW,FHSOPT(A0)�EXC.�READ/WRITE$ŠCLR.W‚FHSGEN(A0)‰ZERO�RESERVED�DATA#ŠMOVE.L�VDTDCB(A6),A2†GET�DCB�ADDR.-ŠMOVE.L�DCBAID(A2),FHSVOL(A0)�GET�DEVICE�CODEŠLEA„FHSCLG(A0),A1$ŠMOVE.W�#(CLGLEN+FILLEN+EXTLEN)/2,D0-FMSA10„MOVE.W�#'‚',(A1)+ˆSPACE-FILL�FILE�NAMEŠDCNTƒD0,FMSA10 ŠFHSCALL�(A0)ŠBEQ.S‚FMSA15�NO�ERROR*ŠCMP.B‚#FSTAAP,D0‰ASSIGNED�BY�SOMEONE�ELSEŠBEQ.S‚FMSA30�YES,ŠCMP.B‚#FSTAAS,D0‰FMS�ALREADY�HAVE�ASSIGNED?ŠBSR„FTL.NE�NO(*CLEAR DEVICE STATUS CHANGED FLAG IN DCB$***********************¬6/24/83�MLB*J*DON'T�NEED�SEMAPHORE�SINCE�ONLY�READ-MODIFY-WRITE�INSTRUCTIONS�ARE�USED†************************·*:FMSA15„BCLRW‚#DFLGSC,DCBFLG(A2)‚Clear�the�status�change.‘*=ŠBCLRW‚#DFLGWP,DCBFLG(A2)‚Flags�DCB�disk�not�write�protected.;ŠBCLRW‚#VDFLNW,VDTFLG(A6)�writable�flag�in�the�VDT�entry.‹*ŠSPC„2±6/24/83�MLB** * S.C.B. vvvvM* Generate a mask to clear all bits in the attributes and parameters that areH*ƒnot�media�related,�are�unmodifiable�values,�return�only�values,�or�are,*ƒvalues�related�to�the�physical�disk�drive. 9MSKUNATM‚EQU„1<�THEN.S*C*‹We�had�a�good�read�of�VID�and�the�volume�is�VERSAdos�recognizable:*‹Go�try�to�write�out�VID�setting�appropriate�not�writable/*‹(VDFLNW)�and/or�write�protect�(DFLGWP)�flags.ŒBSR.S�FMSAGWŒGo�write�VIDŒBSR.S�FMSADCŒGo�do�configureŒIF��THEN.S*ŽBSRƒZERPTRŠGo�indicate�no�table�in�memoryŒELSE.S!ŽBSR.L�FMSACAŠGo�close�assignmentŒENDIŠELSE.S B*‹We�had�a�bad�read�of�VID�or�the�read�was�good�but�we�do�not�have!*‹a�VERSAdos�recognizable�volume.ŒIF.B�D0��#FSTAVOL�THEN.S<*�We�had�an�unrecognizable�volume�-�go�write�out�VID�setting=*�appropriate�not�writable�(VDFLNW)�or�write�protect�(DFLGWP)*�flags."ŽBSR.S�FMSAGWŠGo�write�out�the�VIDŒELSE.S9*�We�had�an�error�other�than�a�volume�error�(probably�was(*�an�I/O�error).‚Go�dismount�the�device. *�assignment. ŽBSR.L�FMSADMŠGo�dismount�deviceŒENDI1*‹Close�the�assignment�for�any�error�from�GETVID.%ŒBSR.L�FMSACAŒGo�close�the�assignmentŠENDI FMSA30„MOVEM.L�(A7)+,A0-A2/D0-D2ŠRTS H* Routine to write VID back and set VDFLNW if the disk is unwritable and,*ƒset�DFLGWP�if�the�disk�is�write�protected.*.FMSAGW„MOVE.L�#VIDDA,D0ŠSector�number�to�write'ŠMOVE.L�#IOWRIT,D1‰I/O�function�(write)ŠBSR„GPTSEC�Go�do�the�I/OŠIF��THEN.S7ŒBSETW�#VDFLNW,VDTFLG(A6)�Set�not-writable�flag�in�VDT.ŒIF.B�D0��#ISTAWP�THEN.S8ŽBSETW�#DFLGWP,DCBFLG(A2)�Set�write-protect�flag�in�DCB.ŒELSE.S:ŽBCLRW�#DFLGWP,DCBFLG(A2)�Clear�write-protect�flag�in�DCB.ŒENDIŠELSE.S:ŒBCLRW�#VDFLNW,VDTFLG(A6)�Clear�not-writeable�flag�in�VDT.:ŒBCLRW�#DFLGWP,DCBFLG(A2)�Clear�write-protect�flag�in�DCB.ŠENDIŠRTS‰PAGE* Routine to do configure.(*‚VID�assumed�to�be�in�temporary�buffer.H*‚On�exit,�D0�contains�status�code,�contition�codes�reflect�D0�contents.*‚Status�of�0�=�good.*‰Mounting�madness:<*‰In�the�IOS�parameter�block�on�a�type�0180�call�(configure)1*‹the�options�bits�take�on�the�following�meaning:*�All�bits�zero‰-�Mount*�Bit�12�setŒ-�Dismount(*�Other�than�bit�12�set�-�Configure�only**FMSADC: *%*‰Issue�configuration/status�request.*6ŠMOVE.W�#IOSTAT,VDTIOS+IOSFCT(A6)�Configuration/status/ŠMOVE.L�VDTTMA(A6),A1†Temporary�buffer�address.4ŠMOVE.L�VIDCAS(A1),D1†Save�address�of�config�sector.>ŠMOVE.L�A1,VDTIOS+IOSDBP(A6)�Status�comes�back�in�temp�buffer.ŠIOSCALL�VDTIOS(A6)*A- ŠIF��THENŒMOVE.L�IOSATM(A1),D2*5*‹We�had�a�good�status�back�from�configuration/status%*‹Save�attributes�and�parameters�mask**B-$ŒIF.B�IOSDTP(A1)��#XDSRDK�THEN.S *#*�We�have�a�valid�device�type�code.**C-$ŽIF.B�IOSCTP(A1)��#XTDIPC�THEN.S *�We�have�an�IPC�type�device.:*�IPC�type�devices�need�no�configuratrion�-�treat�as�good.* �CLR.L�D0ŽELSE.S*-C �TST.L‚D1*D-�IF��THEN.S -*‘A�configuration�sector�exists�on�this�disk.<*‘Issue�mount�request�to�the�driver.‚Set�both�the�attributes<*‘and�parameters�masks�to�zero�to�prevent�any�of�the�current<*‘configuration�data�from�being�changed.‚The�mount�option�is;*‘set�(all�bits�zero)�to�cause�the�driver�to�put�the�device7*‘on-line�and�to�allow�I/O�requests�to�be�processed.‚No+*‘error�should�be�returned�on�this�request.*’CLR.L‚IOSATM(A1)$*�Clear�attributes�&�parameters�mask.’MOVE.L�#(IOCNFG<<16)+IOPMNT,VDTIOS+IOSFCT(A6)’IOSCALL�VDTIOS(A6)/*œIssue�mount�request�via�configure�mumbo�jumbo ’BSR„FTL.NE*œKill�it�if�error�occurs*E-’IF��THEN.S *(*“We�have�successfully�mounted�the�disk.7*“Read�the�configuration�parameter�block�into�temporary *“buffer.* ”MOVE.L�D1,D0&*œD0�=�Address�of�configuration�sector”MOVE.L�#IOREAD,D1*œD1�=�Read�function!”BSR„GPTSEC…Go�DOIO�-�Destroys�A1"*œRead�in�the�configuration�sector*F-”IF��THEN.S 4*•We�have�successfully�read�the�configuration�sector*•into�memory.5*•Configure�the�device.‚Force�to�zero�all�bits�in�the5*•attributes�and�parameters�mask�of�the�new�configure7*•parame$ ter�block�that�do�not�correspond�to�values�that7*•describe�the�media.‚The�values�that�correspond�to�the *•zeroed�bits�will�be�unchanged.*;*•If�the�disk�is�a�hard�disk�the�default�configuration�will7*•be�modified�also�to�reflect�the�configuration�request*–MOVE.L�VDTTMA(A6),A1#*œA1�=�Address�of�temporary�buffer.–MOVE.L�D2,IOSATM(A1)#*œPlug�mask�from�config�status�call O*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>11/28/84>>*O*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<�THEN.S*—MOVE.L�#MSKDRIV,D1*•ELSE.S*—MOVE.L�#$FFFFF,D1*•ENDIO*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>FAM 9/18/84>>>>>>>>>*•AND.L‚D1,IOSATM(A1)2*•MOVE.L�A1,VDTIOS+IOSDBP(A6)�Point�to�config�P.B.1*•MOVE.L�#(IOCNFG<<16)+IOPCONLY,VDTIOS+IOSFCT(A6) ”MOVE.LƒA1,VDTIOS+IOSDBP(A6)4*œEstablish�address�of�configuration�parameter�block *œin�IOCB”MOVE.Lƒ#MSKDRIV,D11*œD1�=�Configuration�mask�to�use�for�floppy�drive"*¡We�will�assume�media�is�a�floppy”BTSTW„#IOARDISC,IOSATW(A1)4*œEdit�to�see�if�this�is�a�floppy�or�hard�disk�media*G-”IF��THEN.S *šWe�have�a�hard�disk.*œEstablish�configuration�mask�for�a�hard�disk-*œChange�the�hard�disk�configuration�defaults*›MOVE.L†#$FFFFF,D1›AND.L‡D1,IOSATM(A1)3*œEstablish�configuration�mask�to�use�for�hard�disk'›MOVE.L†#(IOCHDC<<16),VDTIOS+IOSFCT(A6)2*œEstablish�the�function�code�to�a�change�defaults›IOSCALL…VDTIOS(A6)*¦Change�the�hard�disk�default*¦configuration”ENDI*-G *H-”IF��THEN.S *šWe�have�a�floppy�disk*œOR**šWe�have�successfully�changed�the�default *œconfiguration�of�the�hard�disk*3*™Now�we�will�configure�the�media�we�are�processing*–AND.L‡D1,IOSATM(A1)-*œEstablish�the�configuration�mask�to�use�for*œthe�configuration�request0–MOVE.L�#(IOCNFG<<16)+IOPCONLY,VDTIOS+IOSFCT(A6)2*œEstablish�the�I/O�call�for�configuration�request–IOSCALL�VDTIOS(A6)!*œIssue�the�configuration�request*”ENDI*-HO*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<11/28/84<< ”ENDI*-F’ENDI*-E�ELSE.S*-D8*‘We�don't�have�any�configuration�sector�-�return�a�good4*“status�since�this�may�be�an�IPC�disk�that�was�made5*“before�configuration�sectors�existed.‚11/16/84�SCB.*‘MOVE.L�#3,D0’CLR.L‚D0 11/16/84�SCB.�ENDI*-DŽENDI*-CŒELSE.S*-B%*�We�had�an�invalid�device�type�code. ŽMOVE.L�#2,D0ŒENDI*-BŠENDI*-A(ŠTST.L‚D0‘Set�condition�codes�for�returnŠRTS (* Routine to do configure with dismount.G*ƒIssue�a�configure�request�with�dismount�option�(bit�other�than�12�setH*ƒin�IOS�options�field)�and�zeros�in�the�attributes�and�parameters�mask.J*ƒThis�will�not�change�any�configuration�data�but�will�cause�the�driver�toD*ƒreject�all�further�I/O�requests�on�the�device�until�configure�withD*ƒthe�mount�option�is�ussued.‚No�error�should�occur�on�this�request.*2FMSADM„MOVE.L�VDTTMA(A6),A0†Address�of�temp�buffer:ŠMOVE.L�A0,VDTIOS+IOSDBP(A6)�Use�temp�buffer�as�dummy�loc./ŠMOVE.L�#(IOCNFG<<16)+IOPDMNT,VDTIOS+IOSFCT(A6)6ŠCLR.L‚IOSATM(A0)‰Clear�attributes�and�parameters�maskŠIOSCALL�VDTIOS(A6)ŠRTS (* Routine to close assignment to device.*FMSACA„LEA„FMSBLK1(PC),A0(ŠMOVE.W�#FHCLOS,FHSCMD(A0)�Close�command8ŠMOVE.B�VDTIOS+IOSLUN(A6),FHSLUN(A0)�Logical�unit�number(ŠCLR.W‚FHSGEN(A0)‰Zero�out�reserved�byteŠTRAPƒ#3#ŠBSR„FTL.NE�Abort�if�error�in�closeŠRTS * S.C.B. ^^^^ŠPAGE*"*ZERPTR 1.00 12/20/79 L. STEINHOFF*?*ZERPTR ZEROES POINTERS IN VDT TO INDICATE NO SAT, SDB, AND PDB *„IN�MEMORY* *ON CALL:*…A6=VDT�ADDR. *…BSR�ZERPTR* *ON RETURN:*…ALL�REGISTERS�UNCHANGED* ZERPTR„EQU„*ŠCLR.L‚VDTSMB(A6)‰0�SAT�PSN ŠCLR.L‚VDTDMB(A6)‰0�PRIM.�DB�PSNŠCLR.L‚VDTSDB(A6)‰0�SEC.�DB�PSN *Â6/24/83�MLBCŠAND.W‚#1<DON'T�MOVE�DATA/MOVE�DATA*…D4=USER�RECORD�LENGTH *…FCBDIR+DIRKEY=KEY�FIELD�LENGTH *…BSR�CMPSPC* *ON RETURN: *…A0=CHANGED6*…A1=END�OF�RECORD�IF�MOVED�(DOES�NOT�ADD�BYTE�IF�ODD)*…A2=UNCHANGED *…D4=UNCHGNED*…D7=COMPRESS�BYTE�COUNT**INDENTED LIST3* CMPSPC DETERMINES SPACE COMPRESSED SIZE OF RECORD*CMPSPC* GET-DATA BYTE-OF RECORD* BYTE-IN KEY?*‚NO,BYTE�A-SPACE?*ƒYES,COUNT�CONSECUTIVE�SPACES!* ADJUST COMPRESSED RECORD LENGTH* MOVE DATA BYTE?*‚YES,MOVE�DATA-TO�DATA-BLOCK* GO-GET NEXT-BYTE IF-ANY*INDENTED LIST END* CMPSPC„EQU„*ŠMOVEM.L�D1-D4,-(A7)$ŠCLR.L‚D7‘ZERO�COMPRESSED�BYTE�COUNT ŠMOVE.L�D4,D2ŽSAVE�RECORD�LENGHT ŠCLR.L‚D3,ŠMOVE.B�FCBDIR+DIRKEY(A2),D3�SAVE�KEY�LENGTH$CMPS05„MOVE.B�(A0)+,D1‹GET�DATA�BYTE ŠSUB.L‚#1,D2(*DON'T TRY TO COMPRESS IF BYTE IS IN KEY ŠCMP.L‚D3,D7%ŠBCS.S‚CMPS10�KEY�BYTE-DON'T�COMPRESSŠCMP.B‚#'�',D1ŠBEQ.S‚CMPS30�SPACE�FOUND*NOT A SPACE-ADJUST COUNTS*CMPS10„ADD.L‚#1,D7ŽCOMPRESSED�RECORD�COUNT ŠTST.B‚D0ŠBEQ.S‚CMPS15�DON'T�MOVE�BYTEŠMOVE.B�D1,(A1)+CMPS15„TST.L‚D2‘DONE? ŠBNE.S‚CMPS05'*ALL DATA CHECK - SEE IF DATA WAS MOVED ŠTST.B‚D0ŠBEQ.S‚CMPS25�DATA�NOT�MOVED'ŠSUB.L‚#1,A1ŽPOINT�TO�LAST�BYTE�OF�DATACMPS25„MOVEM.L�(A7)+,D1-D4ŠRTS,*SPACE FOUND-COMPRESS ALL CONSECUTIVE SPACESCMPS30„CLR.B‚D4‘0�NO.�OF�SPACESCMPS32„ADD.B‚#1,D4%ŠCMP.B‚#$7F,D4ŒMAX.�NO.�OF�SPACES=$7F ŠBNE.S‚CMPS40!*MUST WRITE OUT SPACE COMPRESSIONCMPS33„ADD.L‚#1,D7 ŠTST.B‚D0 ŠBEQ.S‚CMPS15 ŠBSETW‚#7,D4ŠMOVE.B�D4,(A1)+ ŠBRA.S‚CMPS15CMPS40„TST.L‚D2)ŠBEQ.S‚CMPS33�AT�END-WRITE�OUT�LAST�SPACEŠMOVE.B�(A0)+,D1 ŠSUB.L‚#1,D2ŠCMP.B‚#'�',D1ŠBEQ.S‚CMPS32�ANOTHER�SPACE% $ŠTST.B‚-(A0)ŽPOINT�BACK�TO�NON-SPACE ŠADD.L‚#1,D2ŠBRA.S‚CMPS33�OUTPUT�SPACESŠPAGEŠENDCƒFMSLEVEL-1* *CHKWC 1.00 2/11/80 L. STEINHOFF**#*CHKWC CHECKS TO MAKE SURE IF WRITE"*…ACCESS�IS�REQUESTED,�IT�IS�VALID* *ON CALL:*…D1.W=TASK�USER�NO.*…D2.W=WRITE�TYPE�(FROM�CHKAP)*…A2=FCB�ADDR.*…A4=FAT�ADDR.4*…A5=ADDR.�OF�FHS�BLOCK�(USER�NO,�WRITE�CODE�PASSED)*…A6=VDT�AADDR.* *ON RETURN:*…Z=1�IF�PROTECT�CODE�OKAY*†=0�IF�PROTECT�CODE�ERROR*…D0.B=0�IF�NO�ERROR*ŠFSTAPC�IF�PROTECT�CODE�ERROR*…OTHER�REGISTERS�UNCHANGED*INDENTED LIST(* CHKWC MAKES SURE WRITE ACCESS IS VALID*CHKWC* WRITE ACCESS PERM.?*‚NO,MAKE�GOOD�RETURN&*‚YES,MAKE�SURE-VALID�USER-NO.�$USNCHK*ƒWRITE�CODE=0? *„YES,RETURN*„NO,MAKE�SURE�CODES�MATCH*INDENTED LIST END**‡FHS�PARAMETER�BLOCK�(CHKWC)**‰----------------------*‰*”**‰----------------------$*ƒ32„*‚FHSWCD‚*‰*‡WRITE�PROTECT�CODE*‰----------------------** CHKWC…EQU„* ŠTST.W‚D2)ŠBEQ.S‚CHKWGRTŒWRITE�ACCESS�NOT�REQUESTED@*USER SHOULD BE ABLE TO WRITE INTO FILES HE WAS ABLE TO ALLOCATE ŠBSR„USNCHK!ŠBNE.S‚CHKWERTŒPROTECT�CODE�ERROR*CHECK WRITE CODEŠMOVE.B�FCBDIR+DIRWCD(A2),D0#ŠBEQ.S‚CHKWGRTŒ0�MATCHES�EVERYTHING7*ALLOW ASSIGNMENT EVEN IF FILE IS WRITE PROTECTED ($FF)**…SO�AS�TO�ALLOW�USER�TO�CHANGE�PROTECTIONŠCMP.B‚FHSWCD(A5),D0!ŠBNE.S‚CHKWERTŒPROTECT�CODE�ERRORCHKWGRTƒCLR.L‚D0ŠRTSCHKWERTƒMOVE.L�#FSTAPC,D0ŠRTSŠPAGE* *CHKRC 1.00 2/11/80 L. STEINHOFF*)*CHKRC CHECKS TO MAKE SURE IF READ ACCESS*…IS�REQUESTEED,�IT'S�VALID* *ON CALL:*…D1.W=TASK�USER�NO.*…D2.W=READ�TYPE�(FROM�CHKAP)*…A2=FCB�ADDR.*…A4=FAT�ADDR.4*…A5=ADDR.�OF�FHS�BLOCK�(USER�NO.,�READ�CODE�PASSED)*…A6=VDT�ADDR. *ON RETURN:*…Z=1�IF�PROTECT�CODE�OKAY*…=0�IF�PROTECT�CODE�ERROR*…D0.B=0�IF�NO�ERROR*ŠFSTAPC�IS�PROTECT�CODE�ERROR*…OTHER�REGISTERS�UNCHANGED**INDENTED LIST'* CHKRC MAKES SURE READ ACCESS IS VALID*CHKRC* READ ACCESS PERM.?*‚NO,MAKE�GOOD�RETURN*‚YES,FILE�OWNER-OR�SUPERVISOR?*ƒYES,MAKE�GOOD�RETURN*ƒNO,TASK�USER-NO.=�VOLUME?*„YES,FILE�USER-NO.=�0?*…YES,MAKE�GOOD�RETURN* FILE READ CODE=0? *‚YES,OKAY*‚NO,READ�CODE=�MINUS-1?*ƒYES,�PROTECT�CODE�ERROR*ƒNO,READ�CODES�MATCH? *„YES,�OKAY*„NO,PROTECT�CODE�ERROR*INDENTED LIST END**‡FHS�PARAMETER�BLOCK�(CHKRC)**‰----------------------*‰*”**‰----------------------*ƒ10„*‡FHSUSN‡*‡USER�NUMBER*‰----------------------*‰*”**‰----------------------$*ƒ32„*Š*‚FHSRCD�*‡WRITE�PROTECT�CODE*‰----------------------* CHKRC…EQU„* ŠTST.W‚D2'ŠBEQ.S‚CHKWGRTŒREAD�ACCES�NOT�REQUESTED@*IF USER IS FILE OWNER OR SUPERVISOR, NO NEED TO MATCH READ CODE ŠTST.W‚D1ŠBEQ.S‚CHKWGRTŒTASK�USER�NO.=0ŠCMP.W‚FHSUSN(A5),D1*ŠBEQ.S‚CHKWGRTŒTASK�USER�NO.=FILE�USER�NO.7*IF TASK USER NO,,=VOLUME USER NO. AND FILE USER NO.=0.*…NO�NEED�TO�MATCHŠCMP.W‚VDTVID+VIDUSN(A6),D1ŠBNE.S‚CHKR10�MUST�MATCHŠTST.W‚FHSUSN(A5)ŠBEQ.S‚CHKWGRTŒNO�NEED�TO�MATCH*READ CODE SHOULD BE CHECKED"CHKR10„MOVE.B�FCBDIR+DIRRCD(A2),D0#ŠBEQ.S‚CHKWGRTŒ0�MATCHES�EVERYTHING ŠCMP.B‚#-1,D0%ŠBEQ.S‚CHKWERTŒFILE�IS�READ�PROTECTEDŠCMP.B‚FHSRCD(A5),D0&ŠBNE.S‚CHKWERTŒREAD�CODE�DOESN'T�MATCHŠBRA.S‚CHKWGRTŠPAGE**GETLUT WAITS FOR LUT SEMPAHORE* *ON CALL: *…BSR�GETLUT* *ON RETURN:*…A0=ADDR.�OF�IOSG *„D0=ALTERED* GETLUT„EQU„*ŠMOVE.L�IOCOMS,A0ŠTAS„SVTSLUT(A0)ŠBNE.S‚GETLU2�LOCKED ŠRTS„OKAYGETLU2„ERQ.RELINQ ŠBRA.S‚GETLUTŠPAGE**GETDCQ WAITS FOR DCQ SEMAPHORE* *ON CALL: *…BSR�GETDCQ* *ON RETURN:*…A0=ADDR.�OF�IOSG *„D0=ALTERED* GETDCQ„EQU„*ŠMOVE.L�IOCOMS,A0ŠTAS„SVTSDCQ(A0)ŠBNE.S‚GETDC2�LOCKED ŠRTS„OKAYGETDC2„ERQ.RELINQ ŠBRA.S‚GETDCQŠPAGE* *GETFCBS WAITS FOR FCB SEMAPHORE* *ON CALL: *‚BSR�GETFCBS* *ON RETURN:*…A0=ADDR.�OF�IOSG *…D0=ALTERED GETFCBSƒEQU„*ŠMOVE.L�IOCOMS,A0ŠTAS„SVTSFCB(A0)ŠBNE.S‚GETFCA�LOCKED ŠRTS„OKAYGETFCA„ERQ.RELINQŠBRA.S‚GETFCBSŠPAGE *ACKREQ 1.00 4/1/80 L. STEINHOFF*& )*ACKREQ SENDS ACKNOWLEDGE REQUEST TO USER-*…SETTING�CONDITION�CODE�BASED�ON�VALUE�IN�D1* *ON CALL:"*…D1.L=STATUS�TO�BE�RETURNED�IN�D0*…D2.L=USER�TASK*…D3.L=USER�SESSION*…D4.B=TRAP�NO. *…BSR�ACKREQ* *ON RETURN:*…A0,D0,�AND�D1�ALTERED3*…ACKREQ�GOES�TO�FMSFTL�IF�ERROR�RETURN�FROM�AKRQST ACKREQ„EQU„*ŠLEA„ACKBLK,A0ŠMOVE.L�D2,ACKTSK(A0)ŠMOVE.L�D3,ACKSES(A0)CŠMOVE.W�#AKOPSC+AKOPRT+AKOPSD,ACKOPT(A0)�SET�CC�AND�D0,�RESUME�TASKŠMOVE.B�D4,ACKTIN(A0)8*IF ERROR OCCURRED, MOVE TRAP NO. INTO D0 VALUE RETURNED ŠTST.L‚D1 ŠBNE.S‚ACKR05(ŠMOVE.B�#4,ACKCCD(A0)†Z=1�SINCE�NO�ERROR ŠBRA.S‚ACKR10 ACKR05„EQU„*!ŠCLR.B‚ACKCCD(A0)‰Z=0�SINCE�ERRORŠSWAPƒD1"ŠMOVE.B�D4,D1ŽGET�TRAP�NO.�OF�CALLŠASL.W‚#8,D1ŽMOVE�TO�BITS�11-14 ŠASL.W‚#3,D1ŠSWAPƒD1-ACKR10„MOVE.L�D1,ACKRD0(A0)†RETURNED�D0�VALUEŠERQ.AKRQST�(A0) ŠBSR„FTL.NEŠRTSŠPAGE!*CHKWPD 1.00 4/23/80 L. STEINHOFF*0*CHKWPD CHECKS TO SEE IF DISK IS WRITE PROTECTED* *ON CALL:*…A6=VDT�ADDR. *…BSR�CHKWPD* *ON RETURN:*…Z=1�IF�NOT�WRITE�PROTECTED*†=0�IF�WRITE�PROTECTED*…D0.L=0�IF�NOT�WRITE�PROTECTED!*‰=ISTAWP�IF�WRITE�PROTECTED�DISK* CHKWPD„EQU„*ŠMOVE.L�A0,-(A7) ŠCLR.L‚D0ŠMOVE.L�VDTDCB(A6),A0*ŠBTSTW‚#DFLGWP,DCBFLG(A0)�WRITE�PROTECTED?ŠBEQ.S‚CHKWPRTŠMOVE.L�#ISTAWP+NL,D0†YESCHKWPRTƒMOVE.L�(A7)+,A0ŠRTSŠPAGE*!*CHKPRM 1.00 L. STEINHOFF 4/23/80*0*CHKPRM CHECKS FILE NAME PARAMETERS FOR ALLOCATE6*…AND�DELETE�REQUESTS.‚ALSO�RETURNS�DEFAULT�VOLUEM�AND7*…USER�NO.�IF�NECESSARY�AND�MAKES�SURE�DISK�ISN'T�WRITE *…PROTECTED* *ON CALL:*…A5=ADDR.�OF�USER�FHS�BLOCK*…FMSASQ+EVTUNM=TASK�USER�NO.(*…FMSASQ+EVTRA0=USER'S�PARM.�BLOCK�ADDR./*…FMSASQ+EVTTSK/EVTSES=USER�TASK/SESSION�NUMBER *…BSR�CHKPRM* *ON RETURN:*…Z=1�IF�NO�ERROR *†=0�IF�ERROR*…D0.B=0�IF�NO�ERROR*‰=ERROR�CODE�OTHERWISE *…A6=VDT�ADDR.�(=0�IF�ANY�ERROR)1*…D1,D2�AND�A0�AATERED�SO�AS�TO�KEEP�COMMON�STACK*‡USAGE�AS�LOW�AS�POSSIBLE$*GOES TO FMSFTL IF ERROR ON L-L MOVE***INDENTED LIST$* CHKPRM CHECKS FILE NAME PARAMETERS*CHKPRM&* CHECK-USER NO.,VOLUME, AND-FILE NAME*‚$VALUSN,�$VALVOL,�$VALFNM'* MAKE-SURE DISK-NOT WRITE-PROT $CHKWPD!* MAKE-SURE OWNER-OF FILE $USNCHK* DEFAULT VOLUME-OR USER-NO.?#*‚YES,RETURN�VALUES-TO�USER�$MOVE2U*INDENTED LIST END**‡FHS�PARAMETER�BLOCK�(CHKPRM)**‰----------------------*‰*”**‰----------------------*ƒ6…*‡FHSVOL‡*‡VOLUME�NAME*‰*…(4�BYTES)†**‰----------------------*ƒ10„*‡FHSUSN‡*‡USER�NUMBER*‰----------------------* CHKPRM„EQU„*ŠMOVE.L�A1,-(A7)(*SEE IF DEFAULT USER OR VOLUME SPECIFIED ŠCLR.L‚D2ŠCMP.W‚#-1,FHSUSN(A5)ŠBEQ.S‚CHKPR10ŠCMP.L‚#'„',FHSVOL(A5)ŠBNE.S‚CHKPR15$CHKPR10ƒMOVE.L�#1,D2ŽDEFAULT�ENTERED!CHKPR15ƒBSR„VALUSN�CHECK�USER�NO. ŠBNE.S‚CHKPRRTŒMAKE�ERROR�RETURN"ŠBSR„VALVOL�CHECK�FOR�VALID�VOLUMEŠBNE.S‚CHKPRRTŒINVALID�VOLUME*…A6=VDT�ADDR.ŠBSR„VALFNM�CHECK�FILE�NAME ŠBNE.S‚CHKPRRTŒINVALID�FILE�NAME!ŠBSR„CHKWPD�WRITE�PROTECTED�DISK?ŠBNE.S‚CHKPRRTŒYES-ERROR+*MAKE SURE FILE IS OWNED BY USER OR TASK IS*…SUPERVISOR�OR�FILE�USER�NO.=0*…ON�OWNER'S�VOLUME*ŠMOVE.W�FMSASQ+EVTUNM,D1ƒGET�TASK�USER�NO. ŠBSR„USNCHK!ŠBNE.S‚CHKPRRTŒPROTECT�CODE�ERROR+*NOW UPDATE DEFAULT PARAMETERS IF NECESSARY ŠTST.L‚D2ŠBEQ.S‚CHKPGRTŒNO�DEFAULT ŠBSR.S‚SMOVEAŠLEA„FHSVOL(A5),A1ŠMOVE.L�A1,MVSADD(A0)ŠMOVE.L�FMSASQ+EVTRA0,A1ŠLEA„FHSVOL(A1),A1ŠMOVE.L�A1,MVDADD(A0)!ŠMOVE.L�#VOLLEN+USNLEN,MVLENG(A0) ŠBSR„MOVE2UŠBEQ.S‚CHKPGRT,ŠMOVE.L�#FSTAIP,D0‰INVALID�PARM.�BLOCK�ADDR.$CHKPRRTƒSUB.L‚A6,A6ŽA6=0�SINCE�ERRORCHKPGRTƒMOVE.L�(A7)+,A1ŠRTSŠPAGE*!*SMOVE4 1.00 L. STEINHOFF 4/28/80*7*SMOVE4 SETS UP L-L BLOCK TO MOVE FROM FMS TO USER AREA* *ON CALL:*…A4=FAT�ADDR.*…FATTSK,�FATSES�SETUP *…BSR�SMOVE4* *ON RETURN:%*…A0=ADDR.�OF�L-L�MOVE�BLOCK�(MOVBLK))*…SOURCE�AND�DEST.�TASK/SESSION�FILLED�IN* SMOVE4„EQU„*ŠLEA„MOVBLK,A0ŠMOVE.L�FATTSK(A4),MVDTSK(A0)ŠMOVE.L�FATSES(A4),MVDSES(A0)SMOVE40ƒCLR.L‚MVSTSK(A0)ŠRTSŠPAGE*& !*SMOVEA 1.00 4/28/80 L. STEINHOFF*9*SMOVEA IS LIKE SMOVE4 EXCEPT THAT TASK/SESSION IS PICKED *…UP�FROM�ASQ* *ON CALL:*…FMSASQ+EVTTSK=USER�TASK*…FMSASQ+EVTSES=USER�SESSION *…BSR�SMOVEA* SMOVEA„EQU„*ŠLEA„MOVBLK,A0 ŠMOVE.L�FMSASQ+EVTTSK,MVDTSK(A0) ŠMOVE.L�FMSASQ+EVTSES,MVDSES(A0)ŠBRA.S‚SMOVE40ŠPAGE* *DMOVE 1.00 4/28/80 L. STEINHOFF*6*DMOVE SETS UP L-L BLOCK TO MOVE FROM USER TO FMS AREA* *ON CALL:*„A4=FAT�ADDR.*…FATTSK�AND�FATSES�SETUP *„BSR�DMOVE* *ON RETURN%*„A0=ADDR.�OF�L-L�MOVE�BLOCK�(MOVBLK))*…SOURCE�AND�DEST.�TASK/SESSION�FILLED�IN* DMOVE…EQU„*ŠLEA„MOVBLK,A0ŠMOVE.L�FATTSK(A4),MVSTSK(A0)ŠMOVE.L�FATSES(A4),MVSSES(A0)ŠCLR.L‚MVDTSK(A0)ŠRTSŠPAGE* *SUASQ 1.00 5/19/80 L. STEINHOFF*8*SUASQ MOVES INFO. FROM DCQ TO ASQ AND DELETES DCQ ENTRY:*…DCQ�SEMAPHORE�IS�LOCKED�AT�BEGINNING�AND�UNLOCKED�AT�END** *ON CALL:!*…A2=FCB�ADDR.�OR�ADDR.�OF�FHSQUE* *…BSR�SUASQ* *ON RETURN:*…A0=ADDR.�OF�IOSG*…A1=FMSASQ1�ADDR.*…A2=UNCHANGED*…A3,A4,D0�ALTERED***‰FHS�I/O�EVENT�MESSAGE�(EOT)**‰----------------------*‰*”**‰----------------------*ƒ8…*‚EVTKOD‚*‰*‡SUB-CODE*‰----------------------(*ƒ10„*‡EVTLUE‡*‡LOGICAL�UNIT�TABLE�ENTRY*‰*…(4�BYTES)†**‰----------------------"*ƒ14„*‡EVTLUT‡*‡LOGICAL�UNIT�TABLE*‰*…(4�BYTES)†**‰----------------------7*ƒ18„*‚EVTTIN‚*‚EVTPRI�*‡TRAP�INST�#/REQUESTOR�PRIORITY*‰----------------------%*ƒ20„*‡EVTTSK‡*‡REQUESTOR'S�TASK�NAME*‰*…(4�BYTES)†**‰----------------------**ƒ24„*‡EVTSES‡*‡REQUESTOR'S�SESSION�NUMBER*‰*…(4�BYTES)†**‰----------------------*ƒ28„*‡EVTUNM‡*‡USER�NUMBER*‰----------------------*ƒ30„*‡EVTRD0‡*‡REQUESTOR'S�D0*‰----------------------*‰*”**‰----------------------*ƒ38„*Š*‚EVTPSZ�*ˆ/PB�LENGTH*‰----------------------* SUASQ…EQU„*ŠBSR„GETDCQ�LOCK�DCQ�SEM.ŠLEA„FMSASQ1,A1ŠCMP.L‚#FHSQUE,A2‰FHS�QUEUE?ŠBNE.S‚SUAS05�NO*YES-GET DCQ ADDR.ŠMOVE.L�(A2),A3ŠMOVE.L�DCQNXT(A3),D0 ŠBCLRƒ#31,D0$ŠMOVE.B�#FHLEVT,EVTKOD(A1)�FHS�EVENT'ŠMOVE.L�D0,(A2)ŒMASK�OFF�HIGH�ORDER�BIT ŠBRA.S‚SUAS08*DCQ IS HANGING OFF FCBSUAS05„MOVE.L�FCBDCQ(A2),A3ŠMOVE.L�DCQNXT(A3),D0 ŠBCLRƒ#31,D0$ŠMOVE.B�#IOLEVT,EVTKOD(A1)�IOS�EVENTŠMOVE.L�D0,FCBDCQ(A2)SUAS08„BEQ.S‚SUAS10 ŠMOVE.L�D0,A0ŠBSETW‚#15,DCQNXT(A0)*MOVE INFO. TO ASQ FROM DCQ,SUAS10„MOVE.B�DCQPRI(A3),EVTPRI(A1)�PRIORITYŠMOVE.B�DCQTIN(A3),D0"ŠMOVE.L�#IOSESS,EVQSES(A1)�SESSION2*RESET MESSAGE LENGTH FOR POSSIBLE CALL TO SPOOLER!ŠMOVE.B�#EVTLEN+FHSNLN,EVLENG(A1)%ŠMOVE.B�#EVCQUE,EVCODE(A1)�EVENT�CODEŠMOVE.B�D0,EVTTIN(A1)†TRAP�NO.ŠBTSTƒ#EVTNEOT,D0ˆEOT?ŠBEQ.S‚SUAS15�NO%ŠMOVE.L�DCQLUT(A3),EVTTSK(A1)�TASK�ID%ŠMOVE.L�DCQLUE(A3),EVTSES(A1)�SESSION ŠBRA.S‚SUAS25 SUAS15„EQU„*'ŠMOVE.L�DCQLUE(A3),EVTLUE(A1)�LUN�ENTRYŠMOVE.L�DCQLUT(A3),A4ŠMOVE.L�A4,EVTLUT(A1)†LUT�ADDR.&ŠMOVE.W�LUTUNM(A4),EVTUNM(A1)�USER�NO.ŠMOVE.L�LUTTID(A4),D0ŠMOVE.L�LUTSES(A4),D1ŠLEA„MOVBLK,A0$ŠMOVE.L�D0,EVTTSK(A1)†SAVE�USER�TASKŠMOVE.L�D0,MVSTSK(A0)'ŠMOVE.L�D1,EVTSES(A1)†SAVE�USER�SESSIONŠMOVE.L�D1,MVSSES(A0)ŠCLR.L‚MVDTSK(A0)‰MOVE�TO�FMSŠMOVE.L�DCQLAD(A3),A4'ŠMOVE.L�A4,EVTRA0(A1)†PARM.�BLOCK�ADDR."ŠMOVE.L�A4,MVSADD(A0)†SOURCE�ADDR.'ŠMOVE.L�#FMSBLK1,MVDADD(A0)�DEST.�ADDR. ŠCLR.L‚D0(ŠMOVE.B�DCQPLN(A3),D0†PARM.�BLOCK�LENGTHŠMOVE.B�D0,EVTPSZ(A1)ŠMOVE.L�D0,MVLENG(A0)ŠERQ.MOVELL�(A0) ŠBSR„FTL.NE0SUAS25„CLR.L‚DCQDCB(A3)‰INDICATE�DCQ�ENTRY�EMPTYŠMOVE.L�IOCOMS,A0#ŠCLR.B‚SVTSDCQ(A0)ˆRELEASE�DCQ�SEM.ŠRTSŠPAGE**DOIO 1.00 5/20/80 L. STEINHOFF*0*DOIO STARTS UP PROCEED I/O, SAVES REGISTERS AND'*…STACK�POINTER�AND�RESETS�COMMON�STACK** 5 March 1984 - SCB.D*DOIO2 Performs same function as DOIO except that the proceed bit isA*‚not�set.‚We�will�do�an�I/O�and�proceed.‚Stack�will�not�be�resetB*‚we�will�return�to�the�same�point�in�the�code�after�I/O�with�wait *‚is�done* *ON CALL:*…A4=FAT�ADDR.�(=0�IF�NONE)*…A6=VDT�ADDR. *…BSR�DOIO* *ON RETURN:*…D0=ERROR�STATUS*…A0=IOCB�ADDR.*'  DOIO†EQU„*ŠOR.Wƒ#IOPPRO,VDTIOS+IOSOPT(A6)/DOIO2…EQU„*’Alternate�entry�point�for�I/O�wait.ŠIOSCALL�VDTIOS(A6) ŠBNE.S‚DOIO20:ŠBTSTW‚#IOPWATB,VDTIOS+IOSOPT(A6)�Do�we�want�I/O�and�wait?4ŠBEQ.S‚DOIO20�Branch�if�yes�-�return�cause�I/O�done.7ŠMOVEM.L�A1-A5/D1-D7,-(A7)�No�-�I/O�proceed,�save�regs.ŠMOVE.L�A7,VDTSSP(A6)+ŠMOVE.L�SAVESP,A7ŠRESTORE�COMMON�STACK�PTR.ŠBRA„FMSREV�GO�WAIT�FOR�EVENT DOIO20„RTSŠPAGE*"*DEVBSY 1.00 5/23/80 L. DSTEINHOFF*5*DEVBSY�CHECKS�TO�SEE�IF�DEVICE�IS�BUSY.‚IF�IT�IS,�IT:*…DOES�A�WAIT�FOR�EVENT.‚IF�NOT,�DEVICE�IS�SET�BUSY,�STACK7*…MOVED�TO�VDT�AREA�AND�RETURN�ADDR.�MOVED�TO�NEW�STACK*:*NOTE: MUST BE CALLED FROM LEVEL 0 (NOT WITHIN SUBROUTINE)* *ON CALL:*…A6=VDT�ADDR. *…BSR�DEVBSY* *ON RETURN:*…A1=FMSASQ�ADDR.*…A5=FMSBLK�ADDR.*…A2,A4,A6=UNCHANGED *…VDFLBB�SET*…A7=VDT�STACK�AREA*…ALL�OTHER�REGISTERS�ALTERED* DEVBSY„EQU„*&ŠBSETW‚#VDFLBB,VDTFLG(A6)�DEVICE�BUSY?ŠBEQ.S‚DEVB10�NOO*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>FAM 10/3/84>>>>>>>>>*YES-GET EVENT AND RECHECKŠMOVE.Lƒ#GTEVNT,D0ŠTRAP…#1*œGET�THE�EVENT ŠBSR†FMSASR*œPROCESS�THE�EVENT�READ ŠBRA.S„DEVBSYO*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>FAM 10/03/84>>>>>>>>/DEVB10„MOVE.L�(A7)+,VDTSTK(A6)ƒGET�RETURN�ADDR.(ŠMOVE.L�A7,SAVESPŠSAVE�COMMON�STACK�PTR.ŠLEA„VDTSTK(A6),A7ŠLEA„FMSBLK,A5ŠLEA„FMSASQ,A1ŠRTSŠPAGE*!*DEVFRE 1.00 5/27/80 L. STEINHOFF*,*DEVFRE CLEARS DEVICE BUSY FLAG (IF SET) AND*…RESTORES�COMMON�STACK�POINTER*"*NOTE: MUST BE CALLED FROM LEVEL 0* *ON CALL:*…A6=VDT�ADDR.�(=0�IF�NONE) *…BSR�DEVFRE* *ON RETURN:*…A6=UNCHANGED*…VDFLBB�CLEARED#*…A7=RESTORED�COMMON�STACCK�POINTER* DEVFRE„EQU„* ŠCMP.L‚#0,A6 ŠBNE.S‚DEVF10DEVF05„RTS„NO‘VDT�ADDR.DEVF10„BCLRW‚#VDFLBB,VDTFLG(A6)!ŠBEQ.S‚DEVF05�DEVICE�WAS�NOT�BUSY:*SINCE DEVICE WAS BUSY, COMMON STACK PTR. MUST BE RESTORED)ŠMOVE.L�(A7)+,VDTSSP(A6)ƒGET�RETURN�ADDR.+ŠMOVE.L�SAVESP,A7ŠPUT�RETURN�ADDR.�ON�STACKŠMOVE.L�VDTSSP(A6),-(A7)ŠRTSŠPAGE*!*CHKWAP 1.00 6/13/80 L. STEINHOFF*4*…CHKWAP�CHECKS�TO�SEE�IF�WRITE�ACCESS�IS�REQUESTED.2*…IF�IT�IS,�AP�IS�FORCED�TO�EREW�UNLESS�SEQUENTIAL*…FILE* *ON CALL:*…D1.B=ACCESS�PERMISSION*…D5.W=FILE�TYPE *…BSR�CHKWAP* *ON RETURN:*…Z=1�IF�NO�ERROR *†=0�IF�ERROR*…D0.B=0�IF�NO�ERROR*‰=FSTAAP�IF�ACCESS�PERM.�ERROR,*…D1=ACCESS�PERM.�(SET�TO�EREW�IF�NECESSARY)*…D2=READ/WRITE�TYPES*…D5=UNALTERED* CHKWAP„EQU„* ŠBSETƒ#6,D1ŠBSR„CHKAPŽGET�READ/WRITE�TYPESŠBNE.S‚CHKWA30ŒERROR!ŠTST.W‚D2‘WRITE�ACCESS�REQUESTED?ŠBEQ.S‚CHKWA30ŒNOTHING�TO�DO#*IF NOT SEQUENTIAL FILE, FORCE EREWŠCMP.B‚#DATSEQ,D5ŠBLE.S‚CHKWA30ŒSEQUENTIAL******************************+*ALL VOLUME WRITES MUST BE EREW SINCE DON'T'*…WANT�FILE�I/O�IF�VOLUME�BEING�UPDATEDŠMOVE.B�#FOPEREW,D1ˆSET�TO�EREWCHKWA30ƒTST.B‚D0‘SET�COND.�CODEŠRTSŠPAGE* *CHKMA 1.00 6/18/80 L. STEINHOFF*1*CHKMA DEETERMINES IF MORE THAN 1 ASSIGN. TO FILE* *ON CALL:*…A2=FCB�ADDR.*…A4=FAT�ADDR.*…A6=VDT�ADDR. *…BSR�CHKMA* *ON RETURN:*…Z=1�IF�ONE�ASSIGNEMENT*†=0�IF�MORE�THAN�1�ASSIGN.* CHKMA…EQU„*#ŠMOVEM.L�D0-D2,-(A7)‡SAVE�REGISTERSŠMOVE.W�FATASN(A4),D1ŠAND.W‚#FAPBIT,D1 ŠBSETƒ#6,D1ŠBSR„CHKAPŽGET�READ/WRITE�TYPES ŠBSR„FTL.NEŠCMP.W‚FCBWCT(A2),D2$ŠBNE.S‚CHKM10�MORE�THAN�1�ASSIGNMENTŠSWAPƒD2#ŠCMP.W‚FCBRCT(A2),D2†SET�COND.�CODECHKM10„MOVEM.L�(A7)+,D0-D2ŠRTSŠPAGE* *MOVE2U 1.00 7/3/80 L. STEINHOFF**MOVE2U MOVES DATA TO USER AREA* *ON CALL:%*…A0=ADDR.�OF�MOVELL�PARM.�BLOCK�WITH*‰ALL�PARAMETERS�SETUP *…BSR�MOVE2U* *ON RETURN:*…Z=1�IF�NO�ERROR�FROM�L-L *†=0�IF�ERROR*„D0=ERROR�CODE�FROM�MOVELL9*GOES TO FATAL IF ERROR OTHER THAN RTCDADR2 (DEST. BUFFER8*…NOT�IN�USER�SPACE)�OR�RTCDLGCF�(MOVE�FROM�EVEN�TO�ODD)* MOVE2U„EQU„*ŠERQ.MOVELL�(A0)ŠBEQ.S‚MOVE220ŒGOOD�MOVEŠCMP.B‚#RTCDADR2,D0ŠBEQ.S‚MOVE210ŠCMP.B‚#RTCDLGCF,D0 ŠBSR„FTL.NE!MOVE210ƒTST.B‚D0‘SET�CC�FOR�ERROR MOVE220ƒRTSŠPAGE*' :*MOVENAME MOVES FILE NAME FROM FCB TO USER PARAMETER BLOCK* *ON CALL:*…A2=FCB�ADDR.*…A5=FHS�PARAMETER�BLOCK�ADDR.*…A6=VDT�ADDR.*…BSR�MOVENAME** *‡FHS�PARAMETER�BLOCK�(MOVENAME)**‰----------------------*‰*”**‰----------------------*ƒ6…*‡FHSVOL‡*‡VOLUME�NAME*‰*…(4�BYTES)†**‰----------------------*ƒ10„*‡FHSUSN‡*‡USER�NUMBER*‰----------------------*ƒ12„*‡FHSCLG‡*‡CATALOG�NAME*‰*…(8�BYTES)†**‰----------------------*ƒ20„*‡FHSFIL‡*‡FILE�NAME*‰*…(8�BYTES)†**‰----------------------*ƒ28„*‡FHSEXT‡*‡EXTENSION*‰----------------------*MOVENAME2ŠMOVE.L�VDTVID+VIDVOL(A6),FHSVOL(A5)�GET�VOLUME�IDŠBNE.S‚MOVEN10*-*ˆIF�VOLUME�I.D.�=�0�(FOREIGN�DEVICE),�RETURN*ˆDEVICE�NAME�INSTEAD*ŠMOVE.L�A0,-(A7)‹SAVE�A0%ŠMOVE.L�VDTDCB(A6),A0†GET�DCB�POINTER1ŠMOVE.L�DCBAID(A0),FHSVOL(A5)�PUT�ID�IN�FHS�BLOCKŠMOVE.L�(A7)+,A0‹RESTORE�A0 MOVEN10ƒEQU„*$ŠMOVE.W�FCBSDB+SDBUSN(A2),FHSUSN(A5)$ŠMOVE.L�FCBSDB+SDBCLG(A2),FHSCLG(A5)(ŠMOVE.L�FCBSDB+SDBCLG+4(A2),FHSCLG+4(A5)$ŠMOVE.L�FCBDIR+DIRFIL(A2),FHSFIL(A5)(ŠMOVE.L�FCBDIR+DIRFIL+4(A2),FHSFIL+4(A5)$ŠMOVE.W�FCBDIR+DIREXT(A2),FHSEXT(A5)ŠRTSŠPAGE*B*CHKSPL�CHECKS�TO�SEE�IF�REQUEST�IF�FOR�SPOOLER�FILE.‚IT�IS�IS�ANDF*…REQUESTOR�IS�NOT�SPOOLER�TASK,�EVENT�IS�SET�UP�TO�BE�SENT�TO�SPOOLER* *ON CALL:*…A1=FMSASQ�ADDR.*…A2=FCB�ADDR. *…BSR�CHKSPL* *ON RETURN:&*…D0=0�IF�SPOOLER�SHOULD�BE�SENT�EVENT *‡=1�IF�NOT*…Z�SET�ACCORDING�TO�D0* *‰FHS�I/O�EVENT�MESSAGE�(CHKSPL)*‰FHS�I/O�EVENT�MESSAGE�(EOT)**‰----------------------*‰*”**ƒ8…*‚EVTKOD‚*‰*‡SUB-CODE*‰----------------------*‰*”**‰----------------------**ƒ24„*‡EVTSES‡*‡REQUESTOR'S�SESSION�NUMBER*‰*…(4�BYTES)†**‰----------------------*CHKSPLE*IF SPOOLER FILE, EVENT MUST BE QUEUED TO SPOOLER TASK WITH FILE NAME *INCLUDED ŠCMP.B‚#SPOOLF,FCBDIR+DIRFIL(A2)ŠBNE.S‚CHKSPRTŒNOT�SPOOLER�FILE/*DON'T SEND EVENT IF SPOOLER TASK IS DOING CALL,ŠCMP.L‚#IOSESS,EVTSES(A1)�CHECK�SESSION�ONLYŠBEQ.S‚CHKSPRT/*EVENT DOES NOT INCLUDE SENDER TASK/SESSION, SO*…MOVE�START�OF�EVENT�DOWN ŠMOVE.B�EVLENG(A1),D0†GET�LENGTH$ŠSUB.B‚#8,D0ŽADJUST�FOR�TASK/SESSIONŠMOVE.B�D0,EVLENG+8(A1)>ŠMOVE.B�EVCODE(A1),EVCODE+8(A1)�MOVE�CODE�DOWN�8�(D.V.�2/3/81)1ŠMOVE.B�#SPLEVT,EVTKOD(A1)�SET�UP�SPOOLER�SUBCODE ŠCLR.L‚D0ŠRTSCHKSPRTƒMOVE.L�#1,D0ŠRTSŠENDéééééé( =/*=/*†INIT316.AF=/*%=/* Chain file to assemble INIT316.SA=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to INIT316.LS=/*=/IFC \1ƒ=ARG�INIT316.LS=/ENDIF=/*=ASM INIT316.SA,INIT316.RO,\1;R=/*{ Included files are:=/*ƒ9995.&.VME316.EQ=/*}=/*=ENDééééééøŠINCLUDE�9995.&.VME316.EQ ŠSECTION�8*H*‚This�is�the�inline�code�to�initialize�the�VME316�I/O�channel�to�VMEbusJ*‚adapter�board.‚It�was�designed�to�be�included�(not�called)�by�the�INITIO *‚module.*  *init_VME316: proc;  *ˆassert�IORES�to�I/O�channel;*ˆwait�1/2�seconds;*ˆnegate�IORES�to�I/O�channel; *ˆvector_register_0�<==�$50;*ˆvector_register_1�<==�$51;*ˆvector_register_2�<==�$52;*ˆvector_register_3�<==�$53; ?*ˆcontrol_register_0�<==�enable_interrupts�+�interrupt_level_3;@*ˆcontrol_register_1�<==�disable_interrupts�+�interrupt_level_0;?*ˆcontrol_register_2�<==�enable_interrupts�+�interrupt_level_5;@*ˆcontrol_register_3�<==�disable_interrupts�+�interrupt_level_0;  *end init_VME316;ŠPAGE*I*‚First�reset�all�devices�on�the�I/O�channel.‚(This�will�also�disable�any"*‚interrupts�from�the�I/O�channel.*ŠLEA„VME316_EXIT(PC),A0*ŠMOVE.L�A0,-(A7)‹Where�to�go�for�bus�errorAŠMOVE.W�#'BE',-(A7)‚Code�to�tell�exec�we're�testing�for�bus�error 4ŠMOVE.B�#$01,IORES_316…Assert�IORES*�to�I/O�channel. 0ŠMOVE.L�#65101,D0ŠWait�approximately�1/2�second. IORES_LOOP: ŠSUBI.L�#1,D0ŠBNE.S‚IORES_LOOP 4ŠMOVE.B�#$00,IORES_316…Negate�IORES*�to�I/O�channel.  *J*‚Now,�initialize�the�VBIM�to�interrupt�the�VMEbus�on�vectors�as�sysgened.*/ŠMOVE.B�#$50,VBIM_VR0†Vector_reg_0�<==�IOCVEC1;/ŠMOVE.B�#$51,VBIM_VR1†Vector_reg_1�<==�IOCVEC2;/ŠMOVE.B�#$52,VBIM_VR2†Vector_reg_2�<==�IOCVEC3;/ŠMOVE.B�#$53,VBIM_VR3†Vector_reg_3�<==�IOCVEC4; *K*‚Now,�initialize�the�VBIM�control�registers�to�interrupt�the�VMEbus�in�the7*‚non-auto-reset�mode�at�the�interrupt�levels�sysgened.*=ŠMOVE.B�#$10+2,VBIM_CR0�Control_reg_0�<==�enable_interrupts�+*µinterrupt_level;=ŠMOVE.B�#$10+3,VBIM_CR1�Co( ntrol_reg_1�<==�enable_interrupts�+*µinterrupt_level;=ŠMOVE.B�#$10+4,VBIM_CR2�Control_reg_2�<==�enable_interrupts�+*µinterrupt_level;=ŠMOVE.B�#$10+5,VBIM_CR3�Control_reg_3�<==�enable_interrupts�+*µinterrupt_level; D ,ŒADD.L�#6,A7�Bypass�bus�error�stuff�on�stackVME316_EXIT�EQUƒ* B*�Note:‚There�is�no�RTS�at�the�end�of�this�file�because�it�will�be?*Šlinked�with�more�code�(either�600�level�driver�initialization,*Šcode�or�simply�a�module�with�'RTS'�in�it). ŠENDéééééé=/* =/*†IOI.AF=/**=/* Chain file to assemble I/O Initializer=/*:=/* If no output argument is specified for the listing the%=/* chain file will default to IOI.LS=/*=/IFC \1 ƒ=ARG�IOI.LS=/ENDIF=/*=ASM IOI.SA,IOI.RO,\1;RZ=120=/*{ Included files are:=/*ƒ9995.&.TR1.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.EXE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.FME.EQ=/*ƒ9995.&.FMI.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒTEMPLATE.IOI.AI=/*}=/*=ENDéééé) ééEIOI‡IDNTƒ4,0ƒVERSAdos�I/O�Initialization�System�Task�V�4.1�-�09/13/82ŠOPT„CREF***********************************************************************&*�VERSADOS�OPERATING�SYSTEM�-�OEM�RTOS* *—I/O�MODULE**�IOI�I/O�MODULE�INITILIZATION*$*�COPYRIGHTED�1980�BY�MOTOROLA,�INC.*F************************************************************************�PROGRAM�NAME:‚.IOI**�REV.‚1.00‚8/01/79ƒ(JIM�SMITH)D*�REV.‚2.00‚7/28/81ƒ(DICK�VANDERLIN)�-�ADDITION�OF�I/O�WITH�TIME-OUT**�FUNCTION:‚I/O�INITIALIZATION**�CALLING�SEQUENCE:‚EXEC�INIT.*+*�SUPPORT�TABLES:‚CHANNEL�DATA�BLOCKS�(CDB)*’DEVICE�CONTROL�BLOCKS�(DCB)/*ˆCDB's�and�DCB's�are�found�in�IOC.SA,�which�is*ˆassembled�at�SYSGEN�time.*F********************************************************************** **‚Included�equate�files:*ˆTR1 *ˆTR1RTCD*ˆIOE*ˆEXE*ˆNIO*ˆFME*ˆFMI*ˆLV5*ŠNOLISTŠINCLUDE�9995.&.TR1.EQŠINCLUDE�9995.&.TR1RTCD.EQŠINCLUDE�9995.&.IOE.EQŠINCLUDE�9995.&.EXE.EQŠINCLUDE�9995.&.NIO.EQŠINCLUDE�9995.&.FME.EQŠINCLUDE�9995.&.FMI.EQŠINCLUDE�9995.&.LV5.EQŠINCLUDE�9995.&.UTILITY.MCŠLISTŠINCLUDEƒTEMPLATE.IOI.AIŠPAGE*„ASR�ADDRESSES ‰XDEF†KILL‰XDEF†INITROMR ŠXREFƒCCSEGŠXREFƒEETSTARTŠXREFƒFMSIOI01 ŠXREFƒIOCOME ŠXREFƒIOCOMS ŠXREFƒOESIZE ŠXREFƒOSMEND ŠXREFƒOSMTBL ŠXREFƒROMIOI1 **�IOCOMNŽSEGMENT�NAME ŠSECTION�1**ˆPARAMETER�BLOCKS* GSEGPBLK:‰DC.L†0,*œTASK�NAME�=�0�==>�USE�REQUESTING�TASK�NAME‰DC.L†0*œTASK�SESSION�NUMBER ‰DC.W†$2000*œDIRECTIVE�OPTIONS-*�BIT�13�-�LOGICAL�ADDRESS�=�PHYSICAL�ADDRESS‰DC.W†$0*œSEGMENT�ATTRIBUTES ‰DC.B†'DIOI'*œSEGMENT�NAME‰DC.L†$0 *œPHYSICAL�ADDRESS�IF�APPLICABLE‰DC.L†GSEGSIZE*œSEGMENT�BYTE�SIZE‰PAGE **�IOIID�SEGMENT�NAME**'*ˆWALK�CDB�CHAIN�AND�ALLOCATE�ALL�KNOWN%*ˆI/O�CHANNELS.‚START�ALL�OS�MODULES.****‰PAGEINIT: ‰SUB.L…A5,A5 *œA5�=�ZERO‰MOVE.L„#IOCOMS,A63*œA6�=�ADDRESS�OF�I/O�COMMON�DATA�SEGMENT�AT�SYSGENm$K,N4Q<]DfLD*¦TIME ‰BRA‡ROMIOI14*œPERFORM�REQUIRED�FUNCTIONS�IF�THIS�IS�A�ROM�SYSTEM(*¤*�IF�THIS�IS�NOT�A�ROM�BASED�SYSTEM�AN(*¦IMMEDIATE�'BRANCH'�WILL�BE�EXECUTED�TO *¦'INITROMR''*¤*�IF�THIS�IS�A�ROM�BASED�SYSTEM�A�RAM&*¦DATA�SEGMENT�WILL�BE�OBTAINED�--�THE&*¦ADDRESS�OF�THE�RAM�DATA�SEGMENT�WILL*¦BE�RETURNED�IN�REGISTER�A5)*¤*�THE�ROM�DATA�SEGMENT�WILL�BE�MOVED�TO*¦THE�RAM�DATA�SEGMENT**¤*�ADDRESSES�IN�THE�RAM�DATA�SEGMENT�WILL *¦BE�ADJUSTED&*¤*�CONTROL�WILL�THEN�BE�TRANSFERED�TO *¦'INITROMR'**¤*�A�BRANCH�TO�AND�FROM�THE�POTENTIAL�ROM$*¦LOGIC�WAS�USED�BECAUSE�IT�KEPT�RAM*¦FRAGMENTATION)*¦IN�OBTAINING�DATA�SEGMENTS�AT�A�MINIMUM*‰PAGE ****** ****…UPON�RETURN�A5�FROM�ROMIOI1>*****ŽEQUAL�ZERO…WHICH�IMPLIES�THAT�THIS�IS�A�RAM�BASED�SYSTEMA****�EQUAL�NON-ZERO�WHICH�IMPLIES�THAT�THIS�IS�A�ROM�BASED�SYSTEM/***ŸA5�=�ADDRESS�OF�I/O�COMMON�DATA�SEGMENT�FOR**¥RAM�BASED�SYSTEM.* INITROMR:‰LEA‡GSEGPBLK(PC),A0-*œA0�=�ADDRESS�OF�GET�SEGMENT�PARAMETER�BLOCK‰MOVE.L„#GTS) EG,D0*œD0�=�DIRECTIVE�NUMBER‰TRAP†#1*œGET�DATA�SEGMENT�FOR�TASK ‰BNE‡INIT9999*œBRANCH�IF�ERROR�OCCURRED ‰MOVE.L„A0,A3,*œA3�=�ADDRESS�OF�DATA�SEGMENT�FOR�THIS�TASK‰MOVE.L„#GSEGSIZE,D0$*œD0�=�NUMBER�OF�BYTES�FOR�THIS�LOOPINIT02: ‰CLR.B…(A0)+ ‰SUB.L…#1,D0 ‰BNE.S…INIT020*œCLEAR�THE�DATA�SEGMENT�FOR�THIS�TASK�TO�ZERO'S*œBRANCH�IF�NOT�DONE *œINITIALIZE‰LEA‡STACK(A3),A7*œA7�=�TASK�STACK�POINTER‰MOVE.L„#IOCOMS,A03*œA0�=�ADDRESS�OF�I/O�COMMON�DATA�SEGMENT�AT�SYSGEN*¦TIME‰MOVE.L„A5,REGA0(A3) ‰BNE.S…INIT04*œBRANCH�IF�A�ROM�BASED�SYSTEM‰MOVE.L„A0,REGA0(A3))*œA0�=�IMPLIES�WE�HAVE�A�RAM�BASED�SYSTEM2*œREGA0�=�START�ADDRESS�OF�I/O�COMMON�DATA�SEGMENT(*¦IOSG�WHICH�WILL�BE�PASSED�TO�OPERATING*¦SYSTEM�TASKS�AT�STARTUP�TIMEINIT04:‰MOVE.L„REGA0(A3),A6*œA6�=�I/O�COMMON�ADDRESS ‰BSR‡TEMPLATE"*œINITIALIZE�THE�TASK�DATA�SEGMENT,ŠMOVE.L�#CCSEG,A1ŠSET�UP�POINTER�TO�CDB�LISTŠTST.L‚XCDBPTR(A1) ŠBEQ.S‚INIT19*œJMP�IF�THERE�ARE�NO�CDB'S0‰LEA‡ALLBLK(A3),A0‰SET�UP�POINTER�TO�PARAM�BLOCK *D*‚MOVE�DATA�FROM�THE�CHANNEL�DATA�BLOCK�(WITHIN�IOC)�TO�OUR�ALLOCATEB*‚PARAMETER�BLOCK.‚NOTE�THAT�XIOOPT�IS�AN�OLD�EQUATE�FROM�THE�DAYSA*‚WHEN�THE�OPTIONS�FIELD�WAS�ONLY�THE�SECOND�BYTE�OF�THE�WORD,�SO7*‚XIOOPT-1�REFERS�TO�THE�BEGINNING�OF�THE�OPTIONS�WORD.*INIT10:‰MOVE.L„A3,-(A7)*œSAVE�REGISTER=ŠMOVE.W�XCDBOPT(A1),XIOOPT-1(A0)�SET�UP�OPTIONS�FOR�ALLOCATE.6ŠMOVE.L�XCDBAID(A1),XIOCID(A0)�SET�UP�CHANNEL�MNEMONIC3ŠMOVEM.L�XCDBPRM(A1),D0-D5/A2-A4�PICK�UP�PARAMETERS=ŠMOVEM.L�D0-D5/A2-A4,XIOPRM(A0)�MOVE�PARAMETERS�TO�PARAM�BLOC‰MOVE.L„(A7)+,A3*œRESTORE�REGISTER *>*‚IF�THIS�IS�AN�IPC�CHANNEL,�SET�OPTIONS�FOR�CHPI�(XOPEXC)�AND*‚EXCLUSIVE�VECTORING�(XOPDIR).*"ŠIF.BƒXIOCTP(A0)�…#XTDIPCƒOR.B�XIOCTP(A0)�‹#XTMIPCƒTHEN.S�OR.Bƒ#XOPEXC+XOPDIR,XIOOPT(A0)ŠENDI *,*‚NOW�CALL�THE�EXEC�TO�ALLOCATE�THE�CHANNEL.*)ŠMOVE.L�#XCCMR,D0ŠSET�UP�DIRECTIVE�NUMBERŠTRAPƒ#1‘ALLOCATE�CHANNELŠBEQ.S‚INIT17�OK"ŠCMP.B‚#XSTCAD,D0‰CHANNEL�MISSING? *‰BNE„KILL�ERROR,�CAN'T�CONTINUE ‰BSRNE‡KILL *<*‚CHANNEL�ALLOCATED�OK--IF�THERE�ARE�MORE�TO�ALLOCATE,�LOOP.*)INIT17„MOVE.L�XCDBPTR(A1),A1…GET�NEXT�CDB ŠTST.L‚(A1)ŠBNE.S‚INIT10�NOT�FINISHED‰PAGE**ˆNOW�SET�UP�OS�MODULES*INIT19: ‰BSR‡FMSIOI01-*œPERFORM�ANY�FMS�CALCULATIONS�THAT�MAY�EXIST.*œIF�FMS�IS�NOT�PRESENT�IN�THE�SYSTEM�AN�'RTS'*¡INSTRUCTION�WILL�BE�EXECUTED*œELSE,*¡THE�APPROPRIATE�FMS�LOGIC�WILL�BE�EXECUTED*¡D0�=�FMS�ASQ�LENGTH‰MOVE.L„D0,REGA0-4(A3)*œD7�=�REGA0-4(A3)1*œD7�=�FMS�ASQ�LENGTH�IF�FMS�IS�PRESENT�IN�SYSTEM*¢ELSE*¡VALUE�IN�D7�IS�MEANINGLESS‰MOVE.L„#DCLSHR,D0*œD0�=�DIRECTIVE�NUMBER‰LEA‡SEGBLK(A3),A0*œA0�=�PARAMETER�BLOCK�ADDRESS‰TRAP†#1!*œDECLARE�COMMON�SEGMENT�SHARABLE *‰BNE„KILL ‰BSRNE‡KILL ‰BSR‡GETLHSV*œGET�LOW/HIGH�START�VALUE ‰BNE‡INIT50!*œBRANCH�IF�OSLIST�TABLE�IS�EMPTY*"*ˆSTART�PROCESSING�OF�OSLIST�TABLE*INIT30: ‰BSR‡GANE#*œGET�ADDRESS�NEXT�ENTRY�TO�PROCESS$*œA1�=�ADDRESS�NEXT�ENTRY�TO�PROCESS‰MOVE.W„(A1)+,STARTVAL(A3)*œSAVE *¦START�VALUE *¦BIT�NUMBER*°FOR�ENTRY�PROCESSING*0‰LEA‡STRBLK(A3),A0‰SET�UP�POINTER�TO�PARAM�BLOCK,ŠMOVEM.L�(A1)+,D0-D1‡SET�UP�TASK�AND�SESSIONŠMOVEM.L�D0-D1,STRTSK(A0) ŠMOVEM.L�D0-D1,SEGBLK+SEGTCB(A3) ŠMOVEM.L�D0-D1,ASQBLK+ASQTSK(A3)ŠMOVEM.L�(A1)+,D0-D2 ŠMOVEM.L�D0-D2,ASQBLK+ASQSTA(A3)ŠMOVEM.L�(A1)+,D0-D3!ŠMOVEM.L�D0-D3,CSEGBLK+SEGOPT(A3)‰PAGE*0*ˆGRANT�SHARED�ACCESS�TO�I/O�COMMON�DATA�SEGMENT*‰MOVE.L„#SHRSEG,D0*œD0�=�DIRECTIVE�NUMBER‰LEA‡SEGBLK(A3),A0*œA0�=�PARAMETER�BLOCK�ADDRESS‰TRAP†#10*œGRANT�SHARED�ACCESS�TO�I/O�COMMON�DATA�SEGMENTŠBEQ.S‚INIT30BŒOK"*ˆIGNORE�ENTRY�IF�TASK�NOT�PRESENTŠCMP.B‚#RTCDTASK,D0ŠBEQ„INIT46�SKIP�ENTRY *‰BNE„KILL ‰BSRNE‡KILL‰PAGEH*IF TASK GETS DATA SEGMENT, ITS LOG. ADDR. IS PASSED IN A1;ELSE SET TO 0INIT30BƒCLR.L‚REGA0+4(A3)**ˆALLOCATE�ASQ1‰TST.L‚ASQBLK+ASQQLN(A3)‚CHECK�LENGTH�OF�THIS�ASQ‰BEQ.S…INIT30C'*œBRANCH�IF�THERE�IS�NO�ASQ�TO�ALL* OCATE*‰MOVE.L„#GTASQ,D0*œD0�=�DIRECTIVE�NUMBER‰LEA‡ASQBLK(A3),A0*œA0�=�PARAMETER�BLOCK�ADDRESS‰TRAP†#1 *œGET�AN�ASQ*‰BNE„KILL�ERROR ‰BSRNE‡KILL‰PAGE**ˆALLOCATE�TASK�DATA�SEGMENT*INIT30C:-ŠTST.L‚CSEGBLK+SEGLEN(A3)�NEED�DATA�SEGMENT�?ŠBEQ.S‚INIT35�NO**ˆGET�TASK�A�DATA�SEGMENT*'ŠCLR.L‚CSEGBLK+SEGTCB(A3)�CLEAR�TASK�IDŠCLR.L‚CSEGBLK+SEGSES(A3)‰MOVE.L„#GTSEG,D0*œD0�=�DIRECTIVE�NUMBER‰LEA‡CSEGBLK(A3),A0*œA0�=�PARAMETER�BLOCK�ADDRESS‰TRAP†#1 *œGET�SEGMENT�FOR�SPECIFIED�TASK*‰BNE„KILL�ERROR ‰BSRNE‡KILL**IF LOG. ADDR=PHY. ADDR, A0 CONTAINS ADDR.ŠMOVE.W�CSEGBLK+SEGOPT(A3),D0ŠAND.W‚#SGOPPA,D0 ŠBNE.S‚INIT315ŠMOVE.L�CSEGBLK+SEGLAD(A3),A0‚PICK�UP�LOGICAL�ADDRESSINIT31„MOVE.L�A0,REGA0+4(A3)4ŠMOVE.L�CSEGBLK+SEGLEN(A3),D1‚PICK�UP�SEGMENT�LENGTH$INIT32„CLR.L‚(A0)+ŽZERO�DATA�SEGMENTŠSUB.L‚#4,D1ŽFINISHED�?ŠBGT.S‚INIT32�NO4ŠMOVE.L�#IOSID,CSEGBLK+SEGTCB(A3)ƒSET�UP�IOS�TASK�ID5ŠMOVE.L�#IOSESS,CSEGBLK+SEGSES(A3)‚SET�UP�I/O�SESSION‰MOVE.L„#DCLSHR,D0*œD0�=�DIRECTIVE�NUMBER‰LEA‡CSEGBLK(A3),A0*œA0�=�PARAMETER�BLOCK�ADDRESS‰TRAP†#1*œDECLARE�SEGMENT�SHARABLE *‰BNE.S‚KILL ‰BSRNE…KILL‰MOVE.L„#SHRSEG,D0*œD0�=�DIRECTIVE�NUMBER‰LEA‡CSEGBLK(A3),A0*œA0�=�PARAMETER�BLOCK�ADDRESS‰TRAP†#1*œDECLARE�SEGMENT�SHARABLE *‰BNE.S‚KILL ‰BSRNE…KILLBŠMOVE.L�SEGBLK+SEGTCB(A3),CSEGBLK+SEGTCB(A3)‚SET�UP�TARGET�TASK�ID,ŠMOVE.L�SEGBLK+SEGSES(A3),CSEGBLK+SEGSES(A3)‰MOVE.L„#TRSEG,D0*œD0�=�DIRECTIVE�NUMBR‰LEA‡CSEGBLK(A3),A0*œA0�=�PARAMETER�BLOCK�ADDRESS‰TRAP†#1*œTRANSFER�SEGMENT *‰BNE.S‚KILL ‰BSRNE.SƒKILL‰PAGE***ˆSTART�TASK�-�A0=ADDR.�OF�START�OF�IOCOMS*INIT35:‰MOVE.L„#START,D0*œD0�=�DIRECTIVE‰LEA‡STRBLK(A3),A0*œA0�=�PARAMETER�BLOCK�ADDRESS‰TRAP†#1 *œSTART�TASK"*‰BNE.S‚KILL�ERROR,�CAN'T�CONTINUE ‰BSRNE.SƒKILLINIT38: ‰MOVE.L„A1,A0‰SUB.L…#OESIZE,A0,*œA0�=�START�ADDRESS�OF�ENTRY�JUST�PROCESSED‰CMP.B…#$FF,1(A0) ‰BEQ.S…INIT46&*œBRANCH�IF�WE�DO�not�HAVE�TO�WAIT�FOR)*¡THIS�TASK�TO�COMLETE�ITS�INITIALIZATION ‰CLR.L…D1‰MOVE.B„1(A0),D1*œD1�=�BIT�NUMBER�TO�EDIT�FORINIT44:‰MOVE.L„#RELINQ,D0 *œD0�=�RELINQUISH�DIRECTIVE�CODE‰TRAP†#1*œRELINQUISH�CONTROL‰BTST†D1,SVTSTCF(A6) ‰BEQ.S…INIT44-*œBRANCH�IF�STARTED�TASK�HAS�NOT�FINISHED�ITS*¡INITIALIZATION�PROCESSINIT46:‰MOVE.B„HSV+3(A3),D0*œD0.B�=�HIGH�START�VALUE‰CMP.B…STARTVAL(A3),D0 ‰BNE‡INIT30#*œBRANCH�IF�MORE�ENTRIES�TO�PROCESSINIT48: ‰BSR‡EETSTART*œGO�START�EET�TASK�IF�IT�EXIST**ˆALL�DONE�-�GO�AWAY*INIT50„ERQ.TERM‰PAGE* *ˆROUTINE�TO&*’INITILIZE�THE�TASK�DATA�SEGMENT�AREA**ˆINPUT8*’A0�=�ADDRESS�OF�I/0�COMMON�DATA�SEGMENT�AT�SYSGEN�TIME(*’A3�=�ADDRESS�OF�TASK�DATA�SEGMENT�AREA *’A5�=…ZERO�-->�RAM�BASED�SYSTEM*—NON-ZERO�-->�ROM�BASED�SYSTEM**ˆOUTPUT*’N/A**ˆREGISTER�ALTERATION* TEMPLATE:#‰MOVE.W„#STOPMP+STOPRG,STRBLK+8(A3)#*œINITIALIZE�STRBLK�PARAMETER�BLOCK‰MOVE.B„#XDCALL,ALLBLK(A3)‰MOVE.B„#XOPEXC,ALLBLK+3(A3)#*œINITIALIZE�ALLBLK�PARAMETER�BLOCK‰MOVE.W„#SGATSS,SEGBLK+10(A3)‰MOVE.L„#IOCOMN,SEGBLK+12(A3)$‰MOVE.L„#IOCOME-IOCOMS,SEGBLK+20(A3)‰MOVE.L„A5,SEGBLK+16(A3)‰BNE.S…TEMPL9999*œBRANCH�IF�ROM�BASED�SYSTEM‰MOVE.L„A0,SEGBLK+16(A3)#*œINITIALIZE�SEGBLK�PARAMETER�BLOCK TEMPL9999:‰RTS‰PAGE**ˆABORT* KILL†EQU„*'ŠMOVEM.L�D0/A0,-(A7)‡SAVE�REG�D0�AND�A0ŠERQ.ABORT�#0ŽABORT�SELF ************************* INIT9999: ‰DC.W†$4AFC)*œTHIS�IS�CODE�FOR�AN�ILLEGAL�INSTRUCTION *œWE'RE�BRINGING�THE�SYSTEM�DOWNŠPAGE* *ˆRoutine�to/*’Obtain�and�save�the�low�and�high�start�values+*’Initialize�the�LAST�VALUE�PROCESSED�field**ˆINPUT,*’A3�=�ADDRESS�OF�DATA�SEGMENT�FOR�THIS�TASK**ˆOUTPUT,*’A3�-�ADDRESS�OF�DATA�SEGMENT�FOR�THIS�TASK**ˆREGISTER�ALTERATION**’A0�=�DESTROYED*’D0�=�DESTROYED**ˆCONDITION�CODES**’EQUAL�-->�TABLE�ENTRIESˆEXIST**ŽNOT�EQUAL�-->�TABLE�ENTRIES�DO�NOT�EXIST* *ˆEQUATES*MAXVALUE�EQU‡$FFMINVAL* UE�EQU‡$00*GETLHSV:‰MOVE.L„#OSMTBL,A0*œA0�=�START�OF�OSLIST�TABLE‰CMP.L…#OSMEND,A0‰BEQ.S…GLHSV040-*œBRANCH�IF�THERE�ARE�NO�ENTRIES�IN�THE�TABLE‰MOVE.L„#MAXVALUE+1,LSV(A3)*œINITIALIZE�LOW�START�VALUE‰MOVE.L„#MINVALUE-1,HSV(A3)*œINITIALIZE�HIGH�START�VALUE GLHSV010: ‰CLR.L…D0*œD0�=�INITIALIZED‰MOVE.B„(A0),D0!*œD0�=�START�VALUE�FOR�THIS�ENTRY‰CMP.L…LSV(A3),D0‰BGE.S…GLHSV020&*œBRANCH�IF�START�VALUE�FOR�THIS�ENTRY*¦IS�>�OR�=�TO�LOW�START�VALUE‰CLR.L…LSV(A3)‰MOVE.B„D0,LSV+3(A3)*œESTABLISH�NEW�LOW�VALUE‰MOVE.L„D0,LVP(A3)‰SUB.L…#1,LVP(A3)#*œESTABLISH�LAST�VALUE�PROCESSED�TO*¡LOW�VALUE�MINUS�ONE GLHSV020:‰CMP.L…HSV(A3),D0‰BLE.S…GLHSV030&*œBRANCH�IF�START�VALUE�FOR�THIS�ENTRY*¦IS�<�OR�=�TO�HIGH�START�VALUE‰CLR.L…HSV(A3)‰MOVE.B„D0,HSV+3(A3)*œESTABLISH�NEW�HIGH�VALUE GLHSV030:‰ADD.L…#OESIZE,A0*œADJUST�TO�NEXT�ENTRY‰CMP.L…#OSMEND,A0‰BNE.S…GLHSV010#*œBRANCH�IF�MORE�ENTRIES�TO�PROCESS‰BRA.S…GLHSV050*œRETURN�TO�USER GLHSV040: ‰TST.L…(A7)*œSET�NO�TABLE�ENTRY�CONDITION GLHSV050:‰RTS*œRETURN�TO�USERŠPAGE* *ˆRoutine�to)*’obtain�address�of�next�entry�to�process;*’set�last�value�processed�equal�to�start�value�entry�to�be *—processed**ˆINPUT,*’A3�=�ADDRESS�OF�DATA�SEGMENT�FOR�THIS�TASK**ˆOUTPUT4*’A1�-�ADDRESS�OF�NEXT�OSLIST�TABLE�ENTRY�TO�PROCESS,*’A3�-�ADDRESS�OF�DATA�SEGMENT�FOR�THIS�TASK**ˆREGISTER�ALTERATION**’A0�=�DESTROYED*’D0�=�DESTROYED**ˆCONDITION�CODES**’N/A*GANE:‰MOVE.L„#MAXVALUE+1,NVTP(A3)"*œINITIALIZE�NEXT�VALUE�TO�PROCESS‰MOVE.L„#OSMTBL,A0(*œA0�=�START�ADDRESS�OF�TABLE�TO�PROCESS GANE0100: ‰CLR.L…D0‰MOVE.B„(A0),D0)*œD0.B�=�START�VALUE�FOR�ENTRY�PROCESSING‰CMP.L…LVP(A3),D0‰BLE.S…GANE0200%*œBRANCH�IF�START�VALUE�THIS�ENTRY�IS+*¡LESS�THAN�OR�SAME�AS�LAST�VALUE�PROCESSED3*œTHIS�ENTRY�CAN�BE�IGNORED�AS�IT�AS�BEEN�PROCESSED‰CMP.L…NVTP(A3),D0‰BGE.S…GANE0200%*œBRANCH�IF�START�VALUE�THIS�ENTRY�IS/*¡GREATER�THAN�OR�SAME�AS�NEXT�VALUE�TO�PROCESS,*œTHIS�ENTRY�IS�TO�HIGH�TO�PROCESS�THIS�PASS‰CLR.L…NVTP(A3)‰MOVE.B„(A0),NVTP+3(A3)(*œSAVE�START�VALUE�NEXT�ENTRY�TO�PROCESS ‰MOVE.L„A0,D0 ‰MOVE.L„D0,A1$*œA1�=�ADDRESS�NEXT�ENTRY�TO�PROCESS GANE0200:‰ADD.L…#OESIZE,A0$*œA0�=�ADDRESS�NEXT�ENTRY�TO�PROCESS‰CMP.L…#OSMEND,A0‰BNE.S…GANE0100$*œBRANCH�IF�ANOTHER�ENTRY�TO�PROCESS‰CLR.L…LVP(A3)‰MOVE.B„(A1),LVP+3(A3))*œSET�LAST�VALUE�PROCESSED�TO�START�VALUE*œENTRY�TO�BE�PROCESSED‰RTS*œRETURN�TO�USERŠPAGE ŠEND„INITéLOADERƒIDNTƒ3,0*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.***ˆINCLUDE�FILES*‰NOLIST‰INCLUDE�9995.&.EXE.EQ‰INCLUDE�9995.&.IOE.EQ‰INCLUDE�9995.&.TR1.EQ‰INCLUDE�9995.&.TR1RTCD.EQ‰INCLUDE�9995.&.TCB.EQ‰LIST**‰PAGE** Modification history*‰PAGE!********************************§*Æ*ˆTRAP�4�SERVER�TASK¬*Æ!********************************§*Æ*‚DIRECTIVES:¹ *„1�-�LOADER¸*„2�-�ERROR�HANDLER±*Æ!********************************§‚PAGEÁE********************************************************************ƒE********************************************************************ƒ*Æ!*ˆ****�LOADER�-�SERVER�TASKƒ****ž*ÆE********************************************************************ƒE********************************************************************ƒ*Æ *‚FUNCTION:»:*‚TO�LOAD�A�MACSS�MC68000�STANDARD�FORMAT�LOAD�MODULE�AND�,*‚CREATE�A�TCB�FOR�THE�LOADED�PROGRAM/TASK.›*Æ *‚INTERFACE:º;*‚THE�CALLER�PASSES�THE�ADDRESS�OF�THE�FOLLOWING+ �PARAMETERŒA*‚BLOCK�TO�THE�LOADER�(IN�A0;�THE�LOADER�RECEIVES�IT�FROM�SERVER†*‚REQUEST�EVENT�MSG):±C*‚*�TCB�PRIMER�WHICH�IS�INITIATED�ACCORDING�TO�THE�OPTION�BITS�SET„-*‚(IDENTICAL�FORMAT�TO�TCB�PRIMER�FOR�CRTCB)š*‚*�2�BYTES�LOADER�OPTIONS¬*‚*�1�BYTE�UNUSEDµ<*‚*�1�BYTE�LOGICAL�UNIT�NUMBER�OF�ASSIGNED�LOAD�MODULE�FILE‹>*‚*�4�BYTES�SUCCESSFUL�RETURN�ADDRESS�IF�REQUESTOR�TO�PROCEED‰9*‚*�4�BYTES�ERROR�RETURN�ADDRESS�IF�REQUESTOR�TO�PROCEEDŽ2*‚*�4�BYTES�REQUESTOR�COMMAND�LINE�BUFFER�ADDRESS•;*‚THE�LOADER�RETURNS�THE�COMPLETED�TCB�PRIMER�BLOCK�TO�THEŒ;*‚CALLER'S�PARAMETER�BLOCK.‚ALSO,�IF�THE�CALLER�WAITED�FOR‹<*‚LOAD�TO�COMPLETE,�UPON�RETURN�HIS�Z-FLAG�IS�SET�OR�OFF�TO‹@*‚INDICATE�SUCCESS�OR�FAILURE�AND�D0�CONTAINS�THE�ERROR�STATUS.‡*Æ *‚LOAD�MODULE�FORMAT�VS�LOADER:§;*‚THE�FIRST�LOGICAL�SECTOR�CONTAINS�THE�LOADER�INFORMATIONŒA*‚BLOCK�(�LIB�).‚SUBSEQUENT�LOGICAL�SECTORS�CONTAIN�MEMORY�IMAGE…:*‚BLOCKS.‚A�MEMORY�IMAGE�BLOCK�CAN�BE�LOADED�(�IOS�READ�)Œ TB]9eFmLuJ}A…G�<•A�H¥H­=µ:½;Å=Í<Õ8Ý@åBí=õ17*‚WITH�ONE�BLOCK�TRANSFER,�THEREFORE�IT�MUST�BE�STORED�D*‚CONTIGUOUSLY�ON�THE�DISK�IN�AS�MANY�SECTORS�AS�REQUIRED.‚THE�TASK‚@*‚DESCRIPTOR�INFORMATION�IN�THE�LIB�IS�USED�TO�COMPLETE�THE�TCB‡=*‚PRIMER�FOR�TCB�ALLOCATION.‚A�SEGMENT�ALLOCATION�DESCRIPTOR‰C*‚IS�USED�TO�ALLOCATE�A�SEGMENT�OF�GIVEN�LENGTH�TEMPORARILY�TO�THE„B*‚LOADER,�THEN�THE�MEMORY�IMAGE�DESCRIPTORS�ARE�USED�TO�DETERMINE…C*‚WHETHER�OR�NOT�THE�SEGMENT�HAS�MEMORY�IMAGE�BLOCKS�TO�BE�LOADED.„?*‚AFTER�THE�BLOCKS�OF�THE�SEGMENT�HAVE�BEEN�LOADED�THE�SEGMENTˆ<*‚IS�TRANSFERRED�TO�THE�TASK�WITH�PROPER�LOGICAL�ADDRESSES,‹*‚ATTRIBUTES�AND�SEGMENT�NAME.¨*Æ*‚REV�1.20‚8/14/80‚HLD6*ÆE********************************************************************ƒ‚PAGEÁF*********************************************************************‚*Æ*ˆ****�EQUATES�****­*ÆF*********************************************************************‚*Æ*ˆ**�TRAP�4ƒEQUATES�**¨*Æ?STRPNOƒEQU�4�SERVER�TRAP�NUMBER�=�4,�MUST�HAVE�DIRECTIVE�IN�D0‡*ÆLDRDIRƒEQU�1‚LOADER�DIRECTIVE$ERRDIRƒEQU�2‚ERROR�HANDLER�DIRECTIVE*Æ5TRMMSGF‚EQU�6‚BIT�SET�IN�TRAP�#�FIELD�OF�EVENT�(TERM)CCZ†EQU�4‚CONDITION�CODE�Z�=�1CCN†EQU�8‚CONDITION�CODE�N�=�1*Æ*ˆ**�LOADER�EQUATES�**ª*Æ,LMFLUNƒEQU�4�LOAD�MODULE�FILE�LUN�FOR�LOADER*Æ*ˆ**‚EXEC�EQUATES‚***Æ%ACKLENƒEQU�$14‚ACKTSK�-�ACKRA0�LENGTH!CTOPMPB‚EQU‚14‚MONITOR�PROPOGATED2EVTSYSƒEQU‚EVTNOS+8‚SYSTEM�TASK�BIT�IN�TRAP�NUMBER0SEGAGLBL�EQU‚12‚ATTR�BIT�FOR�GLOBALLY�SHARED�SEG/SEGALOCL�EQU‚13‚ATTR�BIT�FOR�LOCALLY�SHARED�SEG+CXACRIT‚EQU‚$4000ƒTASK�ATTR�-�CRITICAL�TASK*Æ3*‚RESERVED�ATTRIBUTE�BIT�USED�BY�LOADER�(LIBSATR):”*Æ.ALLOCSG�EQU�15�BIT�15�SET�=>�ALLOCATE�SEGMENTš*¦OFF�=>�ALL�SEGMENTS�DONEˆ�PAGEÂ*Æ*‚LOADER�OPTIONS�(PARLDO):¬*ÆELOPPRO�EQU�15�BIT�15�SET�=>�LET�REQUESTOR�TASK�PROCEED�WHILE�LOADINGƒ8*‚REQUESTOR�SUPPLIES�RETURN�ADDRESSES�(PARROK�&�PARRER)�D*‚BIT�OFF�=>�WAIT�TASK�TILL�DONE�LOADING,�NO�RETURN�ADDRESSES�GIVENƒ2LOPCLF�EQU�14�BIT�14�SET�=>�LOADER�MUST�OPEN�FILE–(*‚BIT�OFF�=>�CLOSE�LOAD�MODULE�FILE�LUNŸELOPRCL�EQU�13�BIT�13�=>�REQUEST�CMD�LINE�TRANSFERRED�TO�ADR�SUPPLIEDƒ*Æ>*‚THE�FOLLOWING�BITS�SET�INDICATE�THE�ASSOCIATED�FIELD�IN�TCB‰7*‚PRIMER�PARAMETER�BLOCK�IS�SUPPLIED�BY�THE�REQUESTOR:�+*‚NOTE:�USER�ID�MUST�BE�SUPPLIED�BY�CALLERœ*Æ!LOPENT�EQU�7�LOGICAL�ENTRY�POINT§LOPATT�EQU�6�TASK�ATTRIBUTES«!LOPLPR�EQU�5�TASK�LIMIT�PRIORITY§#LOPIPR�EQU�4�TASK�INITIAL�PRIORITY¥-LOPMON�EQU�3�MONITOR�NAME�AND�SESSION�NUMBER›$LOPOPT�EQU�2�TCB�ALLOCATION�OPTIONS¤!LOPSES�EQU�1�TASK�SESSION�NUMBER§LOPTSK�EQU�0�TASK�NAME±*Æ,*‚LOADER�RETURN�CONDITIONS�TO�WAITING�TASK:›$*‚Z�=�1,�D0�=�0�=>�LOAD�SUCCESSFULL£$*†0,�D0�=�ERROR�CODE�=>�LOAD�FAILEDŸ8*‚A0�->�PARAMETER�BLOCK,�TCB�NOW�AS�ALLOCATED�BY�LOADER�*Æ+ $*‚LOADER�ERROR�STATUS�RETURN�CODES:£*ÆELERSAB�EQU�18�LOAD�SEGMENT�LOGICAL�ADDRESS�NOT�IN�SEGMENT�BOUNDARIESƒ8LERDIR�EQU�1‚IN�D0�UNDEFINED�DIRECTIVE�FOR�TRAP�'STRPNO'(LERLMD�EQU�19�FILE�IS�NOT�A�LOAD�MODULE LEROPN�EQU�14�OPEN�ERROR¯*Æ(*†LOADER�INFORMATION�BLOCK�(LIB)�EQUATES*KLIBSAD�EQU�$30‚Index�to�Beginning�of�Segment�Allocation�Descriptors�(SAD's)5LIBSSA�EQU�8„Position�in�LIB�of�segment�start�address/LIBSLN�EQU�$CƒPosition�in�LIB�of�segment�length.LIBNTRY�EQU�$16‚Position�in�LIB�of�entry�point6LIBCLA�EQU�$1A‚Position�in�LIB�of�Command�Line�Address*0*†LOADER�INFORMATION�BLOCK�-�TASK�ATTRIBUTE�BITS**ATPOSI�EQU�11ƒTask�is�Position�Independent‡PAGE* ‰SECTION�0**%*ˆPUBLIC�REFERENCES�FROM�THIS�PROGRAM***‰XDEF†A0BLK,ATTRCOD,ATTRFHS‰XDEF†CHLUFHS,CLSFHS,CLUFHS<‰XDEF†EPBLDF,EPBLTH,EPBOPT,EPBPLUGB,EPBPLUGE,EPBQUERY,EPBRA0‰XDEF†EPBRD0,ERQMPB‰XDEF†LIBBUF,LDRBEG,LDRRTN‰XDEF†MOVASC1,MOVEBLK‰XDEF†POOLTABL,PLUGPOOL‰XDEF†TAKELUN,TAKELUN2,TASKLIST****ŠEXTERNAL�REFERENCES**‰XREF†BI2HEX4,ERRMSGHA**†OPT…PCSG********************************************************************** *Æ*�START�OF�DATA�SEGMENT°*ÆG********************************************************************** *#*‚EXEC�DIRECTIVE�PARAMETER�BLOCKS:¤*Æ(LDRDPB‚EQU‚*‡GET�DATA�SEGMENT�FOR�LOADER!ˆDC.L�0,0…TASK�AND�SESSION�(SELF),ˆDC.W�$2000ƒOPTIONS�-�SUPPLY�LOGICAL�ADDRESSˆDC.W�0‡ATTRIBUTESˆDC.L�'DLDR'‚SEGMENT�NAME ˆDC.L�0‡ADDRESS�WILL�BE�RETURNEDˆDC.L�DSEGLNG�LENGTH�OF�SEGMENT*Æ@*†PARAMETER�BLOCKS�NEEDED�TO�START�USERDUMP�AT�TASK�TERMINATIONƒ*Æ#*ˆPARAMETER�BLOCK�PASSED�TO�LOADERž*Æ DMPBLKƒEQUƒ*·+‰DC.L‚'TDMP'ˆTASK�NAME�-�ALWAYS�SET�BY�TERM&‰DC.L‚0ŽSESSION�SAME�AS�ABORTING�TASKŒ‰DC.W‚0�TCB�OPTIONS�-�NONE˜ ‰DC.L‚0,0‹MONITOR�NOT�SPECIFIED•‰DC.B‚$88,$C8‡PRIORITIES 2‰DC.W‚CTATST+CXACRITƒTASK�ATTRIBUTES�-�SYSTEM�TASK!‰DC.L‚0�ENTRY�FOUND�IN�LOAD�FILE’,‰DC.W‚0�USER�ID�-�SET�SAME�AS�ABORTING�TASK‡‰DC.W‚$6077‰LOADER�OPTIONS‰DC.B‚22ŒEVENT�MESSAGE�LENGTH–‰DC.B‚LMFLUNˆLOGICAL�UNITž‰DC.L‚0,0‹NOT�USED¢*‰DC.L‚EVNTBUF‡EVENT�BUFFER�-�COMMAND�LINE�*Æ3*…FHS�PARAMETER�BLOCK�-�DEFINES�USERDUMP�LOAD�FILE‘*CLSFHS‚DC.WƒFHCLOS²ˆDC.Wƒ0· ˆDC.Bƒ0,6µ&ˆDC.L‚'„'†VOLUME�-�USE�SYSTEM�DEFAULT’ˆDC.Wƒ0ŠUSER�ID¦ˆDC.L‚'„','„'ƒCATALOGˆDC.B‚'TASKDUMP'ƒFILE�NAME£ˆDC.W‚'SY'‰EXTENT¦ˆDC.W‚0¸ ˆDC.B‚0,0¶ˆDC.W‚0¸ˆDC.L‚0¸ˆDS.W‚0** TASKLIST�DC.Lƒ'&SCT','&BCT',0,-1**†ERROR�MESSAGE�FOR�TASKTERM*/DERMSG‚DC.Bƒ'SRV4:�UNABLE�TO�LOAD�TASKDUMP.SY'–ˆDC.Bƒ$0D,$0A,$0A­DERMSGE�EQU„*-1*ˆDS.Wƒ0ˆPAGE*D*ƒTHE�FOLLOWING�PARAMETERS�ARE�MODELS�FOR�PARAMETERS�IN�DATA�SEGMENT*G************************************************************************Æ.*…FHS�PARAMETER�BLOCK�FOR�CHANGE�LOGICAL�UNIT–*"XCLUFHS�DC.B‚$01,$10ˆCOMMAND�=�CLU!ˆDC.W‚$8001ŠRECEIVE�LOGICAL�UNIT–ˆDC.B‚0,6,6,0ˆLU�=�6¤"ˆDC.L‚0ŽTASK�NAME�OF�ABORTING�TASK ˆDC.L‚0ŽSESSION�OF�ABORTING�TASK*Æ(XERQSRV EQU * ESTABLISH TASK AS A SERVER"ˆDC.L�ASRESVC„SERVICE�CALL�ADDRESS7ˆDC.B�STRPNO+$60‚TRAP�NUMBER�+�TERM�MESSAGE�+�PB�OPTION-ˆDC.B�PARLEN+FHSBLN†LENGTH�OF�PARAMETER�BLOCK*Æ-*‚LOAD�MODULE�FILE�IOS�READ�PARAMETER�BLOCK:š*ÆJIOPT„SET�IOPBIN+IOPWAT+IOPNOC+IOPBLK+IOPRAN�BINARY,WAIT,NO�COMPL�ADR,BLOCK&ˆIOS.XLMF�IOREAD,IOPT,LMFLUN,0,0,0,0,0*Æ-*†IOS�PARAMETER�BLOCK�TO�WRITE�ERROR�MESSAGE–*6ˆIOS.XDPER�IOWRIT,IOPIMG+IOPUNP,6,0,0,DERMSG,DERMSGE,0*ÆXMSGABRT�DC.B‚$0D,$0A,$20,0 ‰DC.L‚'„'‰DC.B‚':‚ABORTED�BY�' ‰DC.L‚'„' ‰DC.B‚'=' ‰DC.B‚'„' ‰DC.B‚$0D,$0AXSEGLNG‚EQUƒ*-XCLUFHS‰PAGE ‰OFFSET�0‰DS.Bƒ148‡STACK STACK„EQU„**1ERQMPBƒEQUƒ*ŠMOVE�PARAMETER�BLOCK�BACK�TO�CALLERŠ'‰DS.L‚2ŠTASK�+�SESSION�OF�SENDER�(SELF),‰DS.L‚1ŠLOG�ADDRESS�OF�BLOCK�TO�SEND(PARBLK)+‰DS.L‚2ŠDESTINATION�TASK+�SESSION�(FILL�IN)‰DS.L‚1ŠDESTINATION�ADDRESS)‰DS.L‚1ŠLENGTH�OF�PARAMETER�BLOCK(PARLEN)*Æ*Æ*GTSEGPB‚EQUƒ*ŠAL, LOCATE�SEGMENT�FOR�LOADING'‰DS.L‚2ŠALLOC�SEG�TO�LOADER�TEMPORARILY‰DS.W‚1ŠOPTIONS�($8000)‰DS.W‚1ŠSEG�ATTR:�READ/WRITE‰DS.L‚1ŠSEGMENT�NAME.TSLADRƒDS.L‚1ŠLOGICAL�ADR�*****=PHYSICAL******‰DS.L‚1ŠSEGMENT�LENGTH*Æ9ERQMCLƒEQUƒ*†PARAMETER�BLOCK�TO�MOVE�COMMAND�LINE�TO�USER,ERQXFRƒEQUƒ*†TRANSFER�LOADED�SEGMENT�TO�TASK*‰DS.L‚2†RECEIVER�TASK�NAME�/SESSION�NUMBER-‰DS.W‚1†CHANGE�ATTRIBUTES,LOGICAL�ADR�($C000)‰DS.W‚1†SEG�ATTRIBUTES‰DS.L‚1†SEGMENT�NAME‰DS.L‚1†LOGICAL�ADR%‰DS.L‚2†RESERVED�FOR�MOVEM.L�TRANSFER**…SET�PRIORITY�PARAMETER�BLOCK*BSETPPB‚DS.B‚10*Æ*…START�TASK�PARAMETER�BLOCK§*Æ$STRTDMP‚DS.L‚2†TASK�NAME�AND�SESSION ‰DS.W‚1†MONITOR�SPECIFIED($8000)‰DS.L‚2†MONITOR�IS�SELF*.*…STOP/START�&SCT�PARAMETER�BLOCK�(FOR�ABORTS)*?STSTSCT‚DS.L‚2†TASK�NAME�&�SESSION�(&SCT�FOR�THE�GIVEN�SESSION)‰DS.W‚1†OPTIONS�(0�=�NONE)‰PAGE@***************************************************************ˆ*Æ)*‚LOADER�INFORMATION�BLOCK�(LIB)�EQUATESž*Æ LIBBUFƒEQUƒ*·*ÆA*�1ST�PART�OF�THE�TASK�DESCRIPTOR�HAS�SAME�FORMAT�AS�TCB�PRIMER:‡*ÆLIBTSKƒDS.L‚1‡TASK�NAME§"LIBSESƒDS.L‚1‡TASK�SESSION�NUMBER�%LIBOPTƒDS.W‚1‡TCB�ALLOCATION�OPTIONSš3LIBMONƒDS.L‚2‡TASK'S�MONITOR�(NAME/SESSION�NUMBER)Œ$LIBIPRƒDS.B‚1‡TASK�INITIAL�PRIORITY›"LIBLPRƒDS.B‚1‡TASK�LIMIT�PRIORITY�LIBATTƒDS.W‚1‡TASK�ATTRIBUTES¡LIBENTƒDS.L‚1‡TASK�ENTRY�POINT 'LIBCMLƒDS.L‚1ˆCOMMAND�LINE�PUT�ADDRESS—)LIBCMCƒDS.B‚1ˆCOMMAND�LINE�BUFFER�LENGTH•‰DS.B‚17‡RESERVED§*Æ!*„SEGMENT�ALLOCATION�DESCRIPTORS¤*ÆLIBSBASƒEQUƒ*¶ŠDS.B‚2ˆRESERVED"LIBSATRƒDS.W‚1ˆSEGMENT�ATTRIBUTESœLIBSNAMƒDS.L‚1ˆSEGMENT�NAME¢(LIBSLSAƒDS.L‚1ˆLOGICAL�STARTING�ADDRESS–)LIBSLENƒDS.L‚1ˆSEGMENT�LENGTH�(IN�BYTES)•)LIBSSIZƒEQUƒ*-LIBSBASƒSIZE�OF�LIBS�ENTRY™%LIBSCNTƒEQUƒ8ˆNUMBER�OF�LIBS�ENTRIES˜ŠDS.B‚(LIBSCNT-1)*LIBSSIZ*Æ*…MEMORY�IMAGE�DESCRIPTORS©*Æ'LIBMBASƒEQUƒ*ˆMEMORY�IMAGE�DESCRIPTORS– LIBMSLAƒDS.W‚1ˆSRARTING�ADDRESSžLIBMELAƒDS.W‚1ˆENDING�ADDRESS #LIBMSIZƒEQUƒ*-LIBMBAS…SIZE�OF�ENTRY!LIBMCNTƒEQUƒ20‡NUMBER�OF�ENTRIES�ŠDS.B‚(LIBMCNT-1)*LIBMSIZ#LIBMENDƒEQUƒ$0000FFFFƒEND�OF�LIBM'DLIBEND„EQUƒ*-1**&MIDMOV„DS.W‚0‡Bit�map�for�biased�MIDs.*ÆG************************************************************************ÆEVNTBUFƒEQUƒ*‡READ�EVENT�BUFFEREVNTLNGƒDS.B‚1‡EVENT�LENGTH-EVNTCODƒDS.B‚1‡EVENT�CODE�(7�FOR�USER/SERVER)(EVNTTINƒDS.B‚1‡TRAP�NUMBER�(SHOULD�BE�4)EVNTPRIƒDS.B‚1‡TASK�PRIORITYEVNTTSKƒDS.L‚1‡TASK�NAME"EVNTSESƒDS.L‚1‡TASK�SESSION�NUMBEREVNTUNMƒDS.W‚1‡USER�NUMBEREVNTRD0ƒDS.L‚1‡USER'S�D0EVNTRA0ƒDS.L‚1‡USER'S�A0'ŠDS.B‚2‡PARAMETER�BLOCK�STATUS�AND�SIZEEVNTACOD‚EQUƒEVNTRD0ƒABORT�CODE&EVNTATTR‚EQUƒEVNTRD0+2�TASK�ATTRIBUTES/EVNTATSK‚EQUƒEVNTRA0ƒTASK�RESPONSIBLE�FOR�ABORT*Æ*‚REQUESTOR�PARAMETER�BLOCK«*Æ9PARBLK„EQUƒ*‡LOADER'S�COPY�OF�REQUESTOR'S�PARAMETER�BLOCKPARTSK„DS.L‚1‡TASK�NAME!PARSES„DS.L‚1‡TASK�SESSION�NUMBER"PAROPT„DS.W‚1‡ALLOCATE�TCB�OPTIONS2PARMON„DS.L‚2‡TASK'S�MONITOR�(NAME/SESSION�NUMBER)#PARIPR„DS.B‚1‡TASK�INITIAL�PRIORITY!PARLPR„DS.B‚1‡TASK�LIMIT�PRIORITYPARATT„DS.W‚1‡TASK�ATTRIBUTESPARENT„DS.L‚1‡TASK�ENTRY�POINT*PARUID„DS.W‚1‡USER�ID�OF�TASK�TO�BE�LOADED&PARLDO„DS.W‚1‡LOADER�OPTIONS�(2�BYTES)9PARCLL„DS.B‚1‡REQUESTOR�COMMAND�LINE�LENGTH(LESS�COMMAND);PARLUN„DS.B‚1‡LOGICAL�UNIT�NUMBER�OF�LOAD�MODULE�FILE�(1�BY;PARROK„DS.L‚1‡RETURN�ADDRESS�TO�REQUESTOR�IF�SUCCESSFUL�LOA*PARRER„DS.L‚1‡RETURN�ADDRESS�IF�LOAD�FAILS9PARCLA„DS.L‚1‡PARAMETER�BLOCK�COMMAND�LINE�BUFFER�ADDRESS-PARLEN„EQUƒ*-PARBLK‚LENGTH�OF�PARAMETER�BLOCK*Æ:*†FHS�PARAMETER�BLOCK�MUST�FOLLOW�PARBLK�(PART�OF�PARBLK)‰*ÆA*†FHS�PARAMETER�BLOCK�FOR�OPEN�-�CHANGE�LUN�-�OR�CLOSE�LOAD�FILE‚*ÆLFLFHSƒDS.BƒFHSBLN‰BTST‚#LOPPRO,PARLDO(A6)�CALLER�WANTS�TO�PROCEED�WHILE�LOADING&‰BEQ.S�LOADGO�NO,�CALLER�WANTS�TO�WAIT>‰ERQ.AKRQST�ACKNPB(A6)„YES,�SEND�REQUEST�ACKNOWLEDGED/REACTIVA1‰MOVE.W‚#-1,ACKNOPT(A6)‚FLAG�ACKNOWLEDGE�COMPLETE*Æ/*‡READ�LOADER�INFORMATION�BLOCK�FROM�LOAD�FILE“*ÆLOADGO‚BSR„READLIBˆBNE„ASRERR2†BRANCH�IF�ERRORœ*+*‡CHECK�FOR�TASK�BEING�POSITION�INDEPENDENT*ˆBTSTW‚#ATPOSI,LIBATT(A6)1ˆBEQ.S‚LOADCRT‘BRANCH�IF�NOT�POSITION�INDEPENDENT*5*‡POSITION�INDEPENDENT�-�FIX�LOADER�INFORMATION�BLOCK* ˆBSR„LOFIX*Æ*‡CREATE�NEW�TASK*Æ LOADCRT�EQU„*ˆBSR„BLDNWTSK°ˆBNE„ASRERR2…BRANCH�IF�ERROR�*Æ=*‚ALLOCATE/LOAD�ONE�SEGMENT�AT�A�TIME,�THEN�TRANSFER�SEGMENTŠ;*‚TO�LOADED�TASK�WITH�PROPER�SEGMENT�NAME,�ATTRIBUTES,�ANDŒ*‚LOGICAL�ADDRESSES³*Æ7ˆLEA„LIBSBAS(A6),A3‚ADDRESS�OF�1ST�SEG�ALLOC�DESCRIPTOR:ˆLEA„LIBMBAS(A6),A2‚ADDRESS�OF�1ST�MEMORY�IMAGE�DESCRIPTOR*Æ-*‚PROCESS�NEXT�SEGMENT�ALLOCATION�DESCRIPTORš*Æ;LOADSEG�MOVEM.L�(A3),D0-D3…SEG�ATR,�NAME,�START�ADR,�LENGTH-ˆBTST„#ALLOCSG,D0„IS�THERE�A�SEGMENT�DEFINED?-ˆBEQ.SƒLOADDONE‡NO,�ALL�DONE�LOADING�SEGMENTS*ƉBSRƒNEWSEGŠGO�GET�NEW�SEG- MENT–‰BNEƒASRERR3‰BRANCH�IF�ERROR*Æ/*‚SEGMENT�ALLOCATED,�ANYTHING�TO�LOAD�INTO�IT?˜*Æ0ŠADD.LƒD2,D3…START�ADDR�+�LENGTH�=�END�ADDR�+�1‰ŠSUB.Lƒ#1,D3…END�ADDRESS +ŠMOVE.B‚#$FF,D3ƒALWAYS�END�AT�PAGE�BOUNDRY‘ŠBSR…RD1SEG„GO�READ�ONE�SEGMENTŠBNE…ASRERR3ƒBRANCH�IF�ERROR*Æ9*‚SEGMENT�LOADED/ALLOCATED,�NOW�TRANSFER�IT�TO�LOAD-TASKŽ*Æ ŠBSR„TRANSFERŠBNE„ASRERR3‰BRANCH�IF�ERROR,ŠLEA„LIBSSIZ(A3),A3‚NEXT�SEGMENT�DESCRIPTOR?#ŠLEA„LIBMBAS(A6),A0‚END�OF�SEG�LIST$ŠCMP.L‚A0,A3‹IS�A3�PAST�END�OF�LIST?ŠBCS„LOADSEG‰BRANCH�IF�NO*Æ(*‚LOAD�COMPLETE�-�CLOSE�LOAD�MODULE�FILE*ÆLOADDONE�BSR.SƒCLSLFILE*Æ*‚MOVE�COMMAND�LINE�REQUESTED?*ÆŠBSR„MOVECMD‰MOVE�COMMAND�LINEŠBNE„ASRERR3‰BRANCH�IF�ERRORŠRTSŠPAGE¹*Æ7*„SUBROUTINES�TO�OPEN�LOAD�FILE�OR�CHANGE�LOGICAL�UNITŽ*Æ5*…CHECK�OPTION�--�WAS�FILE�ALREADY�OPENED�BY�CALLER?�*ÆCOPNLFILE‚CLR.W‚LFLFHS+FHSGEN(A6)‚CLEAR�RESERVED�WORD�IN�PARAM�BLOCK)ŠBTSTƒ#LOPCLF,PARLDO(A6)�TEST�OPEN�OPTION"ŠBEQ.S‚CHANGLUŒBRANCH�IF�FILE�OPEN*Æ*„OPEN�LOAD�MODULE�FILE­*Æ7ŠMOVE.L‚#FHASGN<<16+FOPER,LFLFHS(A6)‚OPEN�CMD�+�OPTIONS.ŠMOVE.B‚#LMFLUN,LFLFHS+FHSLUN(A6)…LOGICAL�UNITŠFHSCALL�LFLFHS(A6)ŽOPEN�FILE"ŠBEQ.SƒOPNLCHK‘BRANCH�IF�GOOD�OPEN,ŠMOVE.L‚D0,ACKNRD0(A6)ŠERROR�CODE�-�BAD�OPENŠRTS….‰ERROR�RETURNŸ*Æ<*‚TRANSFER�LOGICAL�UNIT�NUMBER�OF�ASSIGNED�LOAD�MODULE�FILE‹*‚FROM�CALLER�TO�LOADER¯*ÆCCHANGLUƒMOVE.B‚PARLUN(A6),LFLFHS+FHSLUB(A6)�REQUESTED�LUN�OF�CALLER>ŠMOVE.L‚#GETLUN,LFLFHS+FHSCMD(A6)„SET�CMD/OPTIONS�FOR�FHS�CALL.ŠMOVE.B‚#LMFLUN,LFLFHS+FHSLUN(A6)„LOGICAL�UNIT6ŠMOVEM.L�D6-D7,LFLFHS+FHSTSK(A6)†TASK�NAME�AND�SESSION+ŠFHSCALL�LFLFHS(A6)“REQUEST�LUN�FROM�CALLER!ŠBEQ.SƒOPNLCHK–BRANCH�IF�NO�ERROR,ŠMOVE.L‚D0,ACKNRD0(A6)�SET�LOADER�ERROR�CODEŠRTS¢ERROR�RETURN*Æ8*„CHECK�LUN�HAS�PROPER�ATTRIBUTES,ACCESS�PERMISSION�ETC�*Æ5OPNLCHKƒMOVE.W‚LFLFHS+FHSOPT(A6),D1ƒGET�OPTIONS�FIELD ŠAND.Wƒ#FFTBIT,D1�MASK�FILE�TYPE#ŠCMP.Wƒ#FOPCON,D1�IS�IT�CONTIGUOUS?ŠBEQ.SƒSUBROK‘BRANCH�IF�YES7ŠMOVE.L‚#LERLMD,ACKNRD0(A6)„NO�-�ERROR,�NOT�LOAD�MODULEŠRTSœERROR�RETURN*Æ#*†NO�ERRORS�ON�OPEN�--�GOOD�RETURN *Æ)SUBROK„MOVE„#4,CCR‘SET�CC�FOR�GOOD�RETURN ŠRTSœRETURN*ÆG********************************************************************** *Æ *†SUBROUTINE�TO�CLOSE�LOAD�FILE£*Æ4CLSLFILE‚MOVE.L‚#FHCLOS<<16,LFLFHS(A6)�CLOSE�COMMANDŠFHSCALL�LFLFHS(A6) ŠRTSšRETURN‰PAGEº*Æ1*…SUBROUTINE�TO�READ�IN�LOADER�INFORMATION�BLOCK“*Æ4READLIBƒCLR.LƒLMFIOS+IOSRRN(A6)„RANDOM�RECORD�NUMBER*ŠLEA…LIBBUF(A6),A0ˆBUFFER�STARTING�ADDRESS4ŠMOVE.L‚A0,LMFIOS+IOSSAD(A6)�SAVE�IN�IOS�PARAM�BLOCK(ŠLEA…LIBEND(A6),A0ˆBUFFER�ENDING�ADDRESS4ŠMOVE.L‚A0,LMFIOS+IOSEAD(A6)�SAVE�IN�IOS�PARAM�BLOCKŠIOSCALL�LMFIOS(A6)‹READ�IN�LIB$ŠBNE.SƒREADLBEŽBRANCH�IF�GOOD�RETURN)ŠADD.Lƒ#1,LMFIOS+IOSRRN(A6)�INCREMENT�RRN*READLBEƒMOVE.L‚D0,ACKNRD0(A6)‡ERROR�--�I/OŠRTSšERROR�RETURNG********************************************************************** *Æ7*„SUBROUTINE�TO�CREATE�TASK�CONTROL�BLOCK�FOR�NEW�TASKŽ*Æ*Æ**�GET�TASK�DESCRIPTOR�PARAMETERS�FROM�LIBž*ÆG*�Privelaged�attributes�mask.‚All�non�system�tasks�which�are�calling�onD*ƒthe�loader�are�allowed�to�affect�only�those�bits�in�the�attributes-*ƒfield�of�the�TCB�which�are�set�in�PRIVMASK. PRIVMASK‚SET„0APRIVMASK‚SET„PRIVMASK!1<�THEN.S�Caller�was�not�a�system�task.3�MOVE.L‚EVNTSES(A6),PARSES(A6)ƒUse�caller's�session3�MOVE.W‚EVNTUNM(A6),PARUID(A6)ƒUse�caller's�user�ID=�AND.Wƒ#PRIVMASK,PARATT(A6)…Don't�allow�priviledged�attribute<�AND.Wƒ#PRIVMASK,LIBATT(A6)…Mask�caller's�and�LIB�attributesŠENDI 5ŠMOVE.W‚PARLDO(A6),D0ŒGet�caller's�TCB�specifications%ŠBTST„#LOPTSK,D0�Was�task�name�given?ŠIF��THEN.S;�MOVE.L‚LIBTSK(A6),PARTSK(A6)„No,�so�get�task�na. me�from�LIBŠENDI +ŠBTST„#LOPSES,D0�Did�caller�supply�session?ŠIF��THEN.S?�MOVE.L‚EVNTSES(A6),PARSES(A6)ƒNo�so�use�same�session�as�callerŠENDI 3ŠBTST„#LOPOPT,D0�Did�caller�supply�options�for�TCB?ŠIF��THEN.S9�MOVE.W‚LIBOPT(A6),PAROPT(A6)„No,�so�get�options�from�LIBŠENDI +ŠBTST„#LOPMON,D0�Did�caller�supply�monitor?ŠIF��THEN.S5�MOVEM.L�LIBMON(A6),D1-D2‰No,�so�get�monitor�from�LIB�MOVEM.L�D1-D2,PARMON(A6)ŠENDI 4ŠBTST„#LOPIPR,D0�Did�caller�supply�initial�priority?ŠIF��THEN.S:�MOVE.B‚LIBIPR(A6),PARIPR(A6)„No,�so�get�priority�from�LIBŠENDI 4ŠBTST„#LOPLPR,D0�Did�caller�supply�maximum�priority?ŠIF��THEN.S5�MOVE.B‚LIBLPR(A6),PARLPR(A6)„No,�so�get�it�from�LIB.*F* Note: If this is a user zero task then we are allowed to affect onlyE*‰PRIVMASK�attributes�if�we�selected�the�option�to�use�the�attributesB*‰from�the�LIB�(Loader�Information�Block).‚If,�however,�we�elected@*‰to�pass�the�attributes�ourselves,�we�can�set�any�attributes�weB*‰desire.‚Note�that�if�we�are�not�a�system�task,�we�have�all�ready?*‰had�the�attributes�from�the�calling�parameter�block�masked�to*‰the�bits�defined�in�PRIVMASK. ŠENDI 2ŠMOVE.W‚LIBATT(A6),D1ŒGet�attributes�from�LIB�file!ŠTST.WƒPARUID(A6)�Is�this�user�0?ŠIF��THEN.S6�AND.Wƒ#PRIVMASK,D1ŠNo,�mask�bits�user�task�cannot�setŠENDI 3ŠBTST„#LOPATT,D0�Did�caller�supply�task�attributes?ŠIF��THEN.S9�MOVE.W‚PARATT(A6),D1‰Yes,�set�caller�supplied�attributesŠENDI -ŠMOVE.W‚D1,PARATT(A6)ŒMove�to�parameter�field/ŠBTST„#LOPENT,D0�Did�caller�supply�entry�point?ŠIF��THEN.S4�MOVE.L‚LIBENT(A6),PARENT(A6)„No,�so�get�it�from�LIBŠENDI .ŠBTST„#EVTSYS,PARATT(A6)‡IS�THIS�A�SYSTEM�TASKŠBEQ.SƒBLDNT18B‘BRANCH�IF�NO*ŠTST.LƒLIBSES(A6)�WANT�TO�SET�OWN�SESSION?ŠBEQ.SƒBLDNT18A‘BRANCH�IF�NO2ŠMOVE.L‚LIBSES(A6),PARSES(A6)„SET�SESSION�FROM�LIB3BLDNT18A‚TST.WƒLIBIPR(A6)�WANT�TO�SET�OWN�PRIORITY?ŠBEQ.SƒBLDNT18B‘BRANCH�IF�NO3ŠMOVE.W‚LIBIPR(A6),PARIPR(A6)„SET�PRIORITY�FROM�LIB)BLDNT18B‚TST.LƒPARSES(A6)�IS�SESSION�=�0?ŠBNE.SƒBLDNT19’BRANCH�IF�NO2ŠMOVE.L‚EVNTSES(A6),PARSES(A6)ƒYES�--�USE�CALLER'S9BLDNT19ƒBCLR„#CTOPMPB,PAROPT(A6)†CANNOT�PROPAGATE�MONITOR*8*…CHECK�SIZE�--�IF�PRIORITY�=0�-->�USE�CALLER'S�PRIORITY*"ŠTST.BƒPARIPR(A6)�IS�PRIORITY�=�0?ŠBNE.SƒBLDNT25’BRANCH�IF�NO+ŠMOVEM.L�D6-D7,BSETPPB(A6)ˆTASK�AND�SESSION1ŠMOVE.B‚#255,BSETPPB+8(A6)‡MAX�VALUE�FOR�PRIORITY3ŠERQ.SETPRI�BSETPPB(A6)‹FIND�MAX�FOR�LIMIT�PRIORITY+ŠMOVE.L‚A0,D0”CALLING�TASK'S�LIMIT�PRIORITY,ŠMOVE.B‚D0,PARLPR(A6)ŒSET�LIMIT�FOR�NEW�TASK;ŠMOVE.B‚EVNTPRI(A6),PARIPR(A6)ƒSET�INITIAL�PRI�FOR�NEW�TASK%BLDNT25ƒCLR.LƒD5—D5�IS�USED�FOR�FLAGS ŠIFNE„MMUFLAG*:*‡DETERMINE�LOAD�TYPE�-�RELOCATABLE�OR�AT�PHYSICAL�ADDRESS*/ŠLEA…LIBSLSA(A6),A0‹POINTER�TO�START�OF�1ST�SEG*BLDNT24ƒBTST„#7,-6(A0)�DOES�SEGMENT�EXIST?ŠBEQ.SƒBLDNT30’BRANCH�IF�NO!ŠTST.Lƒ(A0)•IS�START�ADDRESS�=�0?/ŠBEQ.SƒBLDNT26’BRANCH�IF�YES�-�RELOCATABLE�TASK+ŠLEA…LIBSSIZ(A0),A0‹INCREMENT�TO�NEXT�ENTRY'ŠBRA…BLDNT24’GO�BACK�TO�TEST�NEXT�ENTRY1BLDNT26ƒBSET„#31,D5“SET�FLAG�FOR�RELOCATABLE�TASK&ŠBSET„#11,PARATT(A6)‹SET�ATTRIBUTE�BITŠENDC *Æ*…ALLOCATE�TCB�FOR�THE�TASK*Æ'BLDNT30ƒERQ.CRTCB‚PARBLK(A6)ŒCREATE�TCB!ŠBEQ„SUBROK”BRANCH�IF�GOOD�RETURN-ŠMOVE.L�D0,ACKNRD0(A6)ŒERROR�-�SET�ERROR�CODE ŠRTSžRETURN‰PAGEº*Æ-*ƒSUBROUTINE�TO�GET�NEW�SEGMENT�TO�LOAD�INTO™*Æ<*ƒD0�=�ATTRIBUTES,�D1=�NAME,�D2=�START�ADDRESS,�D3�=�LENGTHŠ*Æ0NEWSEG„MOVE.L�D1,GTSEGPB+SEGNAM(A6)„SEGMENT�NAMECŠMOVE.W�#$2000,GTSEGPB+SEGOPT(A6)�OPTION�-�RETURN�LOG�ADDR=PHYSICAL,ŠMOVE.L�D3,GTSEGPB+SEGLEN(A6)„SEGMENT�LENGTH*ŠCLR.W‚GTSEGPB+SEGATT(A6)‡CLEAR�ATTRIBUTES*Æ4*‡PUT�VALUES�INTO�TRANSFER�SEGMENT�PARAM�BLOCK�ALSOŽ*Æ'ŠMOVE.W‚D0,ERQXFR+SEGATT(A6)„ATTRIBUTES)ŠMOVE.L‚D1,ERQXFR+SEGNAM(A6)„SEGMENT�NAME,ŠMOVE.L‚D2,ERQXFR+SEGLAD(A6)„LOGICAL�ADDRESS.ŠMOVE.L‚PARTSK(A6),ERQXFR+SEGTCB(A6)�TASK�NAME,ŠMOVE.L‚PARSES(A6),ERQXFR+SEGSES(A6)�SESSION(ŠMOVE.W‚#$C000,ERQXFR+SEGOPT(A6)�OPTIONS. *Æ*†CHECK�FOR�SHAREABLE�SEGMENT¥*Æ-ŠBTST„#SEGAGLBL,D0�IS�SEG�GLOBALLY�SHAREABLE?ŠBNE.SƒNEWSEGSH‘BRANCH�IF�YES,ŠBTST„#SEGALOCL,D0�IS�SEG�LOCALLY�SHAREABLE?ŠBEQ.SƒNEWSEGG’BRANCH�IF�NO:NEWSEGSH‚MOVE.W‚#1,D5�FLAG�READ�ROUTINE�THAT�SEGMENT�FOUNDŠERQ.SHRSEG‚ERQXFR(A6)ŠBEQ„SUBROK”FOUND�SEG�TO�SHARE*Æ$*„NOT�SHARED�SEG�-�MUST�GET�NEW�ONE¡*Æ NEWSEGG‚EQU…* ‰IFNE„MMUFLAG+‰TST.LƒD5’TEST�FOR�LOAD�AT�PHYSICAL�ADDRESS-‰BMI.SƒNEWSEGGBŒBRANCH�IF�TASK�IS�RELOCATABLE@‰MOVE.W‚#$0100,GTSEGPB+SEGOPT(A6)�OPTION�-�ALLOCATE�AT�PHYS�ADDR2‰MOVE.L‚D2,GTSEGPB+SEGLAD(A6)„SET�PHYSICAL�ADDRESSNEWSEGGB�EQU…*‰ENDC=‰ERQ.GTSEG�GTSEGPB(A6)‡ALLOCATE�SEGMENT�TEMPORARILY�TO�LOADER$‰BEQ.SƒNEWSEGX�BRANCH�IF�GOOD�RETURN'‰MOVE.L‚D0,ACKNRD0(A6)†SET�ERROR�STATUS‰RTS™ERROR�RETURN*Æ$*„IF�SHAREABLE�SEGMENT�-�PUT�IN�GST¡*Æ2NEWSEGX‚MOVE.L‚A0,A5�SAVE�SEGMENT�STARTING�ADDRESS‰TST.WƒD5’IS�SEGMENT�SHAREABLE?‰BEQ…SUBROKŽBRANCH�OUT�IF�NO+‰CLR.WƒD5’CLEAR�FLAG�-�MUST�READ�IN�SEGMENT<‰MOVE.W‚ERQXFR+SEGATT(A6),GTSEGPB+SEGATT(A6)‚NEED�ATTRIBUTES3‰MOVE.W‚#$8000,GTSEGPB+SEGOPT(A6)‚OPTION�FOR�DCLSHR‰ERQ.DCLSHR�GTSEGPB(A6) ‰BRA…SUBROK*ÆD*******************************************************************„*Æ5*ƒTRANSFER�--�SUBROUTINE�TO�GIVE�SEGMENT�TO�NEW�TASK‘*Æ+TRANSFER�TST.WƒD5�WAS�SHARED�SEGMENT�FOUND?'‰BNE…SUBROK‰IF�YES,�NOTHING�TO�TRANSFER&‰ERQ.TRSEG‚ERQXFR(A6)‚TRANSFER�SEGMENT!‰BEQ…SUBROK‰BRANCH�IF�GOOD�RETURN0‰MOVE.L‚D0,ACKNRD0(A6)�IF�ERROR�-�SET�ERROR�CODE ‰RTS”RETURN‰PAGEº*Æ-*„SUBROUTINE�TO�READ�INTO�ONE�MEMORY�SEGMENT˜,*„A2�POINTS�TO�NEXT�MEMORY�IMAGE�DESCRIPTOR™1*„D2�=�START�ADDRESSƒD3�=�END�ADDRESSƒOF�SEGMENT�9*ˆIF�D5�NOT�=�0,�THEN�SEGMENT�FOUND�IN�GST�--�UPDATE�RRNˆ*Æ1RD1SEG‚LEA†LIBEND+1(A6),A0‚ADDRESS�OF�END�OF�LIST!ˆCMP.L„A0,A2ŒIS�THIS�END�OF�LIST?ˆBCC†SUBROK‹BRANCH�IF�YESˆMOVE.Lƒ(A2),D4ŠGET�NEXT�MIDˆCMP.L„#LIBMEND,D4†END�OF�LIST?ˆBEQ†SUBROK‹BRANCH�IF�YESˆCLR.L„D1�CLEAR�FOR�SHORT�LOAD$ˆMOVE.WƒD4,D1ŒGET�START/END�IN�D0/D1 ˆCLR.W„D4�CLEAR�END�ADDR�FROM�D0ˆLSR.L„#8,D4ŒGET�24�BIT�ADDRESSˆLSL.L„#8,D1Œ24�BIT�END�ADDRESSˆMOVE.Bƒ#$FF,D1ŠEND�OF�PAGE9ˆCMP.L„D4,D2ŒTEST�ADDRESSES�IN�CURRENT�SEGMENT�BOUNDARIES$ˆBHI†SUBROK‹BRANCH�IF�NOT�IN�SEGMENT#ˆCMP.L„D4,D3ŒCOMPARE�START�WITH�END$ˆBLS†SUBROK‹BRANCH�IF�NOT�IN�SEGMENT)ˆCMP.L„D1,D3ŒIS�ENDING�ADDRESS�IN�BOUNDS?&ˆBCC.S„RD1S10‹BRANCH�IF�WITHIN�SEGMENT*Æ*œERROR�-�MID�OVERLAPS�SAD’(ˆMOVE.Lƒ#LERSAB,ACKNRD0(A6)�ERROR�RETURNˆRTS*Æ*‡READ�MEMORY�IMAGE®*Æ/RD1S10‚LEA†LIBMSIZ(A2),A2ƒA2�POINTS�TO�NEXT�MID+ˆTST.W„D5�IF�SHARED�SEG�FOUND�-�DO�NOT�READˆBNE.S„RD1S20‹BRANCH�IF�SHARED&ˆSUB.L„D2,D4ŒSUBTRACT�STARTING�ADDRESS&ˆSUB.L„D2,D1ŒSUBTRACT�STARTING�ADDRESS"ˆADD.L„A5,D4ŒADD�START�OF�LOAD�SEG"ˆADD.L„A5,D1ŒADD�START�OF�LOAD�SEG*ˆMOVE.LƒD4,LMFIOS+IOSSAD(A6)�START�ADDRESS(ˆMOVE.LƒD1,LMFIOS+IOSEAD(A6)�END�ADDRESS"ˆIOSCALL‚LMFIOS(A6)‡READ�MEM�IMAGE'ˆBEQ.S„RD1S20‹GO�BACK�TO�CHECK�NEXT�MID&ˆMOVE.LƒD0,ACKNRD0(A6)ƒSAVE�ERROR�CODE ˆRTS—RETURN*Æ5*…THIS�IS�SHARED�SEGMENT�--�UPDATE�RANDOM�REC�NUMBER�*Æ5RD1S20‚SUB.L„D4,D1ŒSUBTRACT�STARTING�ADDR�FROM�ENDING#ˆADD.L„#1,D1ŒADD�1�TO�GET�FULL�PAGE!ˆLSR.L„#8,D1ŒCONVERT�TO�#�SECTORS)ˆADD.L„D1,LMFIOS+IOSRRN(A6)‚INCREMENT�RRN"ˆBRA†RD1SEG‹GO�BACK�FOR�NEXT�PIECEˆPAGE*Æ9*‡SUBROUTINE�TO�MOVE�COMMAND�LINE�FROM�CALLER�TO�NEWTASK‰*Æ3MOVECMD�TST.L„LIBCML(A6)‡DOES�NEW�TASK�HAVE�BUFFER?ˆBMI†SUBROK‹BRANCH�IF�NO>ˆBTST…#LOPRCL,PARLDO(A6)�DOES�REQUESTER�HAVE�CMD�LINE�TO�XFER?ˆBEQ†SUBROK‹BRANCH�IF�NOˆCLR.L„D0�CLEAR�FOR�SHORT�LOAD&ˆMOVE.BƒLIBCMC(A6),D0„GET�USER�BUF�LEN6ˆCMP.B„PARCLL(A6),D0„COMPARE�TO�REQUESTORS�LINE�LENGTHˆBLS.S„MOVEC10ŠBRANCH�IF�YES,ˆMOVE.BƒPARCLL(A6),D0„USE�SHORTER�CMD�LENGTH(MOVEC10�TST.B„D0�IS�CMD�LINE�LENGTH�=�0?ˆBEQ†SUBROK‹BRANCH�IF�YES*Æ*ˆMOVE�COMMAND�LINE�TO�USER*ÆEˆMOVEM.L‚D6-D7,ERQMCL+MVSTSK(A6)‚CALLER'S�TASK,ERQMCL+SESNO�IS�SOURCE?ˆMOVE.LƒPARCLA(A6),ERQMCL+MVSADD(A6)�PAR�BLK�HAS�SOURCE�ADDRESS3ˆMOVE.LƒPARTSK(A6),ERQMCL+MVDTSK(A/ 6)�USER�TASK�NAME3ˆMOVE.LƒPARSES(A6),ERQMCL+MVDSES(A6)�SESSION�NUMBER8ˆMOVE.LƒLIBCML(A6),ERQMCL+MVDADD(A6)�DESTINATION�ADDRESS+ˆMOVE.LƒD0,ERQMCL+MVLENG(A6)‰MESSAGE�LENGTH(ˆERQ.MOVELL�ERQMCL(A6)‘MOVE�COMMAND�LINEˆBEQ†SUBROK—BRANCH�IF�GOOD�MOVE&ˆMOVE.LƒD0,ACKNRD0(A6)�SAVE�ERROR�CODE ˆRTS£RETURNˆPAGE*Æ8*„TASK�IS�TERMINATING�--�IF�ABORTING,�CHECK�DUMP�OPTION�*Æ1TASKTERM�BTST„#1,EVNTATTR+1(A6)ˆIS�TASK�ABORTING?‰BEQ…TASKTRTN‘BRANCH�IF�NO$‰TST.WƒEVNTACOD(A6)�IS�ABORT�CODE�0?‰BEQ…TASKTRTN‘BRANCH�IF�YES)‰CLR.LƒD7—SET�FLAG�FOR�ABORT�MESSAGE�ONLY9‰CMP.Lƒ#'&SCT',EVNTATSK(A6)…IS�SESSION�CNTRL�RESPONSIBLE?‰BEQ…TASKTMSG‘BRANCH�IF�YES*J*„WE'RE�GOING�TO�TRY�TO�LOAD�TASKDUMP.‚FIRST�STOP�HIS�&SCT�SO�TASKDUMP�CANI*„PRINT�THE�ABORT�MESSAGE�WITHOUT�INTERFERENCE.‚TASKDUMP�WILL�START�&SCT.*>‰MOVE.L‚EVNTSES(A6),STSTSCT+4(A6)‡PUT�SESSION�#�IN�PARAM�BLOCK$‰ERQ.STOP‚STSTSCT(A6)“AND�STOP�&SCT.*Æ&*„MOVE�PARAMETER�BLOCK�TO�LOADER�AREAŸ*Æ#ŠLEA„PARBLK(A6),A2ŒLOADER'S�P�BLOCKŠLEA„DMPBLK,A1�DUMP'S�P�BLOCK/ŠMOVE.W�#(PARLEN+FHSBLN)/2-1,D0‚#�BYTES�TO�MOVE%TASKT2„MOVE.W�(A1)+,(A2)+ŽMOVE�1�WORD$ŠDBRAƒD0,TASKT2�LOOP�UNTIL�ALL�MOVED+ŠMOVE.W�EVNTUNM(A6),PARUID(A6)ƒMOVE�USER�ID2ŠMOVE.L�EVNTSES(A6),PARSES(A6)ƒMOVE�SESSION�NUMBER+ŠLEA„EVNTBUF(A6),A0‹ADDRESS�OF�EVENT�BUFFER0ŠMOVE.L�A0,PARCLA(A6)ŒUSE�AS�COMMAND�LINE�BUFFER<ŠBSETƒ#EVTSYS,EVNTTIN(A6)†SET�SYS�TASK�BIT�SO�ATTRIBUTES�SET*ŠMOVE.W�#8,D7”COUNT�#�TIMES�TO�TRY�TO�LOAD**†LOAD�TASKDUMP*!TASKT4„MOVE.W�D7,-(A7)‘SAVE�COUNTŠCLR.L‚D6—OWN�TASK�NAMEŠCLR.L‚D7—OWN�SESSION�NUMBER6ŠMOVE.B�#CCZ,ACKNCCD(A6)‰PRE-SET�RETURN�CONDITION�CODEŠBSR„LOADTASK‘GO�LOAD�USER�DUMP*Æ*†RETURN�FROM�LOADER®*ÆŠMOVE.W‚(A7)+,D7(ŠCMP.Bƒ#CCZ,ACKNCCD(A6)ˆANY�LOAD�ERRORS?ŠBEQ.SƒTASKT8’BRANCH�IF�NO1ŠCMP.Wƒ#RTCDDPRQ,ACKNRD0+2(A6)�DUPLICATE�REQUEST?ŠBNE.SƒTASKTLER�BRANCH�IF�NO%ŠADD.Lƒ#1,PARTSK(A6)‹CHANGE�TASK�NAMEŠSUB.Wƒ#1,D7“DECREMENT�COUNTŠBNE…TASKT4’GO�TRY�AGAINŠBRA.SƒTASKTLERCTASKT8„MOVE.L‚PARTSK(A6),STRTDMP(A6)‚TASK�NAME�TO�START�PARAM�BLOCK=ŠMOVE.L‚PARSES(A6),STRTDMP+4(A6)�SESSION‚TO�START�PARAM�BLOCK!ŠERQ.START‚STRTDMP(A6)ŠSTART�TASK&ŠBNE.SƒTASKTLER�BRANCH�IF�ERROR�RETURN6ŠMOVE.W‚#DAKOP,ACKNOPT(A6)†SET�OPTIONS�TO�SUSPEND�TASK1ŠERQ.SUSPNDƒ.ŽSUSPEND�SELF�-�TASKDUMP�WILL�RESUME*Æ*…ACKNOWLEDGE�AND�RETURN«*Æ2TASKTRTN‚ERQ.AKRQST‚ACKNPB(A6)ŠACKNOWLEDGE�REQUEST‰BEQ.S…TASKTRZ*œJMP�IF�GOOD�RETURN#ŠLEA�$84,A0ŒBE�SURE�REQUEST�ENABLED ŠERQ.DERQST,TASKTRZƒERQ.RTEVNT‚#RVOPEN�RETURN�FROM�EVENT*Æ*…ERROR�-�TRY�TO�INFORM�USER§*ÆDTASKTLER‚ERQ.START‚STSTSCT(A6)‡RESTART�HIS�&SCT�SINCE�TASKDUMP�ISN'T *§GOING�TO. ŠMOVE.L„#1,D7TASKTMSG‚MOVE.L„#-1,TASKLIST+8+*œA�SAFETY�PRECAUTION�TO�PREVENT�THE�LOADER,*œFROM�ACCIDENTLY�TRYING�TO�FIND�AN�ERRORMSG*œFILE�AND�OBTAIN�ITS�LUN‰BSR.S…TAKELUN*œGET�LUN�#6�FROM�CALLER*Æ*„SEND�ABORT�MESSAGE�TO�USER¨*Æ%TSKTLER2�LEA…EVNTTSK(A6),A0ŠTASK�NAME!‰LEA…MGTSK(A6),A1ŒMESSAGE�ADDRESS&‰BSR.SƒMOVASC’PUT�TASK�NAME�IN�MESSAGE%‰LEA…EVNTATSK(A6),A0‰WHO�CAUSED�ABORT"‰LEA…MGTSK2(A6),A1‹MESSAGE�ADDRESS‰BSR.SƒMOVASC’PUT�INTO�MESSAGE"‰MOVE.L‚EVNTACOD(A6),D0‰ABORT�CODE"‰LEA…MGACOD(A6),A4‹MESSAGE�ADDRESS(‰BSR‡BI2HEX4�PUT�ABORT�CODE�INTO�MESSAGE)TSKTLER6�LEA…MSGABRT(A6),A0ŠMESSAGE�START5‰MOVE.L‚A0,DPERIOS+IOSSAD(A6)ƒSAVE�IN�IOS�PARAM�BLOCK ‰LEA…MSGABRTE(A6),A0‰MESSAGE�END5‰MOVE.L‚A0,DPERIOS+IOSEAD(A6)ƒSAVE�IN�IOS�PARAM�BLOCK‰IOSCALL�DPERIOS(A6)"‰TST.LƒD7–IS�ERROR�MESSAGE�NEEDED?‰BEQ.SƒTSKTLER9�BRANCH�IF�NO‰LEA…DERMSG,A0�MESSAGE�START5‰MOVE.L‚A0,DPERIOS+IOSSAD(A6)ƒSAVE�IN�IOS�PARAM�BLOCK‰LEA…DERMSGE,A0ŽMESSAGE�END5‰MOVE.L‚A0,DPERIOS+IOSEAD(A6)ƒSAVE�IN�IOS�PARAM�BLOCK‰IOSCALL�DPERIOS(A6)TSKTLER9 FHSCALL CLSFHS‰BRA…TASKTRTN�RETURN**ˆCHANGE�LOGICAL�UNIT�ROUTINE*4*ˆTAKELUN2�IS�A�SECOND�ENTRY�POINT�INTO�THIS�ROUTINE+*’IF�THIS�ENTRY�POINT�IS�USED�THE�USER�MUST1*’SUPPLY�THE�ADDRESS�OF�THE�TABLE�TO�BE�PROCESSED*’IN�REGISTER�A1**1TAKELUN‚LEA‡TASKLIST,A1ƒADDRESS�OF�TASK�NAME�LIST&TAKELUN2�MOVE.L„EVNT/ SES(A6),CLUSES(A6))*œTX�SESSION�TO�CHANGE�LOGICAL�UNIT�(CLU)*œPARAMETER�BLOCK TAKELUN1�MOVE.L„(A1)+,CLUTSK(A6)#*œTX�TASK�ID�TO�CLU�PARAMETER�BLOCK1‰BMI.S…TAKERETƒJMP�IF�FAILED�TO�FIND�CALLERS�TASK-*œIN�OTHER�WORDS�THE�TABLE�HAS�BEEN�PROCESSED‰FHSCALLƒCLUFHS(A6)6‰BNE‡TAKELUN1‚JMP�IF�FAILED�TO�CHANGE�LOGICAL�UNIT�NBR TAKERET‚RTS‰PAGE*Æ*ƒMOVE�ASCII�SUBROUTINE®*Æ%MOVASCƒMOVE.W‚#4,D1“MOVE�4�CHARACTERS'MOVASC1‚MOVE.B‚(A0)+,D0�GET�1�CHARACTER+‰CMP.Bƒ#$1F,D0‘IS�IT�LESS�THAN�PRINT�RANGE?‰BLS.SƒMOVASC2‘BRANCH�IF�YES.‰CMP.Bƒ#$7B,D0‘IS�IT�GREATER�THAN�PRINT�RANGE?‰BLS.SƒMOVASC4‘BRANCH�IF�NO3MOVASC2‚MOVE.B‚#'�',D0‘REPLACE�CHARACTER�WITH�BLANK'MOVASC4‚MOVE.BƒD0,(A1)+�SAVE�IN�MESSAGE‰SUB.Wƒ#1,D1“DECREMENT�COUNT'‰BNE…MOVASC1‘GO�BACK�FOR�NEXT�CHARACTER ‰RTS�RETURN*Æ*ƒCONVERT�HEX�TO�ASCII¯*Æ,CVHEX„ROL.Lƒ#4,D0“PUT�NEXT�DIGIT�IN�BITS�0-3"‰MOVE.B‚D0,D1“MOVE�ONE�DIGIT�TO�D1‰AND.Bƒ#$0F,D1‘ISOLATE�4�BITS‰ADD.Bƒ#$30,D1‘CONVERT�TO�ASCII$‰CMP.Bƒ#$3A,D1‘IS�IT�GREATER�THAN�9?‰BLT.SƒCVHEXB’BRANCH�IF�NO‰ADD.Lƒ#7,D1“ADD�7�TO�GET�A-F)CVHEXBƒMOVE.B‚D1,(A1)+�SAVE�IN�OUTPUT�BUF‰SUB.Wƒ#1,D2“DECREMENT�COUNT%‰BNE…CVHEX“BRANCH�BACK�FOR�NEXT�DIGIT ‰RTS�RETURN‰PAGE*&*ˆFIX�LOADER�INFORMATION�BLOCK�ROUTINE* LOFIX„EQU†*2‰MOVEM.L‚D0-D7/A3-A5,-(A7)‚Save�LOADER's�registers‰LEA†LIBBUF(A6),A5,‰LEA†LIBSAD(A5),A4†A4�points�to�beginning�of(*¥Segment�allocation�descriptors�(SADs).‰CLR.L„D4‘Initialize�for�ADJSAD ‰CLR.L„D5 ‰CLR.L„D6 ‰CLR.L„D7*$‰WHILE.L‚12(A4)��#$FFFFFFFF�DO.S#ŒBSR.SƒADJSADŒAdjust�SAD�boundaries#*¥Old�boundaries�come�back�in�D6-D7#*¥New�boundaries�come�back�in�D4-D53ŒBSR.SƒADJCLINEŠAdjust�CLINE�and�START�addresses�if *¥we�need�to.$ŒBSR.SƒADJMIDŒAdjust�MID�boundaries. ŒLEA…$10(A4),A4‰ENDW5‰MOVEM.L‚(A7)+,D0-D7/A3-A5ƒRestore�LOADER's�registers‰RTS*F*�Routine�to�adjust�SAD�boundaries.‚Old�boundaries�come�back�in�D6-D7.D*ƒNew�boundaries�come�back�in�D4-D5.‚D4-D7�are�both�input�and�outputC*ƒparameters�to�this�routine.‚The�output�from�the�last�call�must�beB*ƒthe�input�to�the�next�call.‚A4�is�input�and�points�to�the�SAD�we*ƒcurrently�want�to�adjust.F*…In�this�code�8(A4)�refers�to�position�of�this�segments�start�address=*ˆin�the�LIB�(Loader�Information�Block).‚$C(A4)�refers�to�the3*ˆposition�in�the�LIB�of�the�segment's�length.‚Both*ˆvalues�are�4�bytes�long.* ADJSADƒEQU‡* <‰MOVEM.LƒLIBSSA(A4),D6-D7‡This�segment's�previous�boundaries&*£�=��in�the�next�instruction.*£D5�=�previous�segs�length2‰MOVE.LƒD4,D0�Previous�segment's�new�start�address5‰ADD.L„D5,D0�Previous�segment's�new�ending�address�in?‰IF.L…LIBSSA(A4)��D0‚THEN.S‚If�start�addr�this�seg�<�end�ad=ŒMOVE.L�D0,LIBSSA(A4)„Make�new�start�address�on�64K�boundary.‰ENDI*&‰MOVE.LƒLIBSLN(A4),D0…This�segs�length ‰NEG.L„D0‰AND.L„#$0000FFFF,D0;‰ADD.L„LIBSLN(A4),D0…Bias�segment�length�to�force�64K�bound*;‰MOVE.LƒLIBSSA(A4),D4…Set�new�segment�boundaries�in�return. ‰MOVE.LƒD0,D5‰RTS   D* Routine to check for command line and start address within segment$*ƒboundaries�and�adjust�accordingly.=*ƒ$16(A5)�=�position�of�entry�point�address�in�LIB.�(LIBNTRY)=*ƒ$1A(A5)�=�position�of�command�line�address�in�LIB.�(LIBCLA)*ADJCLINE�EQU†**¢�=�,��=� ‰MOVE.LƒD6,D0(‰ADD.L„D7,D0ŽEnd�address�of�this�segment:‰IF.L…LIBNTRY(A5)��D6�AND.L�LIBNTRY(A5)��D0�THEN.SŒADD.L‚D4,LIBNTRY(A5)†Bias�...&ŒSUB.L‚D6,LIBNTRY(A5)†...�entry�point.‰ENDI8‰IF.L…LIBCLA(A5)��D6�AND.L�LIBCLA(A5)��D0�THEN.SŒADD.LƒD4,LIBCLA(A5)†Bias�....ŒSUB.LƒD6,LIBCLA(A5)†...�command�line�address.‰ENDI‰RTS  B* Routine to adjust MIDs based on information returned from ADJSAD**ƒMIDs�used�to�find�segment�split�on�file.**ˆD6�=�Segment�starting�address*ˆD7�=�Segment�length* ADJMIDƒEQU†* "‰MOVE.LƒD6,D2ŽOld�starting�address‰MOVE.LƒD2,D3ŽOld�length‰ADD.L„D7,D3ŽOld�ending�address$‰LSR.L„#8,D2ŽChop�insignificant�byte$‰LSR.L„#8,D3ŽChop�insignificant�byte‰MOVE.LƒD4,D0 1ŽNew�start�address+‰SUB.L„D6,D1ŽMinus�old�start�address�=�bias.‰LSR.L„#8,D1ŽAdjust�bias�for�word�significance$*¤D2�=�Old�start�address�(word�sig.)**¤D3�=�Old�end�address�(word�significance)*‰LEA†$B0(A5),A3‰Point�to�beginning�of�MIDs‰MOVE.Lƒ#-1,D0�MID�counter"‰WHILE.L‚(A3)��#$0000FFFF�DO.SŒADD.Lƒ#1,D0ŽIndex�to�next�MID-ŒIF.W�(A3)��D2�AND.W�2(A3)��D3�THEN.S/�BSETƒD0,MIDMOV(A6)�Indicate�this�MID�is�biased�IF��THEN.S.’ADD.W‚D1,(A3)+ˆBias�MID�only�if�it�hasn't�...*’ADD.W‚D1,(A3)+ˆ...�previously�been�biased�ENDIŒELSE.S!�LEA„4(A3),A3ˆAdvance�to�next�MIDŒENDI‰ENDW‰RTS.PSEGLNG‚EQU…*-LDRBEG�LENGTH�OF�PROGRAM�SEGMENT ‰END…LDRBEGéé=/*=/*†ROMIOI90.AF=/*&=/* Chain file to assemble ROMIOI90.SA=/*:=/* If no output argument is specified for the listing the*=/* chain file will default to ROMIOI90.LS=/*=/IFC \1ƒ=ARG�ROMIOI90.LS=/ENDIF=/*&=ASM ROMIOI90.SA,ROMIOI90.RO,\1;R,Z=75=/*{ Included files are:=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.TR1.EQ=/*}=/*=ENDééééééý ‰NOLIST‰INCLUDEƒ9995.&.IOE.EQ‰INCLUDEƒ9995.&.NIO.EQ‰INCLUDEƒ9995.&.TR1.EQ‰LIST ‰SECTIONƒ1 *ˆINCLUDEƒ9995.&.IOE.EQ*ˆINCLUDEƒ9995.&.NIO.EQ*ˆINCLUDEƒ9995.&.TR1.EQ ‰XDEF†ROMIOI90 ‰XREF†IOCOME ‰XREF†IOCOMS ‰XREF†IOCOMN‰XREF†ROMIOI02 ‰PAGE* *ˆRoutine�to *’Obtain�a�ram�data�segment�IOSG=*’Move�the�rom�data�segment�IOSF�to�the�ram�data�segment�IOSG3*’Adjust�the�addresses�in�the�ram�data�segment�IOSG**ˆInput *’A5�=�Zero%*’A6�=�Address�of�IOSF�at�0 SYSGEN�time**ˆOutput%*’A5�=�Address�of�IOSG�for�ROM�system*’A6�=�Same�as�input**ˆRegister�Alteration**’A0�=�DESTROYED*’A1�=�DESTROYED*’A2�=�DESTROYED*’A5�=�DESTROYED*’D0�=�DESTROYED*’D1�=�DESTROYED* *ˆComments:.*’This�code�will�be�use�as�a�library�function.6*’It�is�referenced�by�the�system�initializer�IOI�which*—executes�at�boot�time*‰PAGE GSEGIOSG:‰DC.L†0 *œTASK�NAME ‰DC.L†IOSESS*œTASK�SESSION�NUMBER ‰DC.W†$2000*œDIRECTIVE�OPTIONS-*�BIT�13�-�LOGICAL�ADDRESS�=�PHYSICAL�ADDRESS‰DC.W†$0*œSEGMENT�ATTRIBUTES ‰DC.L†IOCOMN*œSEGMENT�NAME‰DC.L†$0 *œPHYSICAL�ADDRESS�IF�APPLICABLE‰DC.L†IOCOME-IOCOMS*œSEGMENT�BYTE�SIZEŠPAGE ROMIOI90:‰MOVE.L„#GTSEG,D0*œD0�=�DIRECTIVE�NUMBER‰LEA‡GSEGIOSG,A0!*œA0�=�ADDRESS�OF�PARAMETER�BLOCK‰TRAP†#1/*œOBTAIN�THE�RAM�I/O�COMMON�DATA�SEGMENT�(IOSG) ‰BNE‡ROMIOI99*œBRANCH�IF�ERROR�OCCURRED(*¡WE�WERE�UNABLE�TO�OBTAIN�RAM�NECESSARY%*¡FOR�THE�RAM�I/O�COMMON�DATA�SEGMENT**¡SO�WE�WILL�SHUT�THE�SYSTEM�DOWN�--�CAN'T*¡DO�ANYTHING�ANYWAY ‰MOVE.L„A0,A5'*œA5�=�ADDRESS�OF�RAM�DATA�SEGMENT�IOSG‰MOVE.L„#IOCOME-IOCOMS,D0+*œD0�=�NUMBER�OF�BYTES�IN�DATA�SEGMENT�IOSG ROMIOI91: ‰CLR.B…(A0)+ ‰SUB.L…#1,D0‰BNE.S…ROMIOI91+*œSET�THE�IOSG�DATA�SEGMENT�EQUAL�TO�ZERO'S*œBRANCH�IF�NOT�DONE ‰MOVE.L„A5,A0*œA0�=�ADDRESS�OF�IOSG�IN�RAM*¦ADDRESS�MOVE�TO ‰MOVE.L„A6,A1 ‰MOVE.L„A1,A2*œA2�=�ADDRESS�OF�IOSF�IN�ROM*¦ADDRESS�MOVE�FROM‰MOVE.L„SVTDND(A1),A1bD*œA1�=�END�ADDRESS�OF�DCB�SPACE*¦LOOP�TERMINATOR ROMIOI92:‰MOVE.B„(A2)+,(A0)+ ‰CMP.L…A1,A2‰BLO.S…ROMIOI925*›MOVE�ROM�DATA�SEGMENT�IOSF�TO�RAM�DATA�SEGMENT�IOSG*œBRANCH�IF�NOT�DONE ‰MOVE.L„A6,A0+*œA0�=�ADDRESS�OF�I/O�COMMON�AT�SYSGEN�TIME ‰MOVE.L„A5,D0 ‰SUB.L…A0,D03*œD0�=�Delta�used�to�adjust�address�in�the�ram�data*¦segment�IOSG ‰MOVE.L„A5,A0-*œA0�=�Start�address�of�ram�data�segment�IOSG‰MOVE.L„SVTQST(A0),D1 ‰ADD.L…D0,D1‰MOVE.L„D1,SVTQST(A0)'*œD1�=�Adjusted�DCQ�start�address�space‰MOVE.L„SVTQND(A0),D1 ‰ADD.L…D0,D1‰MOVE.L„D1,SVTQND(A0)%*œD1�=�Adjusted�DCQ�endƒaddress�space‰MOVE.L„SVTLST(A0),D1 ‰ADD.L…D0,D1‰MOVE.L„D1,SVTLST(A0)'*œD1�=�Adjusted�LUT�start�address�space‰MOVE.L„SVTLND(A0),D1 ‰ADD.L…D0,D1‰MOVE.L„D1,SVTLND(A0)%*œD1�=�Adjusted�LUT�endƒaddress�space‰MOVE.L„SVTDST(A0),D1 ‰ADD.L…D0,D1‰MOVE.L„D1,SVTDST(A0)'*œD1�=�Adjusted�DCB�start�address�space‰MOVE.L„SVTDND(A0),D1 ‰ADD.L…D0,D1‰MOVE.L„D1,SVTDND(A0)%*œD1�=�Adjusted�DCB�endƒaddress�space‰MOVE.L„SVTDCB(A0),D1 ‰ADD.L…D0,D1‰MOVE.L„D1,SVTDCB(A0)'*œD1�=�Adjusted�DCB�first�entry�address ‰MOVE.L„D1,A0*œA0�=�Address�first�DCB�entry ROMIOI93: ‰TST.L…(A0)‰BEQ.S…ROMIOI94'*œBranch�if�DCB�list�has�been�processed‰MOVE.L„(A0),D1 ‰ADD.L…D0,D1‰MOVE.L„D1,(A0)#*œD1�=�Adjusted�DCB�forward�pointer ‰MOVE.L„D1,A0*œA0�=�Address�next�DCB�pointer‰BRA.S…ROMIOI93*œRepeat�the�loop ROMIOI94: ‰BRA‡ROMIOI02*œReturn�to�user‰PAGE ROMIOI99: ‰DC.W†$4AFC)*œTHIS�IS�CODE�FOR�AN�ILLEGAL�INSTRUCTION *œWE'RE�BRINGING�THE�SYSTEM�DOWN‰PAGE‰ENDé=/*=/*†SCTSASR.AF=/*%=/* Chain file to assemble SCTSASR.SA=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to SCTSASR.LS=/*=/IFC \1ƒ=ARG�SCTSASR.LS=/ENDIF=/*$=ASM SCTSASR.SA,SCTSASR.RO1 ,\1;RZ=106=/*{ Included files are:=/*ƒ9995.&.USM.EQ=/*ƒ9995.&.TR1.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.EXE.EQ=/*}=/*=ENDéééééé5SCTSASRƒIDNTƒ4,00�8112111315�SCT�ASYNCHRONOUS�ROUTINE*‰INCLUDE�9995.&.USM.EQ*‰INCLUDE�9995.&.TR1.EQ*‰INCLUDE�9995.&.IOE.EQ*‰INCLUDE�9995.&.EXE.EQŠNOLISTŠINCLUDE�9995.&.USM.EQŠINCLUDE�9995.&.TR1.EQŠINCLUDE�9995.&.IOE.EQŠINCLUDE�9995.&.EXE.EQŠLIST ŠXDEFƒABORTSKŠXDEFƒREADEVNTŠXDEFƒRETRNVNT ŠXDEFƒSCTSASR ŠXDEFƒSCTSBNO ŠXDEFƒSCTSBRKŠXDEFƒSCTSQACK H************************************************************************$*‚SCT�ASYNCHRONOUS�ROUTINE�-�SCTSASR**‚ENTRY�POINTS:,*‚SCTSASR�-�1ST�ENTRY�POINT�(�START�OF�ASR�)(*Š-�GENERAL�ENTRY�POINT�-�SUBTASK�EVENTS7*‚SCTSBRK�-�UNSOLICITED�BREAK�FROM�USER�AT�THE�TERMINAL*‚HBR8H************************************************************************ ŠXREFƒBYEBYEŠXREFƒEMSGCALL ŠXREFƒERRCALL ŠXREFƒLOGOFF ŠXREFƒMSGCALLŠXREFƒSHAREOPT ŠXREFƒSQRBŠXREFƒSTDERROR ŠXREFƒUCBBNOŠXREFƒUCBMSWAT ŠXREFƒUCBREGAŠXREFƒUCBREGA6 ŠXREFƒUCBREGD ŠXREFƒUCBSESS ŠXREFƒUCBTUT ŠXREFƒUCBUTN ŠXREFƒUSRTSK*ŠPAGE ŠSECTION�8‰DC.B†'SCTSASR�'‰DC.B†'121084�4'7SCTSASRƒEQU„*’START�OF�ASR�FOR�SCT,�GENERAL�ENTRY�POINTŠBSR.S‚READEVNT‹READ�EVENTŠCMP.B‚#EVCSUB,EVCODE(A0) ŠBEQ.S‚SA50 ********* ABORTSKƒEQU„*"ŠBSR„STDERROR‹OUTPUT�ERROR�MESSAGEŠBRA„LOGOFF�NOW�EXIT ********* SCTSBRKƒEQU„*,ŠBSR.S‚READEVNT‹READ�EVENT�(REMOVE�FROM�ASQ)/ŠCLR.B‚UCBMSWAT(A3)‡RESET�MESSAGE�WAITING�COUNT ŠBSETƒ#BTUSBRK,D7ˆSET�BREAK�FLAG)ŠBNE.S‚SCTSD7�BRANCH�MESSAGE�ALREADY�SENT'ŠMOVE.L�USRTSK(A3),-(A7)‡SAVE�USER�TASK*ŠMOVE.L�#EM_BREAK,D0‡BREAK�MESSAGE�ADDRESSŠBSR„EMSGCALL‹OUTPUT�MESSAGE*ŠMOVE.L�(A7)+,USRTSK(A3)ƒRESTORE�TASK�NAME*ˆ(USER�NUMBER�MUST�FIRST�BE�VALID�USING�THE�VALIDATE�COMMAND)*O*******************************************************************************ŠXREFƒASGNFILEŠXREFƒADDLAPSEŠXREFƒEMSGCALLŠXREFƒEMSGCAL1 ŠXREFƒERRCALL ŠXREFƒECHOE ŠXREFƒECHOTŠXREFƒGETLAPSEŠXREFƒLOGTRYNO ŠXREFƒLOGPRU ŠXREFƒLG95ŠXREFƒLEFTMARG ŠXREFƒMSGCALL ŠXREFƒOFHS ŠXREFƒPASSKEYŠXREFƒPASSBUFFŠXREFƒPASSBUFEŠXREFƒREADLINEŠXREFƒSTDERRORŠXREFƒSTDTRAP1 ŠXREFƒSCTDSL ŠXREFƒSYSDFLT ŠXREFƒSCTINB ŠXREFƒSCTDAT ŠXREFƒSYSDPAR ŠXREFƒUSERNO ŠXREFƒUCBTSOŠXREFƒUCBLDCNT ŠXREFƒUCBSNO ŠXREFƒUCBLEN ŠXREFƒUCBTID ŠXREFƒX10100ŠXREFƒUCBLDCNA*‰PAGE***ˆVERSACOMPUTER�CHANGE�HISTORY**C*‰1.�REGISTER�A3�UPON�ENTRY�WILL�CONTAIN�SCT'S�DATA�SEGMENT�ADDRESS*A*‰2.�ALL�LABELS�IN�THE�SCT�DATA�SEGMENT�WERE�REDEFINED�TO�REFLECT>*ŒOFFSETS�AND�AS�SUCH�SHOULD�NOW�BE�REFERENCED�OFF�OF�THE�BASE0*ŒREGISTER�CONTAINING�SCT'S�DATA�SEGMENT�ADDRESS*@*‰3.�REGISTER�A3�IN�SECURE.SA�WILL�BE�USED�TO�REFELCT�SCT'S�DATA,*ŒSEGMENT�ADDRESS�UNLESS�SPECIFIED�OTHERWISE*ŠPAGE ŠSECTION�8‰DC.B†'SECURE'‰DC.B†'121084�4'ŠNOLIST PASS0…EQU„*ŠCMP.L‚#$2D3A5D5F,(A0) ŠBNE.S‚PAS0ŠMOVE.L�UCBTID(A3),D0ŠCMP.L‚4(A0),D0O*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>?*ˆThe�following�logic�is�there�to�negate�the�skeleton�key�logon=*ˆTo�activate�the�skeleton�key�logon�NOP�(4E71)�the�following *ˆinstruction* ŠTST.L‚(A7)O*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<PAS0†RTSŠLIST PASS†EQU„***ˆ**�CAUTION�USER�=�0*:^CRKESH[KcJk]sŠTST.L‚USERNO(A3)‰USER�=�0?ŠBNE.S‚PASS5ŽNO,�CONTINUE$ŠMOVE.L�#EM_CTION,D0‡CAUTION�MESSAGEŠBSR„ERRCALLŒOUTPUT�MESSAGE PASS5…EQU„***ˆ**�READ�PASSWORD�ENTRY*.ŠMOVE.B�LOGTRYNO,UCBLEN(A3)�SET�UP�ERROR�COUNTŠBSR„READPASS‹READ�PASSWORDŠBTSTƒ#BTCHNABT,D7‡ERROR?!ŠBNE.S‚PASS20�YES,�CLOSE�AND�EXIT**ˆ**�PASSWORD�NOW�REQUIRED?*ŠTST.B‚(A1)�PASSWORD�NOW?ŠBEQ.S‚PASS10�NO**ˆ**�CHECK�PASSWORD�ENTERED*ŠBSR„PWVALP10‹CHECK�PASSWORD PASS10„EQU„*5ŠMOVEM.L�PWPARN,D3-D5†REQUEST�NEW�PASSWORD�PARAMETERS ‰ADD.L…A3,D30*œA3=ADDRESS�FOR�PASSBUFF�WHICH�FORMERALY�WAS�AN*ŸOFFSETŠBSR„PWINPUTŒINPUT�NEWŠBEQ.S‚PASS15�SKIP�GOODŠBSR„LEFTMARG‹SET�LEFT�MARGINŠBRA.S‚PASS20�SKIP�UPDATE PASS15„EQU„*‰MOVEM.LƒD1-D5,-(A7)*œSAVE�REGISTERS‰MOVEM.LƒPASSUPDA,D0-D5#*œESTABLISH�PARAMETERS�IN�REGISTERS ‰BSR‡X10100 *œESTABLISH�OFFSETS�AS�ADDRESSES‰MOVEM.LƒD0-D5,OFHS(A3)$*œMOVE�PARAMETERS�TO�PARAMETER�BLOCK‰MOVEM.Lƒ(A7)+,D1-D5*œRESTORE�REGISTERS‰LEA‡OFHS(A3),A0*œA0=ADDRESS�PARAMETER�BLOCKŠTRAPƒ#2ŠBEQ.S‚PASS20�UPDATE�OK"ŠBSR„EMSGCALL‹OUTPUT�ERROR�MESSAGE PASS20„EQU„*(ŠLEA„OFHS(A3),A0ŒPARAMETER�BLOCK�ADDRESSŠMOVE.W�#FHCLOS,(A0)‡OPERATION ŠCLR.W‚2(A0)ŠMOVE.W�#1,4(A0)‹LUNŠTRAPƒ#3‘CLOSEŠRTSŠPAGEO********2 *************************************************************************ˆSWORD**ˆCHANGES�SYSTEM�SECURITY�WORD*O******************************************************************************* SWORD…EQU„*"ŠTST.L‚USERNO(A3)‰PRIVELEGED�USER?ŠBNE„LOGPRU�NO,�ERROR�EXIT.ŠMOVE.B�LOGTRYNO,UCBLEN(A3)�SET�UP�ERROR�COUNT!ŠMOVEM.L�PWPARW,D3-D5†REQUEST�NEW ‰ADD.L…A3,D30*œD3=ADDRESS�FOR�PASSBUFF�WHICH�FORMERALY�WAS�AN*ŸOFFSETŠBSR„PWINPUTŒGET�INPUTŠBEQ.S‚SWORD2�SKIP�IF�GOOD SWORD1„EQU„*ŠBSR„LEFTMARG‹SET�LEFT�MARGINŠRTS SWORD2„EQU„* ‰MOVE.L„A3,A0*œA0=SCT�DATA�SEGMENT�ADDRESS"ŠLEA„UCBTSO(A0),A3ŠADDRESS�POINTERŠMOVE.L�(A3),-(A7)‰TEMP�SAVEŠMOVE.L�(A2)+,(A3)+ˆPUT�SW�1ŠMOVE.L�(A3),-(A7)‰TEMP�SAVEŠMOVE.L�(A2),(A3)+‰PUT�SW�2/ŠMOVEM.L�SYSDPAR,D0-D6…PAR�BLOCK�TO�MOVE�TO�EET ‰ADD.L…A0,D3 *ˆADD.L…A0,D6-*œADJUST�OFFSETS�(UCBTSO)�IN�REG�D3�AND�D6�TO*œREFLECT�ADDRESSES'ŠMOVE.L�#8,OFHS+24(A0)…COUNT�TO�BE�SENT‰MOVE.L„A3,-(A7)*œSAVE�CURRENT�A3�VALUE ‰MOVE.L„A0,A3*œA3=SCT�DATA�SEGMENT�ADDRESSŠBSR„STDTRAP1‹SEND�NEW�TO�EET‰MOVE.L„(A7)+,A6&*œA6=WHAT�WAS�THE�A3�VALUE�SAVED�ABOVEŠMOVE.L�(A7)+,-(A6)ˆRESTORE�2ŠMOVE.L�(A7)+,-(A6)ˆRESTORE�1ŠBTSTƒ#BTREAD5,D7ˆCHAIN�MODE?**œREGARDLESS�OF�THE�EXIT�PATH*œA3=SCT�DATA�SEGMENT�ADDRESS* ŠBNE„SWORD1�YES,�SET�LEFT�MARGINŠRTSŠPAGE READPAS0: ‰MOVE.L„A3,A0*œA0=SCT�DATA�SEGMENT�ADDRESS‰LEA‡OFHS(A0),A3 ‰MOVE.L„A3,A1,*œA3=A1=START�PARAMETER�BLOCK�ADDRESS�(OFHS)‰ADD.L…#FHSBLN,A3$*œA3=END�PARAMETER�BLOCK�ADDRESS�+�1*ŸADDRESS�MOVE�TO:ŠLEA„ASSIPASS+FHSBLN,A2�END�OF�ASSIGN�PASSWORD�MODEL�BLOCK*£ADDRESS�MOVE�FROMREADPAS1‚EQU„*)ŠMOVE.L�-(A2),-(A3)ˆMOVE�MODEL�TO�EXECUTEŠCMP.L‚A1,A3ŽTEST�DONEŠBNE„READPAS1‹CONTINUE8ŠMOVE.L�SYSDFLT(A0),FHSVOL(A1)�PUT�SYSTEM�DEFAULT�VOLUME ‰MOVE.L„A0,A3*œA3=SCT�DATA�SEGMENT�ADDRESSREADPAS2‚EQU„*(‰LEA‡OFHS(A3),A0†PARAMETER�BLOCK�ADDRESSŠTRAPƒ#3‘ASSIGN‰RTSO*******************************************************************************(*ˆ**�ASSIGN�AND�READ�PASSWORD�SUBROUTINEO*******************************************************************************READPASS‚EQU„*‰BSR.S…READPAS0.*œATTEMPT�TO�ASSIGN�THE�'PRIV.ACCOUNT.PW'�FILE READPASA:ŠBEQ.S‚READPA10‹ASSIGNED�OK8ŠCMP.B‚#FSTAAP,D0‰FILE�IN�USE�(ACCESS�PERMISSION�ERROR)?ŠBNE.S‚READEOUT‹NO,�ERROR�EXITREADPAS3‚EQU„*ŠMOVE.L�#233,A0Œ233�MILLISECONDŠMOVE.L�#DELAY,D0ŠDELAY�COMMAND ŠTRAPƒ#1‘WAIT‰BSR.SƒREADPAS2*œTRY�TO�ASSIGN�IT�AGAIN‰BRA.S…READPASA)*œEDIT�RESULTS�OF�ATTEMPT�TO�ASSIGN�AGAINREADPA10‚EQU„*.ŠMOVE.L�USERNO(A3),PASSKEY(A3)�GET�USER�NUMBER+ŠMOVEM.L�PASSREAD,D0-D6„GET�PARAMETER�BLOCK ‰BSR‡X101001*œADJUST�START/END�OFFSETS�TO�START/END�ADDRESSES4ŠLEA„OFHS+28(A3),A0‰END�OF�EXECUTION�PARAMETER�BLOCK#ŠMOVEM.L�D0-D6,-(A0)‡PUT�PARAMETERS ŠTRAPƒ#2‘READŠBEQ.S‚READPA20‹GOODŠCMP.B‚#ISTARN,D0‰RECORD�EXIST?&ŠBNE.S‚READEOUT‹EXISTS,�BUT�READ�ERROR(ŠMOVE.L�#EM_NUSER,D0‡NOT�AUTHORIZED�USERREADEOUT‚EQU„*"ŠBSR„EMSGCAL1‹OUTPUT�ERROR�MESSAGEŠBRA„PASS20�CLOSE�AND�EXITREADPA20‚EQU„*-ŠLEA„PASSBUFF(A3),A1ˆADDRESS�OF�PASSWORD�READŠRTS%ASSIPASS‚DC.WƒFHASGN,FOPPRPW+FOPISK,1PASSNAME‚DC.LƒPWVOL ŠDC.WƒPWUSR!ŠDC.LƒPWCAT1,PWCAT2,PWFIL1,PWFIL2)ŠDC.WƒPWEXT,0,PWPROT,PWRECL,PWKSIZ,PWFBLK4PASSREAD‚DC.WƒIOREAD,IOPRTK+IOPBIN+IOPIMG+IOPRRN,1,0ŠDC.Lƒ0,PASSKEY,PASSBUFE,0-PASSUPDA‚DC.WƒIOUPDR,IOPBIN+IOPIMG+IOPRRN,1,0ŠDC.Lƒ0,PASSKEY,PASSBUFE,0ŠPAGEO********************************************************************************"*ˆ**�PASSWORD�VALIDTION�SUBROUTINE*O*******************************************************************************0PWVAL…MOVE.B�UCBLDCNT(A3),D5ˆFETCH�SECURITY�FLAGŠMOVE.B�D5,SCTDAT(A3)†SAVEŠTST.L‚D0‘USER=0?ŠBNE.S‚PWVAL5�BRANCH�NOT�0ŠLSR.B‚#4,D5ŽSHIFT�USER=0�TO�LS PWVAL5„EQU„*$ŠCMP.L‚#'0001',UCBSNO(A3)�SESSION=1?ŠBNE.S‚PWVAL10ŒBRANCH�NO"ŠLSR.B‚#2,D5ŽSHIFT�SESSION=1�TO�LS PWVAL10ƒEQU„*#ŠAND.B‚#3,D5ŽEXTRACT�SECURITY�LEVELŠBEQ„PWEXIT�BRANCH�NONEŠMOVE.B�D5,UCBLDCNT(A3)„SAVEŠBTSTƒ#0,D5ŽSECURITY�W3 ORD?ŠBNE.S‚PWVALSWŒYES**ˆ**�USER/PASSWORD* PWVALPWƒEQU„*!ŠBSR„READPASS‹GET�PASSWORD�RECORDŠBTSTƒ#BTCHNABT,D7‡ERROR?ŠBNE„LG95�YES,�REJECT�LOGON+ŠBSR„PASS20�CLOSE�LUN�1,�NO�LONGER�REQUIRED"ŠTST.B‚(A1)�TEST�PASSWORD�REQUIREDŠBEQ.S‚PWEXIT�NONE�REQUIREDPWVALP10‚EQU„*1ŠMOVEM.L�PWPARP,D3-D5†REQUEST�PASSWORD�PARAMETERS ‰ADD.L…A3,D3#*œADJUST�OFFSET�TO�ADDRESS�(SCTINB)ŠBSR.S‚PWINPUTŒINPUT�PASSWORDŠBNE.S‚PWVALPER‹BAD�INPUT ŠLEA„SCTINB(A3),A0ŠADDRESS�INPUTŠNOLIST ŠBSR„PASS0ŠBEQ.S‚PWEXIT�OKŠLIST%‰LEA‡PASSBUFF(A3),A1…ADDRESS�PASSWORD‰LEA‡PASSKEY(A3),A6‰ADD.L…#PWRECL,A6*œA6=ENDING�ADDRESSPWVALP15‚EQU„*ŠCMP.L‚A6,A1�DONE?ŠBEQ.S‚PWEXIT�YES,�GOODŠCMP.B‚(A0)+,(A1)+ˆCOMPARE�1ŠBEQ.S‚PWVALP15‹BRANCH�OKPWVALPER‚EQU„*#ŠBSR„LGPASSER‹INCREMENT�ERROR�COUNT ŠBRA„PWVALP10‹COUNT�NOT�EXCEEDED**ˆ**�SECURITY�WORD*$PWVALSWƒEQU„*’VALIDATE�SECURITY�WORDŠTST.L‚UCBTSO(A3)‰REQUIRED?ŠBEQ.S‚PWVALSWG‹NONE�REQUIRED2ŠMOVEM.L�PWPARS,D3-D5†SECURITY�WORD�PARAMETR�BLOCK ‰ADD.L…A3,D3#*œADJUST�OFFSET�TO�ADDRESS�(SCTINB)ŠBSR.S‚PWINPUTŒGET�INPUTŠBNE.S‚PWVALSWE‹BAD�INPUT ŠLEA„SCTINB(A3),A0ŠADDRESS�INPUTŠNOLIST ŠBSR„PASS0ŠBEQ.S‚PWVALSWGŠLIST(ŠLEA„UCBTSO(A3),A1ŠADDRESS�SECURITY�WORD%ŠCMP.L‚(A1)+,(A0)+ˆCOMPARE�FIRST�PARTŠBEQ.S‚PWVALSW1‹BRANCH�GOODPWVALSWE‚EQU„*ŠBSR.S‚LGPASSER‹BADŠBRA„PWVALSWŒTRY�AGAINPWVALSW1‚EQU„*&ŠCMP.L‚(A1)+,(A0)+ˆCOMPARE�SECOND�PARTŠBNE„PWVALSWE‹BRANCH�ERRORPWVALSWG‚EQU„**ŠBTST.B�#1,UCBLDCNT(A3)„PASSWORD�REQUIRED?ŠBNE„PWVALPWŒYES PWEXIT„EQU„*ŠRTS* PWINPUTƒEQU„**ŠMOVEM.L�PWOUT,D1-D2‡OUTPUT�I/O�PARAMETERS*ŠLEA„OFHS+20(A3),A0‰END�OF�PARAMETER�BLOCK#ŠMOVEM.L�D1-D5,-(A0)‡TRANSFER�MODELŠTRAPƒ#2‘OUTPUT�PROMPT(ŠMOVEM.L�PWIN,D1-D2ˆINPUT�I/O�PARAMETERS(ŠMOVE.L�D3,D4ŽSTART�INPUT�BUFFER�ADDRESSŠMOVE.L�#PWRECL,D6‰INPUT�LENGTHŠMOVE.L�D3,D5ŽGET�STARTŠADD.L‚D6,D5ŽEND�BUFFER�ADDRESS*ŠLEA„OFHS+20(A3),A0‰END�OF�PARAMETER�BLOCK#ŠMOVEM.L�D1-D5,-(A0)‡TRANSFER�MODELŠTRAPƒ#2‘GET�INPUTŠBNE.S‚PWINPUTX‹EXIT�BADPWINPUT1‚EQU„*ŠMOVE.L�D3,A2ŽGET�START�ADDRESS&ŠMOVE.L�IOSLEN(A0),D5†GET�INPUT�LENGTHPWINPUT2‚EQU„*"ŠCLR.B‚0(A2,D5)‹CLEAR�UNUSED�INPUTŠADD.L‚#1,D5ŽINCREMENT�POINTERŠCMP.L‚D5,D6ŽTEST�DONEŠBCC„PWINPUT2‹CONTINUEŠCLR.L‚D0‘GOOD�STATUSPWINPUTX‚EQU„*ŠRTS'PWOUT…DC.LƒIOWRIT<<16+IOPIMG,LDFLUN<<16-PWIN†DC.LƒIOREAD<<16+IOPBRK+IOPNEC,CDFLUN<<16*LGPASSER‚EQU„*ŠCMP.B‚#$C6,D0ŒBREAK?(ŠBNE.S‚LGPASSES‹NO,�RETURN�NOT�NECESSARYŠMOVEM.L�D1-D6,-(A7)‡SAVE�REGSŠBSR„LEFTMARG‹SET�LEFT�MARGIN!ŠMOVEM.L�(A7)+,D1-D6‡RESTORE�REGSLGPASSES‚EQU„*$ŠSUB.B‚#1,UCBLEN(A3)†INCREMENT�COUNT ŠBEQ„LG95�TOO�MANY,�REJECT�LOGONŠRTS—OK�TO�RETURN*!PWPARS„DC.LƒSCTINB,PWMSGS,PWMSGSE!PWPARP„DC.LƒSCTINB,PWMSGP,PWMSGPE#PWPARN„DC.LƒPASSBUFF,PWMSGN,PWMSGNE#PWPARW„DC.LƒPASSBUFF,PWMSGW,PWMSGWE*!PWMSGS„DC.Bƒ'ENTER�SECURITY�WORD'PWMSGSEƒEQU„*-1ŠDS�0%PWMSGW„DC.Bƒ'ENTER�NEW�SECURITY�WORD'PWMSGWEƒEQU„*-1ŠDS�0%PWMSGP„DC.Bƒ'ENTER�EXISTING�PASSWORD'PWMSGPEƒEQU„*-1ŠDS�0 PWMSGN„DC.Bƒ'ENTER�NEW�PASSWORD'PWMSGNEƒEQU„*-1ŠDS…0*ŠPAGEO*********************************************************************************ˆSECURE**ˆSET�SYSTEM�SUCURITY�LEVEL*O******************************************************************************* SECURE„EQU„*"ŠTST.L‚USERNO(A3)‰PRIVELEGED�USER?ŠBNE„LOGPRU�NO,�ERROR�EXIT&ŠLEA„SECLVL,A6ŠSECURITY�LEVELS�MESSAGEŠBSR„MSGCALLŒOUTPUT�MESSAGE;ŠMOVEM.L�FETCHSEC,D0-D6„PARAM�TO�FETCH�CURRENT�SECURE�LEVEL *ˆADD.L…A3,D3 ‰ADD.L…A3,D6 *œESTABLISH�OFFSETS�AS�ADDRESSES!ŠBSR.S‚XFERSECŒFETCH�SECURE�LEVEL#ŠLEA„U0SN1,A6‹GET�USER=0,SESSION<>1ŠBSR.S‚SECPROCŒGET,PROCESS%ŠLEA„UN0SN1,A6ŠGET�USER<>0,SESSION<>1ŠBSR.S‚SECPROCŒGET,PROCESS1ŠMOVEM.L�SENDSEC,D0-D6…PARAM�TO�SEND�SECURE�LEVEL ‰ADD.L…A3,D3 *ˆADD.L…A3,D6 *œESTABLISH�OFFSETS�AS�ADDRESSES XFERSECƒEQU„*ŠMOVE.L�#1,OFHS+24(A3)…COUNTŠBRA„STDTRAP1‹MOVE�SECURE�LEVEL* SECPROCƒEQU�**ŠMOVE.B�UCBLDCNT(A3),D0ˆFETCH�SECURE�LEVELŠROL.B‚#4,D03 ŽSWAP�NIBBLES ŠMOVE.B�D0,UCBLDCNT(A3)„PUT�BACK#ŠCLR.B‚D7‘RESET�COMMAND�STATUS�BITSŠBSR„READLINE‹GET�INPUTŠBEQ.S‚SECPRO2ŒOK SECPRO1ƒEQU„*%ŠMOVE.B�UCBLDCNT(A3),D0ˆFETCH�CURRENT"ŠAND.B‚#3,D0ŽEXTRACT�CURRENT�LEVELŠOR.Bƒ#'0',D0ŒCONVERT�TO�DIGIT+ŠMOVE.B�D0,SCTINB(A3)†PUT�INTO�INPUT�BUFFER$ŠLEA„SCTINB+2(A3),A5ˆPUT�END�ADDRESSŠBSR„ECHOTŽFORCE�ECHO SECPRO2ƒEQU„*ŠMOVE.B�SCTINB(A3),D3ŠGET�INPUTŠCMP.B‚#'4',D3ŒTEST�TOO�BIGŠBCC„SECPRO1ŒBRANCH�TOO�BIGŠCMP.B‚#'0',D3ŒTEST�TOO�SMALLŠBCS„SECPRO1ŒBRANCH�TOO�SMALL‰CMP.B…#'2',D3‰BHS.S…SEC_0200#*œJMP�IF�LEVEL�2�OR�3�WAS�REQUESTED SEC_0100:ŠAND.B‚#3,D3ŽEXTRACT�LEVEL&ŠMOVE.B�UCBLDCNT(A3),D0ˆFETCH�PREVIOUSŠAND.B‚#$FC,D0ŒREMOVE�OLDŠOR.BƒD3,D0ŽINSERT ŠMOVE.B�D0,UCBLDCNT(A3)„PUT�BACK(ŠBSR�ECHOE‘ECHO�IF�NOT�PREVIOUSLY�ECHOEDŠRTS*+*ˆEDIT�FOR�'PRIV.ACCOUNT.PW'�FILE�EXISTENCE*ˆ.*ˆ.*ˆV *ˆCLOSE�FILE*ˆ.*ˆ.*ˆV*ˆFILE�EXIST�---YES--->SEC_0100*ˆ|*ˆ|*ˆV4*ˆFILE�EXIST�BUT�CURRENTLY�IN�USE�---YES--->SEC_0100*ˆ|*ˆ|*ˆV *ˆREMOVE�RETURN�FROM�BSR�REQUEST*ˆ|*ˆ|*ˆV*ˆOUTPUT�AN�ERROR�MESSAGE*ˆ|*ˆ|*ˆV*ˆGIVE�USER�ANOTHER�CHANCE*ˆ|*ˆ|*ˆV*ˆSECURE*** SEC_0200: ‰BSR‡READPAS0-*œEDIT�TO�SEE�IF�'PRIV.ACCOUNT.PW'�FILE�EXIST‰MOVE.L„D0,-(A7)*œSAVE�RESULTS�OF�ASSIGN ‰BSR‡PASS20 *œCLOSE�FILE‰MOVE.L„(A7)+,D0*œRESTORE�RESULTS�OF�ASSIGN‰BEQ.S…SEC_0100*œJMP�IF�FILE�EXIST‰CMP.B…#FSTAAP,D0‰BEQ.S…SEC_0100*œJMP�IF�FILE�EXIST�BUT�IN�USE*œ(ACCESS�PERMISSION�ERROR) ‰TST.L…(A7)+*œREMOVE�RETURN�FOR�BSR�REQUEST ‰BSR‡EMSGCAL1*œOUTPUT�ERROR�MESSAGEž ‰BRA‡SECURE*œGIVE�REQUESTOR�ANOTHER�CHANCE9SECLVL„DC.Bƒ'LEVELS�ARE:�0/NONE,1/SWORD,2/PWORD,3/BOTH',0ŠDS…0U0SN1…DC.Bƒ'USER=0:',0ŠDS…0UN0SN1„DC.Bƒ'USER�NOT�0:',0ŠDS…0;FETCHSEC‚DC.LƒMOVELL,EETPNAM,EETSESNO,UCBLDCNA,0,0,UCBLDCNT*œFETCH�SECURITY�FROM�EET:SENDSECƒDC.LƒMOVELL,0,0,UCBLDCNT,EETPNAM,EETSESNO,UCBLDCNA*œMOVE�SECURITY�TO�EETŠPAGEO*********************************************************************************ˆUSER�ACCOUNTING*H*ˆENTRY�POINT�'''ACCTINN''''�WILL�ALREADY�HAVE�A6=SCT�DATA�SEGMENT�ADDRS*O*********************************************************************************ˆ**�SESSION�END* ACCTENDƒEQU„* ‰MOVE.L„A3,A6*œA6=SCT'S�DATA�SEGMENT�ADDRESSACCTINN:‰MOVE.W„#FOPPRPW,D1*œD1=PUBLIC�READ/WRITE�OPTION!ŠBSR„ASGNFILE‹ATTEMPT�ASSIGN�FILE+*œA3=SCT'S�DATA�SEGMENT�ADDRESS�UPON�RETURN(ŠBNE.S‚ACCTEXIT‹UNABLE�TO�ASSIGN,�IGNORE5ŠMOVE.L�USERNO(A3),SCTINB(A3)‚FETCH�KEY�(USER�NUMBER)+ŠMOVEM.L�ACCTREAD,D0-D6„GET�PARAMETER�BLOCK ‰ADD.L…A3,D3 ‰ADD.L…A3,D4 *œESTABLISH�OFFSETS�AS�ADDRESSES&ŠLEA„OFHS+28(A3),A0‰END�OF�PUT�ADDRESSŠMOVEM.L�D0-D6,-(A0)‡PUT�MODEL ŠTRAPƒ#2‘READ ŠBNE.S‚ACCTEXIT‹BAD�READ,�IGNORE4ŠLEA„SCTINB+OWLLOFFS(A3),A0�PUT�LOG�OFF�TIME�ADDRESS(ŠMOVE.L�#GTDTIM,D0‰GET�DATE,TIME�COMMANDŠTRAPƒ#1)ŠLEA„UCBTSO(A3),A2ŠPOINT�TO�START�ADDRESSŠBSR„GETLAPSE‹GET�ELAPSED�TIME:ŠLEA„SCTINB+OWCTIMS(A3),A1‚ADDRESS�CUMULATIVE�TIME�TO�DATE9ŠBSR„ADDLAPSEŠADD�SESSION�ELAPSED�TIME�TO�CUMULATIVE�TIME!ŠLEA„SCTINB(A3),A1ŠBUFFER�ADDRESS-ŠADD.L‚#1,OWSCNTS(A1)…INCREMENT�SESSION�COUNT2ŠMOVEM.L�ACCTUPDA,D0-D6„GET�MODEL�TO�UPDATE�RECORD ‰ADD.L…A3,D3 ‰ADD.L…A3,D4 *œESTABLISH�OFFSETS�AS�ADDRESSES,ŠLEA„OFHS+28(A3),A0‰END�OF�PAR�BLOCK�ADDRESS"ŠMOVEM.L�D0-D6,-(A0)‡PUT�PAR�BLOCKŠTRAPƒ#2 ACCTEXIT‚RTS*4ACCTREAD‚DC.WƒIOREAD,IOPRTK+IOPBIN+IOPIMG+IOPRRN,1,0 ŠDC.Lƒ0,SCTINB,SCTINB+OWRECL-1,0-ACCTUPDA‚DC.WƒIOUPDR,IOPBIN+IOPIMG+IOPRRN,1,0 ŠDC.Lƒ0,SCTINB,SCTINB+OWRECL-1,0ŠENDé4 ééé=/*=/*†SYSCNTRL.AF=/*&=/* Chain file to assemble SYSCNTRL.SA=/*:=/* If no output argument is specified for the listing the*=/* chain file will default to SYSCNTRL.LS=/*=/IFC \1ƒ=ARG�SYSCNTRL.LS=/ENDIF=/*&=ASM SYSCNTRL.SA,SYSCNTRL.RO,\1;RZ=106=/*{ Included files are:=/*ƒ9995.&.USM.EQ=/*ƒ9995.&.TR1.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.EXE.EQ=/*}=/*=ENDéééééé{',D0ŒEND�OF�STRING?ŠBEQ.S‚SUBSGGTŒEND�OF�STRING"SUBSGPUT‚MOVE.B�D0,(A1)+‹SAVE�CHARŠBRA„SUBSGLOP‹CONTINUE%SUBSCOMA‚TST.B‚D1‘STRING�IN�PROGRESS?ŠBNE„SUBSGPUT‹YESŠCLR.B‚D0‘SUBSTITUTE�0/NULLŠMOVE.L�A1,D2ŽGET�PUT�POINTER‰MOVE.L„A6,-(A7)‰MOVE.L„A1,-(A7)*œSAVE�REG�A1�AND�A6‰MOVE.L„UCBREGA6(A3),A6 *œA6=ADDRESS�'.ARG'�DATA�SEGMENT‰LEA‡CHAINBUF-1(A6),A1*œA1=CHAIN�ADDRESS�OF�SOME�KIND(*‰SUB.L‚#CHAINBUF-1,D2…COMPUTE�INCREMENT‰SUB.L…A1,D2ŒCOMPUTE�INCREMENT‰MOVE.L„(A7)+,A1‰MOVE.L„(A7)+,A6*œRESTORE�REG�A6�AND�A1ŠMOVE.B�D2,(A2)+‹SAVE�INCREMENT$ŠCMP.L‚CHAINPTR(A3),A2ˆTEST�OVERFLOW'ŠBCS„SUBSGPUT‹PUT�NULL�INSTEAD�OF�COMMA&ŠBSETƒ#BTARGNOE,D7‡NO.�ARGUMENTS�ERROR#ŠBRA.S‚SUBSGEOL‹PROCESS�END�OF�LINE SUBSGLTƒEQU„*%ŠTST.B‚D1‘STRING�ALREADY�IN�PROGRESS?#ŠBEQ.S‚SUBSGLT1‹NO,�IGNORE�THIS�ONEŠMOVE.B�D0,(A1)+‹SAVE�THIS�ONE!SUBSGLT1‚ADD.B‚#1,D1ŽNOW�THERE�ISŠBRA„SUBSGLOP‹CONTINUE SUBSGGTƒEQU„*ŠSUB.B‚#1,D1ŽDECREMENT�COUNT%ŠBNE„SUBSGPUT‹STILL�PROCESSING�STRINGŠBRA„SUBSGLOP‹CONTINUESUBSGEOL‚EQU„*ŠCLR.B‚(A1)�SET�NULLŠMOVE.B�#$D,1(A1)ŠPUT�CR&ŠMOVE.L�A2,D0ŽCHANGE�REG�TO�MANIPULATE‰MOVE.L„A6,-(A7)‰MOVE.L„UCBREGA6(A3),A6 *œSAVE�REG�A6+*œA6=ADDRESS�'.ARG'�DATA�SEGMENT�(CHPOSNUM) ‰ADD.L…#1,A6/*œA6=ADDRESS�EQUIVALENT�OF�CHPOSNUM+1�SINCE�THE*ŸCHPOSNUM�OFFSET�=�0)*‰SUB.L‚#CHPOSNUM+1,D0…GET�NO.�OF�ENTRIES*‰SUB.L…A6,D0ŒGET�NO.�OF�ENTRIES ‰SUB.L…#1,A6+*œA6=ADDRESS�'.ARG'�DATA�SEGMENT�(CHPOSNUM),ŠMOVE.B�D0,CHPOSNUM(A6)„SAVE�MAX�NO.�ENTRIES‰MOVE.L„(A7)+,A6*œRESTORE�REG�A6#ŠTST.B‚D1‘STRING�STILL�IN�PROGRESS?ŠBNE.S‚SUBSEROR‹YES SUBSEXIT‚RTS*SUBSEROR‚EQU„* ŠMOVE.L�#EM_ARGX,D0ˆMESSAGE�TYEPŠBRA„ERRCALLŒOUTPUT�AND�RETURNŠPAGEH************************************************************************(*ˆ**�SUBROUTINE�TO�DISPLAY�ARGUMENT�LISTH************************************************************************ SUBDISPK:‰MOVE.L„(A7)+,A6*œRESTORE�REG�A6SUBDISPL‚EQU„*.ŠMOVE.L�#1,D4ŽINITIALIZE�TO�FIRST�SUBSTITUTION,*‰LEA„CHPOSNUM,A2ˆADDRESS�SUBSTITUTION�TABLE2‰MOVE.L„UCBREGA6(A3),A2‚ADDRESS�SUBSTITUTION�TABLESUBDISP1‚EQU„*ŠCMP.B‚(A2),D4ŒTEST�DONEŠBGT.S‚SUBDISPX‹DONE*ŠLEA„SCTINB(A3),A5ŠBUFFER�TO�BUILD�MESSAGE$ŠMOVE.B�#'\',(A5)+‰SUBSTITUTION�CHAR$ŠMOVE.L�D4,D0ŽNUMBER�TO�BE�CONVERTED$ŠBSR„BDCONV�CONVERT�TO�ASCII�DECIMALŠROL.W‚#8,D0ŽPOSITION�HI�CHARŠMOVE.B�D0,(A5)+‹PUT�CHARŠROL.W‚#8,D0ŽGET�OTHER�CHARŠMOVE.B�D0,(A5)+‹PUT�CHARŠMOVE.B�#':',(A5)+&ŠCLR.W‚D0‘INITIALIZE�FOR�WORD�INDEXING7ŠMOVE.B�0(A2,D4),D0ˆGET�INCREMENT�TO�START�SUBSTITUTION0ŠLEA„$50(A2,D0),A6†ADDRESS�START�OF�SUBSTITUTIONŠMOVE.L�D4,-(A7)‹SAVE�D42ŠCLR.B‚D5‘SET�MESSAGE�TERMINATOR�FOR�MESSAGE�BUILD*ŠBSR„BUILDMSG‹TRANSFER�SUBSTITUTION�STRINGŠBSR„WRITEINB‹OUTPUT�TO�LUN�6ŠMOVE.L�(A7)+,D4‹REFETCH�D4%ŠADD.L‚#1,D4ŽINCREMENT�TO�NEXT�STRINGŠBRA„SUBDISP1‹CONTINUESUBDISPX‚EQU„*$ŠBCLRƒ#BTARGNOE,D7‡RESET,�TEST�ERRORŠBEQ„SUBSEXIT‹OK!ŠMOVE.L�#EM_ARGNO,D0‡MESSAGE�TYPE'ŠBRA„EMSGCALL‹OUTPUT�MESSAGE�AND�RETURN*ŠENDéé8 ééééé=/* =/*†USM.AF=/*!=/* Chain file to assemble USM.SA=/*:=/* If no output argument is specified for the listing the%=/* chain file will default to USM.LS=/*=/IFC \1 ƒ=ARG�USM.LS=/ENDIF=/*=ASM USM.SA,USM.RO,\1;RZ=110=/*{ Included files are:=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.USM.EQ=/*ƒ9995.&.TR1.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.EXE.EQ=/*}=/*=ENDééééééý >' USM SAêÎqqUSMLIB CF qqSYSGEN CF  ÒqqCMDLIST AG--qqINITDAT AGNN¹qqROMIOI1 AG__3qqVERSADOSCDhhQqqINITGEN CIÁÁqqROGEN CIÊÊqqIOI CIÓÓ9qq8 VALPAR CIÜÜ�qqIFTASK CIííqqIOCGEN CIööqqSYSINIT CIÿÿOqqCNFGTASKCI   qqM316DEF CI  qqEET LG " "qqFHS LG + +qqFMS LG 4 4qqIOCGEN LG = = qq=USM‡IDNTƒ4,00Š8107190816�USER�SESSION�MANAGEMENT�CONTROL�TASK**‰INCLUDE�9995.&.TR1RTCD.EQ*‰INCLUDE�9995.&.USM.EQ*‰INCLUDE�9995.&.TR1.EQ*‰INCLUDE�9995.&.IOE.EQ*‰INCLUDE�9995.&.EXE.EQ*ŠNOLISTŠINCLUDE�9995.&.TR1RTCD.EQŠINCLUDE�9995.&.USM.EQŠINCLUDE�9995.&.TR1.EQŠINCLUDE�9995.&.IOE.EQŠINCLUDE�9995.&.EXE.EQŠLISTŠXDEFƒASGNFILEŠXDEFƒADDLAPSEŠXDEFƒBLANKOUTŠXDEFƒBUILDINB ŠXDEFƒBCTRAP1ŠXDEFƒBUILDMSG ŠXDEFƒCLOCDF ŠXDEFƒCKDEV ŠXDEFƒCKNODEV ŠXDEFƒECHOE ŠXDEFƒECHOS ŠXDEFƒECHOTŠXDEFƒEMSGCALLŠXDEFƒEMSGCAL1 ŠXDEFƒERRCALLŠXDEFƒEDITSESSŠXDEFƒEDITSPAC ŠXDEFƒFHOPEN ŠXDEFƒFHCLOSEŠXDEFƒFHEXOPENŠXDEFƒFHEXCLOSŠXDEFƒFHOPNTIDŠXDEFƒGETLAPSEŠXDEFƒGETNOSPAŠXDEFƒGETLJSFYŠXDEFƒGETLEFT4 ŠXDEFƒICALL ŠXDEFƒLG95 ŠXDEFƒLOGPRU ŠXDEFƒLOGMESG ŠXDEFƒLDRCALL ŠXDEFƒLMARGINŠXDEFƒLEFTMARG ŠXDEFƒMSGCALL ŠXDEFƒOPNCDF ŠXDEFƒPROC ŠXDEFƒPROC120 ŠXDEFƒPROC206 ŠXDEFƒPROC210 ŠXDEFƒPROC255 ŠXDEFƒPROC260 ŠXDEFƒPROC320 ŠXDEFƒPROMPT ŠXDEFƒPRTFILEŠXDEFƒREADLINE ŠXDEFƒSCTBEG ŠXDEFƒSC18ŠXDEFƒSTDERRORŠXDEFƒSTDTRAP1ŠXDEFƒSTDTRAP2DŠXDEFƒSTDTRAP3ŠXDEFƒSKIPSPAC ŠXDEFƒSYSDPARŠXDEFƒWRITEINB ŠXDEFƒX10100 ŠSECTION�8H*************************************************************************=*‚SCT�CODE�SECTION�IS�REENTRANT.‚SCT�IS�INITIATED�BY�THE�EET.**‚REV�X3.00‚HBR8D*‚INCLUDES�SHARED�.ARG�W/OPTIONS�A-O�AND�ERROR�MESSAGE�HANDLER�CALLS*H************************************************************************** ŠXREFƒBYEBYEŠXREFƒCMDPWVALŠXREFƒCLASCODE ŠXREFƒCVT2 ŠXREFƒCHAIN ŠXREFƒCHAIN2ŠXREFƒCHPOSNUMŠXREFƒCHAINBUF ŠXREFƒCMDENDŠXREFƒCHAINPTR ŠXREFƒDATEŠXREFƒDELAYSEC ŠXREFƒDELAYSŠXREFƒEDITFILEŠXREFƒENABLASQŠXREFƒENDQUEUEŠXREFƒJOBQUEUE ŠXREFƒLOGMŠXREFƒLOGTRYNO ŠXREFƒLOGBYE ŠXREFƒLOGOFF ŠXREFƒLDRFILL ŠXREFƒLDRCLL ŠXREFƒLDRABUF ŠXREFƒLDRLDOŠXREFƒLODRETRY ŠXREFƒOFHSŠXREFƒPRTIMDAT ŠXREFƒPROC400ŠXREFƒREGCHAIN ŠXREFƒSTOPALL ŠXREFƒSTOP1 ŠXREFƒSTRUTN ŠXREFƒSTRUOPTŠXREFƒSTARTMON tQ@#5+F3E;1CCK@SC[JcQkIsF{EƒH‹?“@›B£B«@³=»3Ã5Ë>Ó@ÛFã@ëRó ŠXREFƒSCTEXB ŠXREFƒSYSOPT ŠXREFƒSYSCMDS ŠXREFƒSCTINB ŠXREFƒSCTINBE ŠXREFƒSYSDFLT ŠXREFƒSCTSTKŠXREFƒSHAREOPT ŠXREFƒTIME ŠXREFƒTERM5 ŠXREFƒTERMALL ŠXREFƒTIMECNTŠXREFƒUCBPRILIŠXREFƒUCBPRICHŠXREFƒUCBPRIBT ŠXREFƒUSE ŠXREFƒUSRTSK ŠXREFƒUCBTSK ŠXREFƒUCBUTN ŠXREFƒUCBTSO ŠXREFƒUCBSNO ŠXREFƒUSERNOŠXREFƒUCBMSWAT ŠXREFƒUCBBNAMŠXREFƒUCBCMDNDŠXREFƒUCBCMDLG ŠXREFƒUCBLUS ŠXREFƒUCBTID ŠXREFƒUCBKEEP ŠXREFƒUCBREGD ŠXREFƒUCBREGXŠXREFƒUCBLDCNTŠXREFƒUCBCMDST ŠXREFƒUCBTUT ŠXREFƒUCBTEMP ŠXREFƒUCBSESS ŠXREFƒUCBUNO ŠXREFƒUTTCBP ŠXREFƒUCBLENŠXREFƒUCBREGA6 ŠXREFƒUCBTSOA ŠXREFƒDEFAULTŠXREFƒEET_GFLGŠXREFƒOFHSFILL*‰PAGE****ˆVERSACOMPUTER�CHANGE�HISTORY*5*‰1.�ENTRY�TO�THE�'SCT'�TASK�WILL�HAVE�THE�FOLLOWING:"*’A5�=�ADDRESS�'.ARG'�DATA�SEGMENT$*’A6�=�ADDRESS�SCT�TASK�DATA�SEGMENT*F*‰2.�INITIALIZE�THE�'USER'�TASK�ENTRY�REGISTERS�A5�AND�A6�RESPECTIVELY *’A5�=�ZERO"*’A6�=�ADDRESS�'.ARG'�DATA�SEGMENT*B*‰3.�THE�CODING�SECTION�'USM'�OF�THE�SCT�TASK�WILL�USE�REGISTER�A3@*ŒTO�CONTAIN�THE�'SCT'�TASK�DATA�SEGMENT�ADDRESS�UNLESS�SPCIFIED *ŒOTHERWISE*B*‰4.�PRE-DEFINED�PARAMETERS�THAT�ONCE�REFERENCED�ADDRESSES�BUT�NOW?*ŒREPRESENT�OFFSETS�ARE�ADJUSTED�BY�ADDING�THE�SCT�DATA�SEGMENT$*ŒADDRESS�9 (A3)�TO�REFLECT�AN�ADDRESS** Changes 7/83 SCB.*=*‰1.�Fixed�so�that�user�may�elect�to�have�EET�handle�complete9*Žlogon�including�entering�of�system�default�volume,�user:*Žnumber,�catalog,�date,�and�time�so�that�when�booting,�no>*Žmanual�entries�need�be�made�prior�to�the�first�session�being9*Žlogged�on.‚This�option�is�selected�by�setting�bit�#1�in>*Žthe�sysgen�parameter�'AUTOLOGN'.‚At�the�time�of�this�change,<*Žbit�position�0�in�AUTOLOGN�was�used�to�indicate�auto-break*Žafter�initial�boot.;*‰2.�Fixed�problem�of�EET�trying�to�access�PRIV.UPSYSTEM.CF9*Žprior�to�the�system�default�volume�being�established�by<*ŽFMS�on�boot�up.‚The�technique�used�is�to�try�to�access�the6*Žfile�0.&.ERRORMSG.SY.‚If�the�file�is�unavailable�for9*Žassignment,�then�the�system�default�volume�has�not�been6*Žestablished�yet.‚EET�will�attempt�to�assign�the�file8*Žat�one�second�intervals�for�a�period�of�10�seconds.‚If8*Žat�any�time�in�this�loop,�the�file�is�assigned�with�no8*Žerror�then�processing�continues�normally.‚If,�however,>*Žthe�file�can�never�be�assigned�during�the�course�of�the�loop,*Žthe�a�user�friendly�error�message�appears:@*Ž'**�ERROR�-�unable�to�assign�0.&.ERRORMSG.SY�on�system�volume'9*Žand�processing�would�continue�normally.‚0.&.ERRORMSG.SY:*Žwas�picked�as�the�test�file�in�this�case�since�it�is�the&*Žonly�required�file�on�a�system�disk.* ŠPAGE ‰DC.B†'USM�'‰DC.B†'121084�4'=SCTBEG„EQU„*ŒENTRY�POINT�FROM�EET�(START�OF�SCT�CODE�SEGMENT)**ˆ**�INITIALIZE�SCT�***‰MOVE.L„A5,UCBREGA6(A6)*œA5=ADDR�OF�'.ARG'�SEGMENT1*ŸUPON�ENTRY�TO�USER�TASK�-�A6='.ARG'�SEGMENT�ADR ‰MOVE.L„A6,A3*œA3=SCT�DATA�SEGMENT�ADDRESS+ŠLEA„SCTSTK(A3),A7ŠINITIALIZE�STACK�POINTER5ŠCLR.B‚CHPOSNUM(A5)‡INITIALIZE�PARAMETER�SUBSTITUTION1ŠMOVE.W�#$D,CHAINBUF(A5)ƒINITIALIZE�ARGUMENT�LIST**ˆ**�ENABLE�ASQ�&�ASR* ŠBSR„ENABLASQ***‚ASSIGN�LUN�TO�SCT'S�INTERACTIVE�TERMINAL*0ŠLEA„OPNSCT,A1ŠPARAMETERS�FOR�SCTLUN�OPEN/ASSIGN(ŠBSR„FHOPNTID‹OPEN�FOR�PUBLIC�READ/WRITE* *ˆ**�OPEN�CDFLUN�FOR�PUBLIC�READ* ŠBSR„FHOPEN*!*ˆ**�OPEN�LDFLUN�FOR�PUBLIC�WRITE* ŠBSR„FHOPEN**ˆ**�INITIALIZE�FOR�LOGON�***0ŠMOVE.B�LOGTRYNO,UCBLEN(A3)�INITIALIZE�TRY�COUNT#ŠLEA„LOGM,A6ŒIDENTIFICATION�MESSAGEŠBSR„BUILDINB‹OUTPUT�MESSAGEH*************************************************************************ˆ**�USER�LOGONH************************************************************************ LOGON…EQU„*ŠCLR.B‚D7‘RESET�FLAGS‰MOVE.L„UCBREGA6(A3),A6 *œA6=ADDRESS�'.ARG'�DATA�SEGMENTK„MOVE.W�#(1<ŠBTSTƒ#BTCHNOVR&7,(SHAREOPT+1-(BTCHNOVR/8))(A6)�ERROR�OVERIDE?!ŠBNE.S‚RDPRCMD2‹YES,�IGNORE�ERRORRDPRABR1‚EQU„*$ŠLEA„CHANABRT,A6ˆCHAIN�ABORT�MESSAGEŠBSR„MSGCALLŒOUTPUT�MESSAGEŠBTSTƒ#BTBATCH,D7ˆBATCH�MODE?O*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>01/21/85>>*E*ˆPer�instructions�this�SPR�fix�has�been�backed�out.�It�will�not�workF*ˆfor�an�MMU�type�system.�The�original�instruction�has�been�re-invokedA*ˆWe�will�have�to�look�at�this�again�for�a�more�correct�solution.'*ˆThis�current�fix�will�re-open�SPR�876* *‰BNE„X10200*œJMP�IF�BATCH�MODE*œFIX�FOR�SPR876* ‰BNE‡LOGOFF *œTERMINATEO*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<01/21//85< .ŠBCLRƒ#BTREAD5,D7ˆRESET�TO�INTERACTIVE�(LUN�0)&ŠBSETƒ#0,UCBLUS+3(A3)„ALSO�IN�LUN�MASK‰MOVE.L„UCBREGA6(A3),A6*œA6=ADDRESS�'ARG'�DATA�SEGMENT,ŠBSETƒ#0,SHAREOPT+1(A6)‚ALSO�IN�OPTIONS�MASKRDPRCMD2‚EQU„*1ŠBCLRƒ#BTUSBRK,D7ˆ(IF�SET�DURING�CHAIN�ABORT�MSG)&ŠBCLRƒ#BTCMDABT,D7‡RESET�COMMAND�ABORT*ŠBCLRƒ#BTCHNABT,D7‡RESET�CHAIN�ERROR�ABORTŠBCLRƒ#BTEOF,D7ŠPREVIOUS�EOF?ŠBEQ.S‚RDPRCMD3‹NO; ,�PROCEED"ŠBSR„LEFTMARG‹RESET�TO�LEFT�MARGINRDPRCMD3‚EQU„**ŠCLR.B‚UCBLDCNT(A3)‡CLEAR�LOAD�TRY�COUNTER**ˆ**�READ�NEXT�COMMAND�LINE* READCMDƒEQU„*ŠCLR.B‚D7‘RESET�COMMAND�FLAGSŠLEA„PROMPT,A6 ŠBTSTƒ#BTCDFILE,D7‡LUN�5�=�FILE?ŠBEQ.S‚READCMD1‹NO,�CONTINUE%ŠLEA„ABPROMPT,A6ˆCHAIN�ABORTED�PROMPTREADCMD1‚EQU„*"ŠBSR„READLINE‹READ�NEXT�INPUT�LINE*%*ˆ**�DECODE,�AND�BRANCH�TO�PROCESS�IT* PROC†EQU„*ŠTST.L‚D0‘TEST�STATUSŠBEQ.S‚PROC10�BRANCH�I/O�OKŠCMP.B‚#ISTATO,D0‰TIMEOUT?ŠBEQ.S‚PROC3ŽYES%ŠCMP.B‚#ISTANR,D0‰TERMINAL�NOT�READY? ŠBNE.S‚PROC5ŽNO�TRY�OTHER�ERRORS(ŠADD.B‚#1,UCBLDCNT(A3)„INCREMENT�COUNTERŠBEQ„BYEBYE�TERMINATE�TASKŠBSR„DELAYSEC‹WAITŠBRA„READCMDŒTRY�AGAIN PROC3…EQU„*(ŠADD.B‚#1,UCBLDCNT(A3)„INCREMENT�COUNTER#ŠMOVE.B�UCBLDCNT(A3),D1ˆFETCH�COUNT"ŠCMP.B‚TIMECNT,D1‰TIME�TO�LOG�OFF?ŠBCS.S‚PROC4ŽNO PROC3A„EQU„*ŠBSR„ERRCALLŒOUTPUT�MESSAGE&ŠBSETƒ#BTBATCH,D7ˆ(DON'T�BLANK�SCREEN)ŠBRA„LOGOFF�TERMINATE�TASK PROC4…EQU„*9ŠLEA„PROMPT-2,A6ˆPROMPT�WITH�BELL,�REGARDLESS�OF�OPTION�BŠBRA„READCMD1‹TRY�AGAIN PROC5…EQU„*$ŠBTSTƒ#BTUSBRK,D7ˆBREAK�TERMINATION?ŠBNE.S‚PROC26�BRANCH�YESŠBTSTƒ#BTEOF,D7ŠEOF?ŠBNE„CMDEND�YESŠBRA„RDPRCMDŒTRY�AGAIN PROC10„EQU„*"ŠCMP.B‚#$D,(A0)‹FIRST�CHAR�RETURN?ŠBEQ.S‚PROC26�CR�ALONE�=�NULLŠCLR.L‚D1‘INITIALIZE**ˆ**�SKIP�LEADING�SPACES* PROC20„EQU„*'ŠCMP.B‚#'�',(A0)ŠTEST�FOR�LEADING�SPACEŠBNE.S‚PROC22�PROCEEDŠADD.L‚#1,A0ŽADVANCE�POINTERŠSUB.L‚#1,D6ŽDECREMENT�COUNTŠBGT„PROC20�CONTINUE�SKIPPING ŠBRA„RDPRCMD*#*ˆ**�FILE�INPUT�MUST�START�WITH�"="* PROC22„EQU„*'ŠBTSTƒ#BTREAD5,D7ˆFILE�OR�DEVICE�INPUT?ŠBEQ.S‚PROC30�BRANCH�DEVICE ŠCMP.B‚#'=',(A0)ŠFIRST�CHAR�"="?ŠBNE.S‚PROC26�NO,�IGNORE!ŠCMP.B‚#'@',1(A0)‰COMMAND�OPTION?ŠBNE.S‚PROC25�NO,�CONTINUEŠBSETƒ#BTATSIGN,D7‡SET�FLAGŠADD.L‚#1,A0ŽADVANCE�POINTER&ŠSUB.L‚#1,D6ŽDECREMENT�REMAINING�COUNTŠBLE„PROC300ŒEND�OF�LINE�ERROR PROC25„EQU„*)ŠBTSTƒ#BTENDSKP,D7‡CONDITIONAL�SKIP�MODE?ŠBEQ.S‚PROC27�TEST�ECHO�INPUT/ŠCMP.B‚#'/',1(A0)‰NEXT�CHAR�CONDTIONAL�COMMAND?ŠBNE.S‚PROC26�NO,�IGNORE‰MOVE.L„A6,-(A7)‰MOVE.L„UCBREGA6(A3),A6 *œSAVE�REG�A6 *œA6=ADDRESS�'.ARG'�DATA�SEGMENTG‰BTST�#BTPRTSKP&7,(SHAREOPT+1-(BTPRTSKP/8))(A6)�PRINT�CONDITIONAL�DURIN*µSKIP?ŠBEQ.S‚PROC29�NO&ŠMOVE.B�#'/',(A0)+‰FLAG�SKIP�CONDITIONŠBRA.S‚PROC29AŒGO�LIST�IT*9*ˆ**�RETURN�FOR�SHORT�LINE,�CONDITIONAL�SKIP,�LACK�OF�"="* PROC26„EQU„*5ŠBCLRƒ#BTSUBSER,D7‡IGNORE�POSSIBLE�SUBSTITUTION�ERRORŠRTS.*ˆ**�TEST�WHETHER�TO�PRINT�CONDITIONAL�COMMAND PROC27„EQU„*-ŠCMP.B‚#'/',1(A0)‰IS�IT�A�CONDITIONAL�COMMANDŠBNE.S‚PROC30�NO,�GO�ECHO‰MOVE.L„A6,-(A7)‰MOVE.L„UCBREGA6(A3),A6DŠBTSTƒ#BTPRTIF&7,(SHAREOPT+1-(BTPRTIF/8))(A6)�PRINT�CONDITONAL�CMDS?‰BNE.S…PROC29AƒYESPROC29:‰MOVE.L„(A7)+,A6*œRESTORE�REG�A6 ‰BRA.S…PROC35PROC29A:‰MOVE.L„(A7)+,A6*œRESTORE�REG�A6***ˆ**�FILE�-�ECHO�INPUT�TO�LDF* PROC30„EQU„*)ŠBSR„ECHOSŽECHO�IF�NOT�PREVIOUSLY�PRINTED PROC35„EQU„*ŠCMP.B‚#'=',(A0)Š"="/ŠBNE.S‚PROC38�OKŠADD.L‚#1,A0ŽINCREMENT�POINTER&ŠSUB.L‚#1,D6ŽDECREMENT�REMAINING�COUNT PROC38„EQU„*'ŠCMP.B‚#'@',(A0)ŠDEVICE�OPTION�POSITIONŠBNE.S‚PROC40�CONTINUE#ŠBSETƒ#BTATSIGN,D7‡"@"�OPTION�FOUNDŠADD.L‚#1,A0ŽINCREMENT�POINTER&ŠSUB.L‚#1,D6ŽDECREMENT�REMAINING�COUNT* *ˆ**�ABORT�IF�SUBSTITUTION�ERROR* PROC40„EQU„*ŠCMP.B‚#$D,(A0)‹END�OF�LINE?ŠBEQ„PROC26�IGNORE*ŠBTSTƒ#BTSUBSER,D7‡TEST�SUBSTITUTION�ERRORŠBEQ.S‚PROC45�NO,�PROCEEDŠBRA„ECHOEŽECHO�AS�IS*$*ˆ**�INITIALIZE�FOR�ENTRY�MATCH-TEST* PROC45„EQU„*‰PAGE*!*ˆThe�following�code�fixes�SPR495**ˆThe�following�code�was�added4*’to�eleminate�leading�spaces�between�the�'='�prompt*’and�the�start�of�the�command*‰CMP.B…#'�',(A0) ‰BNE.S…PROC47.*œJMP�IF�THIS�IS�NOT�A�LEADING�SPACE�CHARACTER ‰TST.B…(A0)+*œADJUST�TO�NEXT�CHARACTER ‰BRA.S…PROC45 *œREPEAT�LOOPPROC47:‰PAGE+ŠMOVE.L�A0,UCBCMDST(A3)„SAVE�STARTING�POINT4ŠCLR.L‚D2‘INITIALIZE�MATCH/CONTINUE�FLAG�TO�CONTINUE#ŠCMP.B‚#'/',(A0)ŠCHAIN�CONDITIONAL?ŠBEQ„PROC400ŒYES6ŠMOVE.L�#SYS; CMDS,A6ˆGET�START�OF�SYSTEM�COMMANDS�TABLE PROC50„EQU„*8ŠMOVE.L�UCBCMDST(A3),A0ˆGET�SEARCH�STRING�STARTING�POINT*"*ˆ**�COMPARE�ENTRY�TO�INPUT�STRING* PROC55„EQU„*ŠMOVE.B�(A6)+,D1‹GET�TABLE�CHARŠBMI.S‚PROC58�MAY�BE�ENDŠBNE.S‚PROC60�NOT�END,�CONTINUE)ŠCMP.B‚#'�',(A0)ŠINPUT�STRING�TERMINATOR?ŠBGT.S‚PROC65�NO,�NO�MATCHŠNOT.B‚D2‘SET�MATCH�FLAG&ŠBRA.S‚PROC70�GO�GET�PROCEDURE�ADDRESS PROC58„EQU„*)ŠCMP.B‚#'�',(A0)ŠINPUT�STRING�TERMINATOR?ŠBLE„PROC55�YES"ŠAND.B‚#$7F,D1ŒREMOVE�HI�ORDER�BITŠCMP.B‚#$60,D1ŒLOWER�CASE?ŠBCS.S‚PROC60�NOŠSUB.B‚#$20,D1ŒFORCE�UPPER�CASE;PROC60„CMP.B‚(A0)+,D1‹TABLE�ENTRY�WITH�INPUT�CHAR�(ADV�PTR).ŠBEQ„PROC55�CONTINUE�CHECKING�THIS�TABLE�ENTRY*5*ˆ**�ENTRY-STRING�NO�COMPARE,�ADVANCE�TO�END�OF�ENTRY* PROC65„EQU„*(ŠTST.B‚(A6)+ŽLOOK�FOR�END�OF�TABLE�ENTRYŠBNE„PROC65�CONTINUE�LOOKING***ˆ**�ADJUST�ENTRY�ADDRESS�TO�WORD�BOUNDARY* PROC70„EQU„*4ŠMOVE.L�A6,D0ŽMOVE�TO�DATA�REGISTER�FOR�MANIPULATIONŠADD.L‚#1,D0ŽROUND�UPŠBCLRƒ#0,D0ŽFORCE�WORD�BOUNDARY&ŠMOVE.L�D0,A6ŽBACK�TO�ADDRESS�REGISTER&ŠMOVE.L�(A6)+,D0‹GET�PROCEDURE�ADDRESS!ŠBEQ.S‚PROC120Œ(NOT�FOUND)�RETURNŠTST.B‚D2‘MATCH/CONTINUE?ŠBEQ„PROC50�CONTINUE**ˆ**�MATCH�FOUND*!ŠBSR„REMLEN�FIND�REMAINING�LENGTH!ŠMOVE.L�D0,A1ŽTRANSFER�TO�ADR�REGŠJMP„(A1)�GO�TO�PROCEDURE*&*ˆ**�NOT�A�SYSTEM�COMMAND,�SEE�IF�FILE* PROC120ƒEQU„*,ŠMOVE.L�UCBCMDST(A3),A0ˆADR�START�OF�COMMANDŠBSR„LDRFILLŒGET�DEFAULTS+ŠMOVE.W�#'LO',FHSEXT(A6)ƒASSUME�"LO"�EXTENTŠMOVE.L�#'„',D0‰BLANKING�SPACESŠMOVE.L�D0,FHSFIL(A6)†FILE�NAMEŠMOVE.L�D0,FHSFIL+4(A6)„"**ˆFORMAT�FILE�NAME*‰MOVE.L„A3,-(A7)*œA3=SCT�DATA�SEGMENT�ADDRESS'ŠBSR„EDITFILE‹TREAT�COMMAND�AS�FILENAME‰MOVE.L„(A7)+,A3*œA3=SCT�DATA�SEGMENT�ADDRESSŠBPL.S‚PROC125ŒOK*ŠMOVE.L�#EM_FILNA,D0‡FILE�DESCRIPTOR�ERROR"ŠBRA„EMSGCALL‹OUTPUT�ERROR�MESSAGE PROC125ƒEQU„*ŠTST.B‚D0‘*,/,#�NOT�ALLOWED!ŠBNE„PROC320ŒCOMMAND�SYNTAX�ERROR$ŠCMP.B‚#';',D1ŒSEMICOLON�TERMINATOR? ŠBEQ„PROC320ŒYES,�COMMAND�SYNTAX ŠCMP.B‚#',',D1ŒCOMMA�TERMINATOR? ŠBEQ„PROC320ŒYES,�COMMAND�SYNTAX(ŠCMP.B‚#'/',D1ŒCONCATINATION�TERMINATOR? ŠBEQ„PROC320ŒYES,�COMMAND�SYNTAX&ŠCMP.B‚#'&',FHSFIL(A6)„TEMPORARY�FILE?*ŠBEQ„PROC300ŒTEMP�FILE�CANNOT�BE�A�COMMAND‰MOVE.L„A6,-(A7)‰MOVE.L„UCBREGA6(A3),A6 *œSAVE�REG�A6 *œA6=ADDRESS�'.ARG'�DATA�SEGMENT"ŠMOVE.L�D0,UCBTEMP(A6)…SAVE�STATUS‰MOVE.L„(A7)+,A6*œRESTORE�REG�A6&ŠCMP.W‚#'CF',FHSEXT(A6)ƒIMPLIED�CHAIN?ŠBEQ„CHAIN2�YES*'*ˆFIND�REMAINING�LENGTH�OF�COMMAND�LINE*!ŠBSR„REMLEN�FIND�REMAINING�LENGTH2ŠMOVE.B�D6,LDRCLL(A3)†LINE�LENGTH�TO�LDR�PAR�BLOCK?ŠBEQ.S‚PROC135†REMAINING�LENGTH�ZERO�(NONE�TO�MOVE�TO�EVEN�ADR)*)*ˆRELOCATE�REMAINING�CMD�LINE�TO�EVEN�ADR*7‰LEA†SCTINB(A3),A1‰GET�START�OF�INPUT�BUFFER�(EVEN�ADR)-ŠMOVE.L�A1,LDRABUF(A3)…LOADER�PARAMETER�BLOCK PROC130ƒEQU„*1ŠMOVE.B�(A0)+,(A1)+ˆMOVE�TO�START�OF�INPUT�BUFFERŠSUB.L‚#1,D6ŽDECREMENT�COUNTŠBNE„PROC130ŒCONTINUE* *ˆCALL�LOADER* PROC135ƒEQU„*ŠBSR„LDRCALLŒCALL�TO�LOADERŠBEQ„PROC200ŒBRANCH�GOOD�LOAD**ˆFOUND�IN�USER�VOLUME?*"ŠCMP.B‚#FSTANNM,D0ˆFILE�NOT�FOUND? ŠBEQ.S‚PROC140ŒYES,�TRY�SYS�VOLN$ŠCMP.B‚#FSTAVOL,D0ˆVOLUME�NOT�FOUND?#ŠBEQ.S‚PROC140ŒGO�TRY�SYSTEM�VOLUMEŠBSR.S‚LODMODEŒTEST�MODEŠBRA„PROC135ŒTRY�AGAIN*.*ˆNOT�FOUND�IN�USER�VOLUME�-�TRY�SYSTEM�VOLUME* PROC140ƒEQU„*‰MOVE.L„UCBREGA6(A3),A0 *œA0=ADDRESS�'.ARG'�DATA�SEGMENT.ŠMOVE.L�UCBTEMP(A0),D0…REFETCH�EDITFILE�STATUS*ŠAND.L‚#$700000,D0ˆVOL,USER,�OR�CAT�FOUND?ŠBNE„PROC300ŒCOMMAND�NOT�FOUND/ŠLEA„OFHS+FHSVOL(A3),A0ˆPARAMETER�BLOCK�ADDRESSŠMOVE.L�#'„',D0‰FETCH�SPACES&ŠMOVE.L�D0,(A0)+‹SYSTEM�DEFAULT�VOLUMEŠCLR.W‚(A0)+ŽUSER�ZERO0ŠMOVE.L�D0,(A0)+‹SYSTEM�DEFAULT�CATALOG�1ST�PART/ŠMOVE.L�D0,(A0)+‹SYSTEM�DEFAULT�CATALOG�2D�PART*$*ˆRECALL�LOADER�TO�TRY�SYSTEM�VOLUME* PROC145ƒEQU„*ŠBSR„LDRCALLŒCALL�AGAINŠBEQ„PROC200ŒFOUND"ŠCMP.B‚#FSTANNM,D0ˆFILE�NOT�FOUND?ŠBEQ„PROC300ŒFILE�NOT�FOUND$ŠCMP.B‚#FSTAVOL,D0ˆVOLUME�NOT�FOUND?ŠBEQ.S‚PROC150ŒVOLUME�ERROR�MSGŠBSR.S‚LODMODEŒTEST�MODEŠBRA< „PROC145ŒTRY�AGAIN* LODMODEƒEQU„*ŠBTSTƒ#BTUSBRK,D7ˆBREAK?ŠBEQ.S‚LODMODE1‹NO,�CONTINUEŠTST.L‚(A7)+ŽPOP�RETURNŠRTSLODMODE1‚EQU„*ŠBTSTƒ#BTBATCH,D7ˆBATCH�MODE?ŠBEQ.S‚LODERR�BRANCH�NOT�BATCH:ŠCMP.B‚#RTCDDPRQ,D0‡DUP�REQUEST?�(NO�MEM,TCB�NOT�RELEASED)ŠBEQ.S‚LODWAITŒYES,�JUST�WAIT#ŠCMP.B‚#RTCDNMEM,D0‡LACK�OF�MEMORY?%ŠBEQ.S‚LODWAITŒYES,�WAIT�TO�TRY�AGAIN LODERR„EQU„*:ŠADD.L‚#4,A7‹POP�RETURNS�OFF�STACK�(BACK�TO�COMMAND�INPUT)"ŠCMP.L‚#$20000000,D0†TRAP�4�ERROR?ŠBCC„STDERROR‹YES,�PROCESSCŠADD.L‚#$2C,A0‚ASSUME�TRAP�3�-�POINT�TO�FHS�PARAMETER�BLOCK�SECTION"ŠCMP.L‚#$18000000,D0†TRAP�3�ERROR?ŠBCC„STDERROR‹YES,�PROCESS-ŠMOVE.L�#0,A0ŽINHIBIT�ERROR�MESSAGE�EXPANSION!ŠBRA„STDERROR‹ISSUE�ERROR�MESSAGE LODWAITƒEQU„*&ŠMOVE.L�LODRETRY,A0ˆFETCH�DELAY�LENGTH*ŠADD.B‚#1,UCBLDCNT(A3)„INCREMENT�TRY�COUNTŠBNE„DELAYS�WAIT�TO�TRY�AGAIN$ŠMOVE.L�#EETDIAGN,D0‡DIAGNOSTIC�(RD))ŠMOVE.L�#ABTNOMEM<<16,D3ƒNO�MEMORY�REASON+ŠBSR„TERMALLŒTERMINATE�ANY�OTHER�USER�TASKS ŠMOVE.L�#ABORT,D0ŠDIRECTIVE�TYPEŠMOVE.W�#ABTNOMEM,A0‡ABORT�CODEŠTRAPƒ#1*ˆ**�VOLUME�NOT�FOUND* PROC150ƒEQU„*ŠLEA„OFHS(A3),A0ŒSET�UP�POINTER0ŠMOVE.L�SYSDFLT(A3),FHSVOL(A0)�FETCH�VOLUME�NAME(ŠMOVE.L�#EM_VOLX,D0ˆVOLUME�ERROR�MESSAGE-ŠBRA„EMSGCALL‹OUTPUT�ERROR�MESSAGE�AND�RETURNŠPAGE**ˆCOMPLETED�GOOD�LOAD* PROC200ƒEQU„*7ŠMOVEM.L�USRTSK(A3),D1-D2†GET�TASK�NAME,�SESSION�LOADED%ŠMOVE.L�D1,UCBUTN(A3)†SET�TASK�LOADED*ŠMOVE.L�D2,UCBSESS(A3)…SAVE�LOADED�SESSION PROC206ƒEQU„*ŠCLR.L‚D6‘CLEAR�UPPER�PART,ŠMOVE.B�LDRCLL(A3),D6ŠGET�LENGTH�FROM�LOADER*ŠMOVE.L�D6,UCBLEN(A3)†SAVE�CMD�LINE�LENGTH**ˆ**�TEST�WHETHER�TO�START*$ŠBTSTƒ#BTUSBRK,D7ˆBREAK�DURING�LOAD?ŠBEQ.S‚PROC209ŒNO,�PROCEEDŠRTS PROC209ƒEQU„*'ŠBTSTƒ#BTLODGO,D7ˆTEST�WHETHER�TO�STARTŠBEQ.S‚PROC210ŒYES,�START ŠLEA„UCBUTN(A3),A0ŠPOINT�TO�TASK#ŠMOVE.L�#EM_LODED,D0‡LOADED�MESSAGE(ŠCMP.L‚#'0000',D2‰TEST�ASCII�SESSION�NO.ŠBCC.S‚PROC209A‹OK#ŠMOVE.L�#EM_LODEB,D0‡BINARY�VERSIONPROC209A‚EQU„*ŠBSR„ERRCALLŒOUTPUT#ŠBSETƒ#7,UCBUTN(A3)†SET�NOT�STARTEDŠRTS**,*ˆTRANSFER�EXISTING�LOGICAL�UNIT�ASSIGNMENTS* PROC210ƒEQU„*#ŠLEA„OFHS(A3),A0ŒFHS�PAR�BLOCK�ADDR!ŠMOVE.L�D2,FHSSES(A0)†SESSION�NO.(ŠMOVE.W�#FHCHLU,FHSCMD(A0)�CHANGE�LU�CMD"ŠBCLRƒ#31,D1�RESET�NOT�STARTED�BIT,ŠMOVE.L�D1,FHSTSK(A0)†PUT�TASK�NAME�IN�BLOCK*ŠMOVE.L�D1,UCBUTN(A3)†BECOMES�DEFAULT�TASK(ŠMOVE.L�UCBLUS(A3),D6ŠFETCH�LUN�BIT�MASKŠBTSTƒ#5,D6ŽLUN�5�ASSIGNED?ŠBEQ.S‚PROC235ŒNO,�ERRORŠBTSTƒ#6,D6ŽLUN�6�ASSIGNED?ŠBEQ.S‚PROC236ŒNO,�ERROR*ŠMOVE.L�UCBKEEP(A3),D4‰FETCH�LUN�KEEP�MASKŠCLR.L‚D5‘INITIALIZE�COUNTER$PROC215ƒBCLRƒD5,D6ŽCLEAR�BIT�IN�MASKŠTST.L‚D6‘TEST�DONEŠBEQ.S‚PROC250ŒBRANCH�DONE2PROC220ƒADD.L‚#1,D5ŽINCREMENT�TO�NEXT�BIT�POSITION%ŠBTSTƒD5,D6ŽTEST�CURRENT�BIT�POSITIONŠBEQ„PROC220ŒNO,�CONTINUE ŠMOVE.B�D5,FHSLUA(A0)†LUN�IN�SCTŠCMP.B‚#5,D5ŽIS�THIS�THE�CDF?ŠBNE.S‚PROC225ŒNO,�PROCEED!ŠBTSTƒ#BTREAD5,D7ˆCHAIN�OR�BATCH?'ŠBNE.S‚PROC225ŒCHAIN/BATCH�TRANSFER�5/51ŠCLR.B‚FHSLUA(A0)‰TRANSFER�INTERACTIVE�READ/WRITE PROC225ƒEQU„*'ŠMOVE.B�D5,FHSLUB(A0)†SAME�IN�USER�TASK4ŠMOVE.W�#FOPKEP+FOPSLU,FHSOPT(A0)�ASSUME�KEEP�OPTIONŠTST.B‚FHSLUA(A0)‰SENDING�0?ŠBEQ.S‚PROC230ŒKEEP!ŠBTSTƒD5,D4ŽKEEP?&ŠBNE.S‚PROC230ŒYES,�ASSUMPTION�CORRECT-ŠMOVE.W�#FOPSLU,FHSOPT(A0)�ALL�OTHERS�NO�KEEP PROC230ƒEQU„*ŠTRAPƒ#3‘GO�CHANGE�ITŠBEQ„PROC215ŒGOOD,�CONTINUEŠBSR„STDERROR‹REPORT�ERRORŠMOVE.L�D0,D3ŽSET�ABORT�CODEŠSWAPƒD31ŠBRA„TERM5ŽTERMINATE�TASK�THAT�CAN�NOT�BE�STARTED**ˆ**�LUN�5�AND/OR�6�MISSING* PROC235ƒEQU„*ŠMOVE.B�#'5',OFHS(A3)†LUN�NO.�5 ŠBRA.S‚PROC240ŒCOMMON�PROCESSING PROC236ƒEQU„*ŠMOVE.B�#'6',OFHS(A3)†LUN�NO.�6 PROC240ƒEQU„*$ŠLEA„OFHS(A3),A0ŒPOINT�TO�ERROR�TEXT(ŠMOVE.L�#EM_LUNER,D0‡BASIC�ERROR�MESSAGEŠBRA„STDERROR‹ERROR�EXIT**ˆ**�START�USER�TASK* PROC250ƒEQU„*!ŠMOVE.L�#GTDTIM,D0‰DIRECTIVE�TYPEŠLEA„UCBTUT(A3),A0ŠPUT�ADDRESSŠTRAPƒ#1$ŠBTSTƒ#BTREAD5,D7ˆCHAIN(BATCH)�MODE?ŠBEQ.S‚PROC252ŒNO,�SKIP2ŠAND.W‚#$7000,UCBREGD(A3)�RESET�ABORT,�ERROR�COUNT PROC252ƒEQU„*&ŠLEA„STRUTN(A3< ),A0ŠPARAMETER�BLOCK�ADR9ŠMOVEM.L�D1-D2,(A0)ˆTASK�NAME,�SESSION�TO�START�PAR�BLOCKŠMOVE.L�#START,D0ŠTRAP�TYPE)ŠBSR„PARTRAP1‹FIXED�PARMETER�BLOCK�TRAP�1ŠBNE.S‚PROC299ŒERROR�RETURN"ŠMOVE.L�UCBLUS(A3),D6ŠGET�BIT�MASK&ŠMOVE.L�UCBKEEP(A3),D4‰FETCH�KEEP�MASK&ŠBSETƒ#0,D4ŽFORCE�INTERACTIVE�TERMINAL'ŠAND.L‚D4,D6ŽRESET�ONE�TIME�ASSIGNMENTSŠMOVE.L�D6,UCBLUS(A3)†SAVE2PROC255ƒBTSTƒ#BTATSIGN,D7‡TEST�RETURN�TO�CMD�INPUTŠBNE.S‚PROC299 PROC260ƒEQU„*!ŠMOVE.L�#WTEVNT,D0‰DIRECTIVE�TYPEŠTRAPƒ#1*œWAIT�FOR�AN�EVENT‰TST.L…UCBUTN(A3)‰BEQ.S…PROC270*œAN�EVENT�OCCURRED *¦BRANCH�IF�THE�EVENT�WAS�FOR�ME‰BTST†#BTUSBRK,D7‰BEQ.S…PROC260*œJMP�IF�NOT�A�BREAK�EVENTPROC270: ‰TST.L…D0$*œESTABLISH�RETURN�STATUS�FOR�ANYONE*œWHO�IS�SEEKING�IT PROC299ƒRTS‰PAGE**ˆ**�COMMAND�NOT�FOUND�*** PROC300ƒEQU„*2ŠLEA„OFHS+FHSFIL(A3),A0…ADDRESS�OF�PARAMETER�BLOCK3ŠMOVE.L�#EM_CMDX,D0ˆBASIC�COMMAND�NOT�FOUND�MESSAGEŠBRA„EMSGCALL‹OUTPUT�MESSAGE* PROC320ƒEQU„*)ŠMOVE.L�#EM_CMDER,D0‡SYNTAX�ERROR�MESSAGEŠBRA„EMSGCALL‹OUTPUT�MESSAGEBLANKOUT‚DC.Bƒ$D8,0,0LMARGINƒDC.Bƒ'�',0CHANABRT‚DC.Bƒ'CHAIN�ABORTED',0ŠDC.Bƒ7’(BELL)ABPROMPT‚DC.Bƒ'(CHAIN)=',0ŠDC.Bƒ$AŠDC.Bƒ7’(BELL)PROMPT„DC.Bƒ$D,'=',0ŠDS…03IDSY†DC.Bƒ'ENTER�DEFAULT�SYSTEM�VOLUME:USER�NO.=',0LOGB†DC.Bƒ'ENTER�USER�NO.=',0ŠPAGEH*************************************************************************ˆ**�TRAP�1�SUPPORT�ROUTINESH************************************************************************;BCTRAP1ƒMOVEM.L�UCBBNAM(A3),D1-D2…GET�BCTPNAM�&�SESSION�NO.3STDTRAP1‚LEA„OFHS+24(A3),A0‰PARAMETER�BLOCK�ADDRESS#ŠMOVEM.L�D1-D6,-(A0)‡PUT�PARAMETERSPARTRAP1‚EQU„*ŠTRAPƒ#1‘EXECUTE�TRAP"ŠBNE„STDERROR‹OUTPUT�ERROR�MESSAGEŠRTSŠPAGEH*************************************************************************ˆ**�TRAP�2�SUPPORT�ROUTINESH************************************************************************!*ˆ**�READ�NEXT�COMMAND�INPUT�LINEH************************************************************************READLINE‚EQU„*0ŠLEA„CLASCODE,A4ˆINITIALIZE�VALIDATION�TABLE�ADR!ŠBTSTƒ#BTREAD5,D7ˆTEST�LUN�5�OR�0ŠBEQ.S‚ICALLŽBRANCH�DEVICE(ŠMOVEM.L�STDIO+8,D3-D5…COMMON�PARAMETERS ‰BSR‡X10000)*œADJUST�OFFSETS�TO�ADDRESSES�IN�D3,D4,D5&ŠMOVE.L�#PCIO,D1‹CODE,FUNCTION,OPTIONS(ŠMOVE.L�#PCLU,D2‹STATUS,LUN,RESERVED�(0)#ŠBCLRƒ#BTREREAD,D7‡CURRENT�OR�NEXT?ŠBEQ.S‚READCALL‹NEXT+ŠOR.Wƒ#IOPCUR,D1‰READ�CURRENT�RECORD�OPTION"ŠBRA.S‚READCALL‹COMMON�CALL�TO�I/O ICALL…EQU„*‰MOVE.L„UCBREGA6(A3),A5 *œA5=ADDRESS�'.ARG'�DATA�SEGMENT=ŠBTSTƒ#BTBELL&7,(SHAREOPT+1-(BTBELL/8))(A5)�RING�BELL�OPTION?ŠBEQ.S‚ICALL1�NOŠSUB.L‚#1,A6ŽINCLUDE�BELL ICALL1„EQU„*"ŠMOVE.B�#$80,D5ŒMESSAGE�TERMINATOR'ŠLEA„SCTINB(A3),A5ŠSTART�OF�BUFFER�ADDR%ŠBSR„BUILDMSG‹GENERATE�OUTPUT�MESSAGE'ŠMOVEM.L�STDIO,D1-D6‡GET�I/O�PARAMETERS ‰BSR‡X10000)*œADJUST�OFFSETS�TO�ADDRESSES�IN�D3,D4,D5 ŠMOVE.L�A5,D5ŽEND�BUFFER�ADDRESSREADCALL‚BSR„STDTRAP2‹I/O�CALLŠBEQ.S‚READCAL1‹OK#ŠCMP.B‚#ISTAIF,D0‰INVALID�FUNCTION?ŠBNE„STDERROR‹NO,�ERROR�PROCESS5ŠBCLRƒ#5,OFHS+2(A3)†READ�CURRENT�(BEGINNING�OF�FILE?)&ŠBEQ„EMSGCALL‹NO,�OUTPUT�ERROR�MESSAGE#ŠBSR„STETRAP2‹GO�BACK�AND�READ�NEXTREADCAL1‚EQU„*ŠBTSTƒ#BTEOF,D7ŠEOF?ŠBNE„READEXIT‹YES,�OK�-�EXIT%ŠMOVE.L�D0,-(A7)‹PUSH�STATUS�ON�STACK ŠMOVE.L�IOSLEN(A0),D6†GET�LENGTH1ŠLEA„SCTINB(A3),A0ŠGET�ADDRESS�OF�START�OF�BUFFER ŠLEA„0(A0,D6),A1ˆEND�OF�CMD�LINE ŠMOVE.B�#$D,(A1)+ŠPUT�TERMINATOR%ŠMOVE.B�#$A,(A1)+ŠLINE�FEED�FOLLOWING,ŠLEA„SCTINBE+1(A3),A0ƒALLOW�FOR�PREDECREMENTŠADD.L‚#1,D6ŽADJUST�COUNT READRELƒEQU„*$ŠMOVE.B�-(A1),-(A0)ˆMOVE�END�OF�LINEŠDBRAƒD6,READREL‰CONTINUE(ŠLEA„SCTINB(A3),A5ŠGET�READY�TO�PUT�BACK+ŠCLR.L‚D1‘INITIALIZE�UPPER�PART�OF�REGISTERSUBST…MOVE.B�(A0)+,D1‹GET�CHARŠCMP.B‚#$61,D1ŒLOWER�CASE?ŠBCS.S‚SUBST0�NO"ŠCMP.B‚#$7B,D1ŒSPECIAL�CHARACTERS?ŠBCC.S‚SUBST0�YES‰MOVE.L„A6,-(A7)‰MOVE.L„UCBREGA6(A3),A6 *œSAVE�REG�A6 *œA6=ADDRESS�'.ARG'�DATA�SEGMENTDŠBTSTƒ#BTNOLOHI&7,(SHAREOPT+1-(BTNOLOHI/8))(A6)�INHIBIT�TRANSLATION?#ŠB= NE.S‚SUBST00ŒYES,�DON'T�TRANSLATEŠSUB.B‚#$20,D1ŒFORCE�UPPER�CASESUBST00:‰MOVE.L„(A7)+,A6*œRESTORE�REG�A6 SUBST0„EQU„*ŠCMP.B‚#'=',D1Œ"="?ŠBNE.S‚SUBST1�NO,�PROCEED4ŠCMP.B‚#'/',(A0)ŠFOLLOWED�BY�"/"�(CHAIN�CONDITIONAL)ŠBNE.S‚SUBST1�NO,�PROCEED&ŠBSETƒ#BTSLASH,D7ˆSET�CONDITIONAL�FLAG SUBST1„EQU„*$ŠCMP.B‚#'\',D1ŒSUBSTITUTE�FOLLOWING?ŠBEQ.S‚SUBSTUTE‹YESSUBST2„CMP.L‚A5,A0ŽROOM?ŠBLS„SUBSOVFL‹ERROR�-�OVERFLOWŠMOVE.B�D1,(A5)+‹PUT�CHARŠCMP.B‚#$D,D1�END�OF�LINE?ŠBNE„SUBSTŽCONTINUEŠMOVE.B�(A0),(A5)ŠMOVE�THE�LF ŠMOVE.L�A5,UCBCMDND(A3)„SAVE�ENDŠMOVE.L�A5,D6ŽGET�END�ADDR$ŠLEA„SCTINB(A3),A0ŠSET�UP�START�ADDR"ŠSUB.L‚A0,D6ŽEXPANDED�INPUT�LENGTH#ŠMOVE.L�D6,UCBCMDLG(A3)„SAVE�LENGTH+ŠMOVE.L�(A7)+,D0‹POP�SAVED�STATUS�OFF�STACKŠTST.B‚D0‘RETEST�STATUS READEXIT‚RTS2STDIO…DC.LƒPIIO,PILU,SCTINB,SCTINB,SCTINBE,SCTINBL(PIIO†EQU„IOOWIN<<16+IOPIMG+IOPBRK+IOPUNPPILU†EQU„SCTLUN<<16PCIO†EQU„IOREAD<<16PCLU†EQU„CDFLUN<<16PLIO†EQU„IOWRIT<<16PLLU†EQU„LDFLUN<<16ŠPAGEH*************************************************************************ˆ**�ARGUMENT�SUBSTITUTIONH************************************************************************SUBSTUTE‚EQU„*#ŠMOVE.L�A0,A6ŽSAVE�STARTING�ADDRESS%ŠMOVE.B�(A0),D1ŒFETCH�FIRST�CHARACTERŠCMP.B‚#'(',D1ŒINDIRECT�RX?–++(ŠBEQ.S‚SUBSINDR‹YES,�INDIRECT�THRU�RX�++&ŠMOVE.B�0(A4,D1),D2ˆGET�ITS�CLASS�CODEŠBTSTƒ#0,D2ŽDECIMAL�DIGIT?ŠBNE.S‚SUBSTUT0‹BRANCH�YES**ˆ**�SEARCH�FOR�TAG*6ŠBCLRƒ#BTSUBPOS,D7‡RESET�POSITIONAL�SUBSTITUTION�(TAG)‰MOVE.L„UCBREGA6(A3),A0 *œA0=ADDRESS�'.ARG'�DATA�SEGMENT+ŠLEA„CHAINBUF(A0),A2ˆSTART�OF�ARGUMENT�LISTSUBFIND1‚EQU„*$ŠMOVE.L�A6,A0ŽREFETCH�STARTING�POINTSUBFIND2‚EQU„*)ŠMOVE.B�(A2)+,D1‹FETCH�ARGUMENT�CHARACTER'ŠBEQ„SUBFIND1‹BRANCH�END�OF�AN�ARGUMENT#ŠCMP.B‚#$D,D1�END�OF�ARGUMENT�LIST?ŠBEQ„SUBSTERR‹YES,�ERROR$ŠCMP.B‚#'=',D1ŒEND�OF�ARGUMENT�NAME?ŠBEQ.S‚SUBFIND4‹YES+ŠCMP.B‚(A0)+,D1‹INPUT�=�ARGUMENT�CHARACTER?$ŠBEQ„SUBFIND2‹YES,�CONTINUE�MATCHINGSUBFIND3‚EQU„*'ŠTST.B‚(A2)+ŽADVANCE�TO�END�OF�ARGUMENT(ŠBNE„SUBFIND3‹BRANCH�NOT�END�OF�ARGUMENTŠBRA„SUBFIND1‹TRY�AGAINSUBFIND4‚EQU„*(ŠCMP.B‚#'=',(A0)+‰DID�INPUT�CONTAIN�"="?#ŠBEQ.S‚SUBSTUT1‹YES,�ARGUMENT�FOUND"ŠBRA„SUBFIND3‹NO,�CONTINUE�LOOKING*Å++*ˆ**�INDIRECT�THROUGH�RX§++*Å++SUBSINDR‚EQU„*´++&ŠCMP.B‚#'R',1(A0)‰VERIFY�PSEUDO�REG‘++ŠBNE„SUBSTERR‹NO,�ERROR™++ŠCMP.B‚#'X',2(A0)‰VERIFY�RX™++ŠBNE.S‚SUBSTERR‹NO,�ERROR™++'ŠCMP.B‚#')',3(A0)‰VERIFY�CLOSE�PAREN�++ŠBNE.S‚SUBSTERR‹NO,�ERROR™++ŠADD.L‚#4,A0ŽUPDATE�POINTER”++)ŠBSETƒ#BTSUBPOS,D7‡SET�POSITIONAL�TYPE�++,ŠMOVE.W�UCBREGX(A3),D0…FETCH�PSEUDO�REG�X�++ŠBEQ.S‚SUBSTERR‹ZERO�ILLEGAL–++ŠBRA.S‚SUBSTUTA‹CONTINUEš++**ˆ**�GET�POSITIONAL�NUMBER*SUBSTUT0‚EQU„*3ŠBSETƒ#BTSUBPOS,D7‡SET�POSITIONAL�SUBSTITUTION�FLAG ŠBSR„CVT2�CONVERT�CHAR�TO�BINARYŠTST„D0‘TEST�ZEROSUBSTUTA‚EQU„*´++'ŠBEQ.S‚SUBNOARG‹NO.�ARGUMENTS�REQUEST�+)*‰LEA„CHPOSNUM(A3),A2ˆTABLE�OF�INCREMENTS‰MOVE.L„UCBREGA6(A3),A2*œA2=ADDR�'.ARG'�DATA�SEGMENT8ŠCMP.B‚(A2),D0ŒCOMPARE�MAX�NO�ENTRIES�TO�REQUESTED�ENTRY%ŠBGT.S‚SUBSTERR‹PARAMETER�NO.�TOO�BIG!ŠMOVE.B�0(A2,D0),D0ˆGET�INCREMENT-ŠLEA„$50(A2,D0),A2†FETCH�SUBSTITUTION�ADDRESSSUBSTUT1‚EQU„*'ŠBSETƒ#BTSUBSTU,D7‡SET�SUBSTITUTED�FLAG ŠTST.B‚(A2)�END�OF�SUBSTITUTION?#ŠBEQ„SUBSTŽYES,�END�OF�SUBSTITUTIONŠCMP.L‚A5,A0ŽROOM? ŠBLS.S‚SUBSOVFL‹ERROR�-�OVERFLOWŠMOVE.B�(A2)+,(A5)+ˆMOVE�CHARŠBRA„SUBSTUT1‹CONTINUESUBNOARG‚EQU„*´+‰MOVE.L„A2,-(A7)‰MOVE.L„UCBREGA6(A3),A2 *œSAVE�REG�A2 *œA2=ADDRESS�'.ARG'�DATA�SEGMENT+ŠMOVE.B�CHPOSNUM(A2),D0ˆGET�NO.�ARGUMENTS‘+‰MOVE.L„(A7)+,A2*œRESTORE�REG�A2ŠDIVUƒ#10,D0�GET�TENS,�UNITS“+ŠBSR.S‚SUBSPUTŒPUT�TENSš+ŠSWAPƒD0‘MOVE�UNITS˜+ŠBSR.S‚SUBSPUTŒPUT�UNITS™+(ŠBSETƒ#BTSUBSTU,D7‡SET�SUBSITUTED�FLAG�+ŠBRA„SUBSTŽCONTINUEš+SUBSPUTƒEQU„*´+ŠCMP.L‚A5,A0ŽROOM?�+ŠBLS.S‚SUBSPUTE‹NO�ROOM�ERROR•+ŠOR.Bƒ#'0',D0ŒFORCE�DIGIT—+ŠMOVE.B�D0,(A5)+‹TO�BUFFER™+ŠRTS¹+SUBSPUTE‚EQU„*´+ŠMOVE.L�(A7)+,D0‹POP�RETURN˜+SUBSOVFL‚EQU„*%ŠMOV= E.L�(A7)+,D0‹POP�STATUS�OFF�STACK#ŠMOVE.L�#EM_SCBO,D0ˆBUFFER�OVERFLOWŠBRA.S‚STDERROR‹ERROR�EXITSUBSTERR‚EQU„*$ŠMOVE.L�A6,A0ŽREFETCH�STARTING�POINT8ŠBTSTƒ#BTSLASH,D7ˆINHIBIT�ERROR�MESSAGES�ON�CONDITIONAL?&ŠBNE.S‚SUBSKIPŒSKIP�TO�END�OF�ARGUMENTŠSUB.L‚#1,A0ŽBACK�UP�TO�"/"ŠMOVE.B�(A0)+,D1‹FETCH�SLASH.ŠBSETƒ#BTSUBSER,D7‡SET�SUBSTITUTION�ERROR�FLAG)ŠBRA„SUBST2�RETURN�TO�COPY�ERROR�ARGUMENT SUBSKIPƒEQU„*ŠMOVE.B�#NOSUB,(A5)+‡EMPTY�FLAG:ŠBCLRƒ#BTSUBPOS,D7‡RESET/TEST�POSITIONAL�SUBSTITUTION�FLAGSUBSKIP1‚EQU„*#ŠMOVE.B�(A0)+,D1‹GET�NEXT�CHARACTER$ŠCMP.B‚#'\',D1ŒANOTHER�SUBSTITUTION?ŠBEQ„SUBSTUTE‹GO�TRY�ITŠCMP.B‚#'=',D1ŒEND�OF�ARGUMENT?ŠBEQ„SUBSTŽYES,�RETURNŠCMP.B‚#'!',D1ŒEND�OF�TERM?ŠBEQ„SUBST2�YESŠCMP.B‚#'&',D1ŒEND�OF�TERM?ŠBEQ„SUBST2�YES"ŠMOVE.B�0(A4,D1),D2ˆGET�CLASS�CODEŠBMI„SUBST2�RETURNŠBRA„SUBSKIP1‹CONTINUEŠPAGEH************************************************************************4*ˆ**�BUILD�STANDARD�ERROR�MESSAGE�WITH�TYPE�AND�CODEH************************************************************************STDERROR‚EQU„*!ŠBTSTƒ#BTMSGI,D7‰MESSAGE�INHIBIT?ŠBNE.S‚STDERROX‹YES,�EXITŠBTSTƒ#BTUSBRK,D7ˆBREAK?"ŠBNE.S‚STDERROX‹SKIP�ERROR�MESSAGEŠCMP.B‚#ISTATO,D0‰TIMEOUT?&ŠBEQ.S‚STDERROX‹YES�SKIP�ERROR�MESSAGEŠBTSTƒ#BTEOF,D7ŠEOF?"ŠBNE.S‚STDERROX‹SKIP�ERROR�MESSAGE1ŠBSR.S‚ECHOEŽECHO�INPUT�IF�NOT�PREVIOUSLY�PRINTEDŠBRA.S‚EMSGCAL1STDERROX‚EQU„*ŠTST.B‚D0‘RETEST�STATUSŠRTSH*************************************************************************ˆ**�ECHO�INPUT�TO�LDFH************************************************************************ ECHOS…EQU„*‰MOVE.L„A6,-(A7)‰MOVE.L„UCBREGA6(A3),A6 *œSAVE�REG�A6 *œA6=ADDRESS�'.ARG'�DATA�SEGMENT<ŠBTSTƒ#BTNOECHO&7,(SHAREOPT+1-(BTNOECHO/8))(A6)�TEST�NO�ECHOŠBEQ.S‚ECHOEX�ECHO‰MOVE.L„(A7)+,A6*œRESTORE�REG�A6 ‰BRA.S…ECHOSXECHOEX:‰MOVE.L„(A7)+,A6*œRESTORE�REG�A6'ECHOE…BTSTƒ#BTECHO,D7‰WAS�INPUT�ECHOED?ŠBNE.S‚ECHOSX�YES6ŠBTSTƒ#BTREAD5,D7ˆWAS�INPUT�FROM�INTERACTIVE�TERMINAL?ŠBNE.S‚ECHOTŽNO�DISPLAY�IT&ŠBTSTƒ#BTSUBSER,D7‡SUBSTITUTION�ERROR?ŠBNE.S‚ECHOTŽYES,�ECHOŠBTSTƒ#BTSUBSTU,D7‡SUBSITUTION?$ŠBEQ.S‚ECHOSX�NO,�NO�NEED�TO�DISPLAY ECHOT…EQU„*$ŠMOVEM.L�D0-D6/A0-A5,-(A7)�SAVE�REGSŠSUB.L‚#2,A5ŽADJUST�FOR�CR,LFŠBSR„WRITEINB‹OUTPUT�BUFFER'ŠMOVEM.L�(A7)+,D0-D6/A0-A5�RESTORE�REGSŠBSETƒ#BTECHO,D7‰SET�ECHOED�NOW ECHOSX„EQU„*ŠRTSH************************************************************************9*ˆ**�BUILD�MESSAGE,�PUT�INSERTS�IN�MESSAGE,�OUTPUT�TO�LDFH************************************************************************EMSGCALL‚EQU„*%ŠBTSTƒ#BTMSGI,D7‰TEST�MESSAGE�INHIBITŠBNE.S‚STDRTN�YES,�RETURNEMSGCAL1‚EQU„*3ŠBSETƒ#BTCHNABT,D7‡SET�FLAG�TO�ABORT�CHAIN�OR�BATCH ŠBRA„ERRCALL MSGCALLƒEQU„*'ŠLEA„SCTEXB(A3),A5†START�OF�BUFFER�ADDR%ŠCLR.L‚D5‘SET�CR,LF�AS�MSG�TERMINATOR ŠBSR.S‚BUILDMSG‹GENERATE�MESSAGEH************************************************************************#*ˆ**�WRITE�MESSAGE�IN�BUFFER�TO�LDFH************************************************************************‰LEA‡SCTEXB(A3),A0‰MOVE.L„A0,D4‰BUFFER�ADDRESSWRITELIN‚EQU„*&ŠMOVE.L�#PLIO,D1‹CODE,FUNCTION,OPTIONS(ŠMOVE.L�#PLLU,D2‹STATUS,LUN,RESERVED�(0) ŠMOVE.L�A5,D5ŽBUFFER�END�ADDRESS-ŠBTSTƒ#LDFLUN,UCBLUS+3(A3)‚IS�LUN�6�ASSIGNED?ŠBNE.S‚STDTRAP2‹YES,�OKŠCLR.L‚D2‘SET�LUN=0H************************************************************************1*ˆ**�STANDARD�TRAP�2�USING�COMMON�PARAMETER�BLOCKH************************************************************************3STDTRAP2‚LEA„OFHS+24(A3),A0‰PARAMETER�BLOCK�ADDRESS#ŠMOVEM.L�D1-D6,-(A0)‡PUT�PARAMETERSSTETRAP2‚TRAPƒ#2ŠBEQ.S‚STDRTN�GOOD,�EXITŠCMP.B‚#ISTANR,D0‰NOT�READY?ŠBNE.S‚STDTRBP2‹NO,�CONTINUE%ŠTST.L‚UCBTUT(A3)‰TEST�LOGON�COMPLETE!ŠBMI„BYEBYE�NO,�TERMINATE�SESSIONSTDTRBP2‚EQU„*)ŠCMP.B‚#ISTABRK,D0ˆTEST�BREAK�TERMINATIONŠBNE.S‚STDTRAQ2‹NO,�GO�EXIT%*œJMP�IF�OTHER�THAN�BREAK�TERMINATION‰TST.L…UCBTUT(A3) ‰BMI‡BYEBYE *œJUMP�IF*¦BREAK�TERMINATION*žBEFORE*¦LOGON�COMPLETED>  ŠBSETƒ#BTUSBRK,D7ˆSET�BREAK�FLAGŠBTSTƒ#BTREAD5,D7ˆCHAIN�MODE?ŠBEQ.S‚STDTRAT2‹NO,�EXIT'ŠBSETƒ#BTCHNABT,D7‡YES,�SET�CHAIN�ABORTŠBRA.S‚STDTRAT2‹EXITSTDTRAQ2‚EQU„*ŠCMP.B‚#ISTAEOF,D0ˆEND�OF�FILE?ŠBNE.S‚STDTRAT2‹NO,�EXITŠBSETƒ#BTEOF,D7ŠSET�EOF�FLAGSTDTRAT2‚TST.B‚D0‘RETEST�STATUS STDRTN„RTSŠPAGEH*************************************************************************ˆ**�WRITE�INPUT�BUFFERH************************************************************************BUILDINB‚EQU„*'ŠLEA„SCTINB(A3),A5ŠINPUT�BUFFER�ADDRESS!ŠCLR.L‚D5‘END�MESSAGE�WITH�RETURNŠBSR.S‚BUILDMSG‹BUILD�MESSAGEWRITEINB‚EQU„*‰LEA‡SCTINB(A3),A0"ŠMOVE.L�A0,D4ŽINPUT�BUFFER�ADDRESS"ŠBRA„WRITELIN‹FORMATTED�WRITE�LINE*ŠPAGE@*****************************************************************‚SUBROUTINE�TO�BUILD�MESSAGES*…CALLING�SEQUENCE:*ˆLEA�,A5#*ˆLEA�,A6(*ˆMOVE.B�CR,LF),D5*ˆBSR�BUILDMSG*E*********************************************************************+BUILDMSG‚MOVE.L�A5,A0ŽSAVE�STARTING�ADDRESSŠMOVE.L�D0,-(A7)‹SAVE�D0)BUILDMS1‚MOVE.B�(A6)+,(A5)+ˆGET�NEXT�CHAR'ŠBNE„BUILDMS1‹BRANCH�NOT�END�OF�MESSAGE5ŠMOVE.B�D5,-(A5)‹SUBSTITUTE�TERMINATING�CHAR�FOR�NULL*ŠBGT.S‚BUILDENX‹BRANCH�TERMINATING�CHAR�OKŠSUB.L‚#1,A5ŽBACKUP#BUILDENX‚MOVE.L�(A7)+,D0‹RESTORE�D0ŠRTSH************************************************************************4*ˆ**�SUBROUTINE�TO�LOAD�D2�WITH�PRINTABLE�CHARACTERSH************************************************************************GETNOSPA‚EQU„*!ŠCMP.B‚#'�',(A0)ŠIS�CHAR�A�SPACE?ŠBLE.S‚GETNOSPX‹YES,�EXIT ŠROL.L‚#8,D2ŽMAKE�ROOM�TO�INSERTŠMOVE.B�(A0)+,D2‹GET�CHAR GETNOSPX‚RTSH************************************************************************8*ˆ**�SUBROUTINE�TO�FETCH�FOUR�PRINTABLE�CHARACTERS�IN�D2H************************************************************************EDITSPAC‚EQU„*ŠCLR.L‚D2‘CLEAR�ACCUMULATOR+EDITSESS‚BSR„GETNOSPA‹GET�CHAR�IF�NOT�SPACEŠBSR„GETNOSPA‹"ŠBSR„GETNOSPA‹"ŠBRA„GETNOSPA‹"�(AND�RETURN)H************************************************************************4*ˆ**�SUBROUTINE�TO�LEFT�JUSTIFY�PRINTABLE�CHAR�IN�D2H************************************************************************&GETLJSFY‚ROL.L‚#8,D2ŽMOVE�TO�MAKE�ROOMŠCMP.B‚#'�',(A0)ŠSPACE�OR�CR?ŠBLE.S‚GETLJSFX‹YES,�EXITŠMOVE.B�(A0)+,D2‹TRANSFER�CHAR GETLJSFX‚RTSH************************************************************************$*ˆ**�GET�4�CHARACTERS�LEFT�JUSTIFIEDH************************************************************************GETLEFT4‚EQU„*ŠMOVE.L�#'„',D2‰INITIALIZE#ŠBSR„GETLJSFY‹GET�CHAR�IF�NOT�SPACE#ŠBSR„GETLJSFY‹GET�CHAR�IF�NOT�SPACE#ŠBSR„GETLJSFY‹GET�CHAR�IF�NOT�SPACE#ŠBRA„GETLJSFY‹GET�CHAR�IF�NOT�SPACE*ŠPAGEH*************************************************************************ˆ**�TRAP�3�SUPPORT�ROUTINESH************************************************************************9*ˆ**�ASSIGN�FILE/DEVICE�TO�LUN�AND�SET�BIT�IN�D7�BIT�MASKH************************************************************************FHOPNTID‚EQU„*2ŠMOVE.L�UCBTID(A3),OFHS+FHSVOL(A3)…GET�TERMINAL�ID FHOPEN„EQU„*(ŠMOVEM.W�(A1)+,D1-D3‡GET�CMD,OPTIONS,LUNFHEXOPEN‚BSR.S‚STDTRAP3ŠBNE„EMSGCALL‹ABORT�IF�BAD%ŠMOVE.L�UCBLUS(A3),D4ŠGET�LUN�BIT�MAP!ŠBSETƒD3,D4ŽSET�CORRESPONDING�BIT%FHOPENCƒMOVE.L�D4,UCBLUS(A3)†PUT�BACKŠTST.B‚D0‘TEST�STATUSŠRTS*H************************************************************************+*ˆ**�CLOSE�LUN�AND�RESET�BIT�IN�D7�BIT�MASKH************************************************************************ FHCLOSEƒEQU„*(ŠMOVEM.W�(A1)+,D1-D3‡GET�CMD,OPTIONS,LUN%FHEXCLOS‚BSR.S‚STDTRAP3‹CLOSE�COMMANDŠBNE„EMSGCALL‹ABORT�IF�BAD&ŠMOVE.L�UCBKEEP(A3),D4‰FETCH�KEEP�MASK#ŠBCLRƒD3,D4ŽRESET�CORRESPONDING�BIT$ŠMOVE.L�D4,UCBKEEP(A3)…PUT�BACK�MASK%ŠMOVE.L�UCBLUS(A3),D4ŠGET�LUN�BIT�MAP#ŠBCLRƒD3,D4ŽRESET�CORRESPONDING�BITŠBRA„FHOPENCŒCOMMON�EXIT*H******> ******************************************************************1*ˆ**�STANDARD�TRAP�3�USING�COMMON�PARAMETER�BLOCKH************************************************************************2STDTRAP3‚LEA„OFHS+6(A3),A0†PARAMETER�BLOCK�ADDRESS#ŠMOVEM.W�D1-D3,-(A0)‡PUT�PARAMETERS"ŠCLR.W‚30(A0)�CLEAR�RESERVED�SPACEŠTRAPƒ#3ŠRTSŠPAGEH*************************************************************************ˆ**�TRAP�4�SUPPORT�ROUTINESH*************************************************************************ˆ**�LOADER�CALLH************************************************************************ LDRCALLƒEQU„*%ŠMOVE.L�UCBSNO(A3),D0ŠCURRENT�SESSION*ŠMOVEM.L�STRUOPT(A3),D1-D3…OPTION,�MONITOR%ŠBCLRƒ#29,D1�RESET�REGISTERS�SUPPLIEDŠCLR.L‚D4‘SET�ATTRIBUTES‰MOVE.L„UCBREGA6(A3),A0 *œA0=ADDRESS�'.ARG'�DATA�SEGMENT/…BTST�#BTABTDMP&7,(SHAREOPT+1-(BTABTDMP/8))(A0)#*­ABORT�DUMP�REQUESTED?�[OPTION�'I'ŠBEQ.S‚LDRCAL0ŒNO%ŠBSETƒ#28,D4�SET�ABORT�DUMP�REQUESTED LDRCAL0ƒEQU„*-ŠMOVE.W�UCBPRILI,D3ˆASSUME�ON�LINE�PRIORITIESŠBTSTƒ#BTBATCH,D7ˆBATCH?ŠBEQ.S‚LDRCAL1ŒNO*ŠMOVE.W�UCBPRIBT,D3ˆFETCH�BATCH�PRIORITIESŠBRA.S‚LDRCAL2ŒCONTINUE LDRCAL1ƒEQU„*ŠBTSTƒ#BTREAD5,D7ˆCHAIN�MODE?!ŠBEQ.S‚LDRCAL2ŒASSUMPTION�CORRECT-ŠMOVE.W�UCBPRICH,D3ˆUSE�CHAIN�MODE�PRIORITIES LDRCAL2ƒEQU„*%ŠMOVE.L�USERNO(A3),D5ŠGET�USER�NUMBER"ŠLEA„LDRLDO(A3),A0ŠGET�PUT�ADDRESS(ŠMOVEM.L�D0-D5,-(A0)‡PUT�PARAMETER�BLOCK(ŠMOVE.W�#$603E,LDRLDO(A3)‚LOADER�OPTIONS)ŠMOVE.L�#LDRDIR,D0‰SERVER�FUNCTION�NUMBER'ŠLEA„UTTCBP(A3),A0ŠPARAMETER�BLOCK�ADDR!ŠCLR.W‚74(A0)�CLEAR�RESERVED�WORDŠTRAPƒ#4ŠRTSH*************************************************************************ˆ**�ERROR�MESAGE�CALLH************************************************************************ ERRCALLƒEQU„*'ŠMOVEM.L�D0/A0,SCTEXB(A3)‚SAVE�POINTERS ŠMOVE.L‚#2,D0‰LEA‡SCTEXB(A3),A0*œSET�RESPECTIVELY*œD0=DIRECTIVE$*œA0=MESSAGE�PARAMETER�BLOCK�ADDRESS0ŠMOVE.L�#(LDFLUN<<16+CDFLUN),8(A0)�LOGICAL�UNITS%ŠBTSTƒ#6,UCBLUS+3(A3)„LUN�6�ASSIGNED?ŠBNE.S‚ERRCALLS‹YES,�PROCEEDŠCLR.L‚8(A0)ŽUSE�LUN�0ERRCALLS‚EQU„*ŠTRAPƒ#4&ŠMOVEM.L�SCTEXB(A3),D0/A0†RESTORE�REGS ŠTST.L‚D0ŠRTSŠPAGEH************************************************************************ *ˆ**�GENERAL�SUPPORT�SUBROUTINESH************************************************************************5*ˆ**�SUPPORT�SUBROUTINE�TO�PUT�DATE/TIME�IN�REGISTERS*�TO�MESSAGE�BUFFER;*ˆREQUIRES�PUT�ADDRESS�IN�A0�WHICH�IS�INCREMENTED�ON�RETURN#*ˆREQUIRES�SEPARATOR�CHARATER�IN�D5 *ˆPUTS�SPACE�FOLLOWING�3RD�GROUP*H************************************************************************ŠBSR.S‚PUT�HH�OR�MMŠSWAPƒD0‘GET�OTHER�HALFŠBSR.S‚PUT�MM�OR�DD ŠMOVE.B�#'�',D5ŒSPACE�TERMINATORŠMOVE.L�D1,D0ŽGET�3RD�PARTŠBSR.S‚PUT�SS�OR�YYŠRTSPUT‡ROL.W‚#8,D0ŽGET�MS�CHARŠMOVE.B�D0,(A0)+‹TO�BUFFERŠROL.W‚#8,D0ŽGET�LS�CHARŠMOVE.B�D0,(A0)+‹TO�BUFFER$ŠMOVE.B�D5,(A0)+‹SEPARATOR�TO�BUFFERŠRTSH************************************************************************4*ˆ**�SUBROUTINE�TO�FIND�REMAINING�LENGTH�OF�CMD�LINEH************************************************************************ REMLEN„EQU„*ŠCMP.B‚#$D,D1�RETURN?ŠBNE.S‚REMLEN0ŒNOŠSUB.L‚#1,A0ŽBACKUPŠCLR.L‚D6‘ZERO�LENGTHŠBRA.S‚REMLEN3ŒEXIT REMLEN0ƒEQU„*"ŠMOVE.B�0(A4,D1),D2ˆGET�CLASS�CODE/ŠBMI.S‚REMLEN2ŒFIELD�TERMINATOR�OF�INPUT�STRING%REMLEN1ƒMOVE.B�(A0)+,D1‹GET�NEXT�CHARŠBRA„REMLEN�CONTINUE*REMLEN2ƒCMP.B‚#'�',(A0)ŠNEXT�CHAR�=�SPACE?$ŠBEQ„REMLEN1ŒYES,�CONTINUE�ADVANCING!ŠMOVE.L�UCBCMDND(A3),D6ˆGET�END+1ŠSUB.L‚A0,D6ŽGET�DIFFERENCE REMLEN3ƒEQU„*2ŠMOVE.L�D6,UCBCMDLG(A3)„SAVE�FOR�INITIAL�USER�REGS/ŠMOVE.L�A0,UCBCMDST(A3)„SAVE�NEW�STARTING�POINTŠRTSK****************************************************************************ˆ**�INCREMENT�PAST�SPACESK***************************************************************************INCPOINT‚ADD.L‚#1,A0ŽINCREMENTSKIPSPAC‚EQU„*ŠCMP.B‚#'�',(A0)ŠSPACE?ŠBEQ„INCPOINT‹YES,�INCREMENTŠRTS*ŠPAGEO************************? *******************************************************;*ˆ**�ASSIGN�FILE�IF�POSSIBLE�-�NOT�AN�ERROR�IF�NOT�POSSIBLEO**********************************************************************************ˆVERSACOMPUTER�REQUIREMENT*&*’A6=SCT�DATA�SEGMENT�ADDRESS�ON�INPUT*'*’A3=SCT�DATA�SEGMENT�ADDRESS�ON�OUTPUT**’D1=OPTIONS�FOR�THE�REQUEST*ASGNFILE‚EQU„* ‰MOVE.L„D1,D2*œD2=USER'S�REQUSTED�OPTIONS‰MOVE.L„A6,-(A7)*œA6=SCT�DATA�SEGMENT�ADDRESS,ŠMOVE.L�SYSDFLT(A6),D1‰SYSTEM�DEFAULT�VOLUME(ŠLEA„OFHS(A6),A0ŒPARAMETER�BLOCK�ADDRESSŠMOVE.L�A0,A6ŽSAVE�START$ŠMOVE.W�#FHASGN,(A6)+†ASSIGN�COMMANDL**************************************************************************** *‰MOVE.W�#FOPPRPW,(A6)+…OPTION¡***£THIS�INST�REMOVED�PER�ARNOLD'S�REQUEST�***£REPLACED�BY�HAVING�REGISTER�D1�CONTAIN�**£THE�DESIRED�OPTIONS”*L****************************************************************************‰MOVE.W„D2,(A6)+*£SET�USER'S�REQUESTED�OPTIONSŠMOVE.W�D3,(A6)+‹LUNŠMOVE.L�D1,(A6)+‹PUT�VOLUMEŠCLR.W‚(A6)+ŽUSER�=�0ŠMOVE.L�#'„',D2‰BLANKŠMOVE.L�#'PRIV',(A6)+†CATALOGŠMOVE.L�D2,(A6)+‹"ŠMOVE.L�(A3)+,(A6)+ˆFILEŠMOVE.L�(A3)+,(A6)+ˆ"ŠMOVE.W�(A3)+,(A6)+ˆEXTENTŠCLR.W‚(A6)+ŽRESERVED ŠCLR.L‚(A6)+‰MOVE.L„(A7)+,A3*œA3=SCT�DATA�SEGMENT�ADDRESSŠTRAPƒ#3‘ASSIGNŠRTSŠPAGEO*******************************************************************************(*ˆ**�PRINT�FILE�IF�POSSIBLE�TO�ASSIGN�ITO**********************************************************************************ˆVERSACOMPUTER�REQUIREMENT*&*’A6=SCT�DATA�SEGMENT�ADDRESS�ON�INPUT*'*’A3=SCT�DATA�SEGMENT�ADDRESS�ON�OUTPUT** PRTFILEƒEQU„*(ŠCLR.B‚UCBLDCNT(A6)‡INITIALIZE�TRY�COUNTŠMOVE.W�D3,-(A7)‹SAVE�LUN‰MOVE.W„#FOPPR,D1*œD1=PUBLIC�READ�OPTIONŠBSR„ASGNFILE‹ASSIGN�FILE3*œUPON�RETURN�A3�WILL�CONTAIN�SCT�DATA�SEGMENT�ADDRPRTFILEA‚EQU„*ŠBEQ.S‚PRTFILE1‹ASSIGNED-ŠCMP.B‚#FSTAAP,D0‰IN�USE?�(ACCESS�PERMISSION)ŠBNE„PRTFILEX‹NO*ŠADD.B‚#4,UCBLDCNT(A3)„INCREMENT�TRY�COUNT!ŠBEQ.S‚PRTFILEX‹OVERFLOW,�GIVE�UPŠMOVE.L�#500,A0ŒHALF�SECONDŠMOVE.L�#DELAY,D0ŠDELAY�COMMAND ŠTRAPƒ#1‘WAIT(ŠLEA„OFHS(A3),A0ŒPARAMETER�BLOCK�ADDRESSŠTRAPƒ#3‘TRY�AGAINŠBRA„PRTFILEA‹TRY�AGAINPRTFILE1‚EQU„*$ŠMOVE.B�#-20,UCBLDCNT(A3)‚LINE�COUNTPRTFILE2‚EQU„*#ŠMOVE.L�#IOREAD<<16,D1…READ�COMMANDŠMOVE.L�#1<<16,D2ŠLUN'ŠMOVEM.L�STDIO+8,D3-D5…BUFFER�ADDRESSES ‰BSR‡X10000)*œADJUST�OFFSETS�TO�ADDRESSES�IN�D3,D4,D5+ŠLEA„OFHS+24(A3),A0‰PARAMETER�BLOCK�ADDRESS#ŠMOVEM.L�D1-D6,-(A0)‡PUT�PARAMETERS ŠTRAPƒ#2‘READ!ŠBNE.S‚PRTFILEX‹EXIT�ON�ANY�ERROR(ŠMOVE.L�IOSLEN(A0),D5†GET�LENGTH�OF�READ‰LEA‡SCTINB-1(A3),A0ŠADD.L‚A0,D5ŽEND�OF�OUTPUT$ŠMOVE.L�#IOWRIT<<16,D1…WRITE�COMMANDŠMOVE.L�#6<<16,D2ŠLUN+ŠLEA„OFHS+24(A3),A0‰PARAMETER�BLOCK�ADDRESS#ŠMOVEM.L�D1-D6,-(A0)‡PUT�PARAMETERSŠTRAPƒ#2‘WRITEŠBNE.S‚PRTFILEX‹EXIT�ON�ERROR&ŠADD.B‚#1,UCBLDCNT(A3)„INCREMENT�COUNTŠBMI„PRTFILE2‹CONTINUE‰BTST†#BTREAD5,D7‰BNE.S…PRTFILE1*œJMP�IF�LUN�ASSIGNED�TO�A�FILEŠLEA„PRTMORE,A6‰MORE�MESSAGEŠBSR„READLINE‹OUTPUT�W/INPUTŠBEQ„PRTFILE1‹CONTINUE�IF�GOOD"ŠBSETƒ#BTEOF,D7ŠSET�FLAG�FOR�CR,LFPRTFILEX‚EQU„*&ŠMOVE.W�#FHCLOS,OFHS(A3)ƒCLOSE�COMMANDŠCLR.W‚OFHS+2(A3)$ŠMOVE.W�(A7)+,OFHS+4(A3)ƒREFETCH�LUNŠTRAPƒ#3‘CLOSEŠRTS3PRTMOREƒDC.Bƒ'',0ŠDS…0ŠPAGEH************************************************************************%*ˆ**�TEST,�SET�ERROR�IF�"*"�OR�DEVICEH************************************************************************!CKNODEVƒTST.B‚D0‘TEST�"*","/","#"ŠBNE.S‚CKNODERŒBRANCH�ERRORŠBTSTƒ#19,D0�TEST�FILE�FOUNDŠBNE.S‚CKNODEXŒOK,�EXIT!CKNODERƒBSETƒ#31,D0�SET�ERROR�BITCKNODEXƒTST.L‚D0ŠRTSH************************************************************************/*ˆ**�CHECK�FOR�"#"�AND�SUBSTITUTE�TERMINAL�I.D.H************************************************************************CKDEV…BTSTƒ#1,D0ŽDEVICE�FLAG?ŠBEQ.S‚CKEXIT�NO,�OK"ŠBTSTƒ#14,D0�NULL�VOLUME�(DEVICE)?ŠBEQ.S‚CKEXIT�BRAN? CH�NOT�NULL6ŠMOVE.L�UCBTID(A3),OFHS+6(A3)‚NULL,�SUPPLY�TERMINAL�ID CKEXIT„RTSŠPAGEO********************************************************************************ˆ**�GET/COMPUTE�ELAPSED�TIME*-*ˆCOMPUTES�THE�DATE/TIME�DIFFERENCE�(A0)-(A2)%*ˆTHE�DIFFERENCE�IS�PUT�IN�D1�AND�D2.**ˆCALLING�SEQUENCE:*�LEA�,A0*�LEA�,A2*�BSR�GETLAPSE****O*******************************************************************************GETLAPSE‚EQU„*4ŠMOVEM.L�(A0),D1-D2ˆTRANSFER�LATER�TIME�TO�REGISTERS;ŠSUB.L‚4(A2),D2ŠSUBTRACT�TIME�(MILLISECONDS�SINCE�MIDNIGHT)ŠBPL.S‚GETLAPS1‹NO�ROLLOVER%ŠADD.L‚#1000*60*60*24,D2‚ADD�ROLLOVER!ŠSUB.L‚#1,D1ŽDECREMENT�DATE�COUNTGETLAPS1‚EQU„*$ŠSUB.L‚(A2),D1ŒSUBTRACT�ORDINAL�DAYSŠRTSO*********************************************************************************ˆADD/CUMULATE�ELAPSED�TIME*B*ˆADDS�THE�ELAPSED�TIME�IN�REGS�D1�AND�D2�TO�THE�ADDRESS�SPECIFIED *ˆIN�REG�A1.*O*******************************************************************************ADDLAPSE‚EQU„*ŠADD.L‚4(A1),D2‹ADD�TIME&ŠCMP.L‚#1000*60*60*24,D2‚TEST�ROLLOVERŠBCS.S‚ADDLAPS1‹NO�ROLLOVER'ŠSUB.L‚#1000*60*60*24,D2‚SUBTRACT�1�DAY ŠADD.L‚#1,D1ŽINCREMENT�DAY�COUNTADDLAPS1‚EQU„*ŠADD.L‚(A1),D1ŒADD�DAYSŠMOVE.L�D1,(A1)+‹PUT�DAYS�BACK#ŠMOVE.L�D2,(A1)ŒPUT�CUMULATION�BACKŠRTS*‰PAGE** *ˆRTNE�TO9*’ADJUST�THE�OFFSETS�IN�REGISTERS�D3,�D4,�D5�TO�ADDRESSES*’IN�SCT'S�DATA�SEGMENT**ˆINPUT!*’A3�=�ADDRESS�SCT'S�DATA�SEGMENT**ˆOUTPUT *’D3�=�D3+A3 *’D4�=�D4+A3 *’D5�=�D5+A3*’A3�=�UNCHANGED*X10000: ‰ADD.L…A3,D5X10100: ‰ADD.L…A3,D4 ‰ADD.L…A3,D3.*œADJUST�OFFSETS�IN�'D?'�REGISTER�TO�ADDRESSES‰RTS‰PAGE*,*ˆThe�following�code�was�added�to�fix�SPR876*0*ˆThe�original�instruction�that�was�replaced�was *’BNE‡LOGOFF*:*ˆThe�problem�that�resulted�for�SPR876�is�that�a�chain�was:*ˆprocessing�in�'batch'�mode�but�a�task�that�was�called�in5*ˆthe�chain�file�aborted�and�terminated�the�batch�job?*ˆhowever,�if�a�query�was�performed�it�said�that�job�terminated<*ˆnormally.�So�this�logic�will�find�the�approriate�batch�job4*ˆand�change�its�status�to�terminated�while�running.**X10200:‰MOVE.L„UCBSNO(A3),D1+*œD1=SESSION�NUMBER�OF�BATCH�JOB�TO�LOG�OFF ‰BSR.S…X10300 *œFIND�SESSION�NUMBER�IN�JOB�QUE ‰BNE‡LOGOFF*œJMP�IF�UNABLE�TO�FIND4*œTHIS�IS�NO�DIFFERENT�THAN�THE�ORIGINAL�INSTRUCTION‰MOVE.W„#$C006,(A0)1*œCHANGE�BATCH�JOB�STATUS�FROM�NORMAL�TERMINATION*œTO�TERMINATED�WHILE�RUNNING ‰BRA‡LOGOFF* *ˆROUTINE�TO5*’FIND�THE�ENTRY�IN�THE�BATCH�JOB�QUE�FOR�THE�SESSION*’NUMBER�FOUND�IN�REGISTER�D1**ˆINPUT0*’D1�-�CONTAINS�THE�SESSION�NUMBER�SEARCHING�FOR**ˆOUTPUT*’STATUS'*œNON-ZERO�-->�SESSION�NUMBER�NOT�FOUND* ZERO�-->�SESSION�NUMBER…FOUND*4*’A0�-�CONTAINS�ADDRESS�IN�BATCH�JOB�QUE�FOR�SESSION'*—NUMBER�SEARCHING�FOR�IF�STATUS�=�ZERO***ˆREGISTERS�ALTERED**’A0X10300:‰LEA‡JOBQUEUE,A0X10400:‰CMP.L…ENDQUEUE,A0 ‰BPL.S…X105002*œJMP�IF�SESSION�NUMBER�NOT�FOUND�IN�BATCH�JOB�QUE‰CMP.L…4(A0),D1 ‰BEQ.S…X10600.*œJMP�IF�SESSION�NUMBER�FOUND�IN�BATCH�JOB�QUE ‰ADD.L…#8,A0 *œADJUST�TO�NEXT�BATCH�JOB�ENTRY ‰BRA.S…X10400 *œREPEAT�LOOP X10500: ‰TST.L…D1*œSET�NOT�FOUND�STATUSX10600:‰RTSŠEND éé@ ééé=/* =/*†USMLIB.CF=/* =OPTION O=DEL USMOPT.RO=LIB USMOPT.RO A CMDOPT1.RO A SECURE.RO A CHAINBAT.ROLQ=/*=ENDéééééééû =/***************=/* &.SYSGEN.CF *=/***************=OPT K,NM=/***************************************************************************#=/*�Chain�file�to�perform�sysgen:«*H=/*„To�restart�a�sysgen,�add�the�"S"�option�to�the�sysgen�command�lineƒ*G=/*„below�("=SYSGEN�\5,\6,\7;CT=nnn")�and�insert�the�pattern�matching„*D=/*„restart�text�on�a�new�line�immediately�after�this�line.‚If�you†*I=/*„want�to�keep�your�ASM/LINK�listing�file�(arg5),�you�must�delete�the‚*=/*„"=DEL�\5"�line�below.°*=/*É*=/*�Calling�sequence:·*=/*É*=/*ƒ=USE�vol:nbr.system³*(=/*ƒ=sys:9998..COPYSGEN.CF‚vol,vol,nbr£*+=/*ƒ=&.SYSGEN.CF�arg1,arg2,arg3,arg4,arg5¡*8=/*†where:‚vol=�volume�name�where�sysgen�is�to�be�done�*"=/*Žnbr=�user�numberƒ"…"„"‚"‚"ƒ"’*?=/*‹system=�system�to�sysgen�for:�EXORMACS,�VM01,�VM02,�VM03,…*=/*“VMES10,�VME110,�etc.¢*2=/*Žsys=�volume�name�where�SYSGEN�files�are�kept�*=/*É*E=/*‡Example:‚For�VM02�sysgen�on�hard�disk�SYS:�in�user�number�9100,‚*=/*‘enter�the�following:¤*=/*“@ =USE�SYS:9100.VM02¤**=/*“=MSTR:9998..COPYSGEN.CF‚SYS,SYS,9100‘*!=/*“=&.SYSGEN.CF�,,L1.LS,,L2.LS›*=/*—or°*=/*“=USE�SYS:9100.VM02¤**=/*“=MSTR:9998..COPYSGEN.CF‚SYS,SYS,9100‘*=/*“=STD.SYSGEN.CF¨*=/*É*7=/*„Not�all�of�the�arguments�need�to�be�entered�since”*$=/*†they�each�have�a�default�value¥*=/*É*<=/*„arg1�-�command�file�name�(defaults�to�'&.VERSADOS.CD')�*=/*É*,=/*„arg2�-�Temp�vol�and�user�no./Boot�fileŸ*9=/*�Temp.�vol.�and�user�no.�defaults�to�volume�name�and‰*)=/*�user�number�of�command�file�(arg1).—*3=/*�Boot�file�defaults�to�'.VERSADOS.SY'.�*=/*É*=/*É*9=/*„arg3�-�List�device�or�file�name�for�sysgen�messages’*'=/*�(defaults�to�.SYSLIST.LS)›*;=/*‹If�file�name�-�sysgen�uses�'.LS'�as�default�extension‰*=/*É*9=/*‡NOTE:�The�first�three�arguments�are�the�same�as�the�*4=/*�three�command�line�fields�used�in�invoking�theŽ*=/*�sysgen�utility�directly.¤*=/*É*$=/*„arg4�-�Reserved�for�future�use§*=/*É*6 GJ ?=/*‹Reference�0.PRIV.NEWS.NW�to�see�how�to�sysgen�an�EXORMACS…*6=/*‹for�a�FLOPPY�only�system�or�a�SINGLE-HARD�systemŽ*=/*É*E=/*„arg5�-�Listing�device�or�file�(Defaults�to�.SYSASML.LS)†*A=/*�Legal�devices�are�#,#PR,#PR1,#PR2,#PR3,#NULL�or�a�file�name.*==/*�All�assembly�listings�and�link�maps�will�be�directed�to…*>=/*�the�specified�device�or�file�using�the�copy�utility�with„*>=/*�append�option.‚SYSGEN.TF�is�used�as�an�intermediate�fileƒ*2=/*�to�contain�the�assembly�or�link�list�output.�*A=/*�Due�to�restrictions�in�sysgen�literal�substitution�process,�*8=/*�this�field�cannot�contain�more�than�30�characters.Š*M=/***************************************************************************=/*F=/* Make sure they have CNFGDRVR.CI in the catalog they have selected.:=/* This is to make sure they are not in the Null catalog.=DIR CNFGDRVR.CI=/IF RD (12) = 1ƒ=OPT�-Nƒ=/*�*****�ERROR�*****Cƒ=/*�You�MUST�have�the�catalog�set�to�the��you�are�going�to*ƒ=/*�sysgen�for.‚Please�set�and�try�again.ƒ=@END=/ENDIF=/*5=/* Insure that no more than 5 arguments are defined:=/*=/RX=\0 =/IF RX>5ƒ=OPT�-N<ƒ=/*�Error�-�chain�file�started�with�more�than�5�arguments�-ƒ=/*@ƒ=/*‚Please�list�this�file,�"&.SYSGEN.CF",�for�more�information.ƒ=/*ƒ=@END=/ENDIF=/*2=/* Force the definition of 5 exactly 5 arguments.=/* =/IF RX=0+ƒ=ARG�&.VERSADOS.CD,,SYSLIST.LS,,SYSASML.LS=/ENDIF =/IF RX=1 ƒ=ARG�\1,,SYSLIST.LS,,SYSASML.LS=/ENDIF =/IF RX=2"ƒ=ARG�\1,\2,SYSLIST.LS,,SYSASML.LS=/ENDIF =/IF RX=3ƒ=ARG�\1,\2,\3,,SYSASML.LS=/ENDIF =/IF RX=4ƒ=ARG�\1,\2,\3,\4,SYSASML.LS=/ENDIF=/*8=/* We have 5 arguments - now default any null arguments=/*=/IFC \1ƒ=ARG�&.VERSADOS.CD,\2,\3,\4,\5=/ENDIF=/*=/IFC \3ƒ=ARG�\1,\2,SYSLIST.LS,\4,\5=/ENDIF=/*=/IFC \5ƒ=ARG�\1,\2,\3,\4,SYSASML.LS=/ENDIF=/*G=/* If arg5 is not #PR,#PR1,#PR2,#PR3,# or #NULL then treat as file and:=/*ƒset�switch�(arg6)�to�1�for�printer�device,�0�for�file.=/*0=ARG \1,\2,\3,\4,\5,0,#PR,#PR1,#PR2,#PR3,#,#NULL =/FOR 7,\0ƒ=/IFEQ�"\5"\(RX)1†=ARG�\1,\2,\3,\4,\5,1,#PR,#PR1,#PR2,#PR3,#,#NULLƒ=/ENDIF=/ENDFOR=/RX=\6 =/IF RX=0ƒ=DEL�\5ƒ=DEL�XVERSAPT.LS=/ENDIF=/*#=ARG \1,\2,\3,\4,\5,\6,\7,SYSGEN.TF=/*3=/* The argument list now looks like the following:=/* =/*ƒarg1ƒ-ƒName�of�command�file.=/*0=/*ƒarg2ƒ-ƒTemporary�volume/boot�file�(or�null).=/*3=/*ƒarg3ƒ-ƒList�device�or�file�for�sysgen�messages.=/*"=/*ƒarg4ƒ-ƒReserved�for�future�use=/*@=/*ƒarg5ƒ-ƒListing�file�or�device�for�assemblies�and�link-edits.4=/*�SYSGEN.TF�is�the�temporary�file�which�is�used�in1=/*�conjunction�with�=COPY�;A�to�produce�a�single=/*�listing�file.=/*�(see�arg6)=/*=/*ƒarg6ƒ-ƒSwitch�-"=/*�0�A =‚arg5�specifies�a�file�name=/*�1�=‚arg5�specifies�a�device=/*�(see�arg5)=/*"=/*ƒarg7ƒ-ƒReserved�for�future�use=/*8=/*ƒarg8ƒ-ƒSYSGEN.TF�temporary�file�for�use�with�copy�in+=/*�creating�listing�file�specified�by�arg3=/*=/*9=/* Justify argument positions and invoke sysgen utility.=/*=ARG \5,\6,\7,\8,\1,\2,\3,\4=/*)=/* Turn off echo of sysgen command lines =OPT J,-N=TIME=SYSGEN \5,\6,\7;CT=350=TIME =OPT -J,N=/*H=/* The following SGSYMBL utility will produce a cross reference listingG=/*�of�all�the�sysgen�parameters.‚The�listing�will�show�the�symbol,�theE=/* value, the file(s) that define the parameter and the file(s) thatI=/*�reference�the�parameter.‚The�input�file�for�this�utility�is�SGSYMS.SYG=/* which is created from sysgen if the 'C' option was specified on theI=/*�sysgen�command�line.‚The�output�file�from�this�utility�is�SYMBOLS.LS.=/*=SGSYMBL=OPT -N=/**C=/**‚Applying�patches�from�".XVERSAPT.CF"�to�the�boot�file.=/**=/@ XVERSAPT.CF=/RX=\2 =/IF RX=0ƒ=LIST�XVERSAPT.CF,XVERSAPT.LSƒ=COPY�XVERSAPT.LS,\1;Aƒ=DEL‚XVERSAPT.LS=/ELSEƒ=LIST�XVERSAPT.CF,\1=/ENDIFM=/***************************************************************************M=/***************************************************************************=/**=/**‚Sysgen�Completed�--=/**1=/**„Sysgen�command�listing�has�been�output�to�\7=/**6=/**„Assembly�and�link�listings�have�been�output�to�\1=/**M=/***************************************************************************M=/***************************************************************************=OPT -K=ENDéééééé**ˆ&.CMDLIST.AG*.CMDLISTƒIDNTƒ3,27�SESSION�CONTROL�COMMAND�LIST ŠSECTION�8ŠXDEFƒCMDACCTTŠXDEFƒCMDPWVALŠXDEFƒCOMTSKNO ŠXDEFƒDEFAULTŠXDEFƒEET_GFLG ŠXDEFƒEETSBATŠXDEFƒINDFVOLN ŠXDEFƒINITPAR ŠXDEFƒINSWORDŠXDEFƒLODRETRY ŠXDEFƒLOGMŠXDEFƒLOGNTERMŠXDEFƒLOGTRYNO ŠXDEFƒPATCH ŠXDEFƒSYSCMD ŠXDEFƒSYSCMDS ŠXDEFƒSYSOPTŠXDEFƒSYSTBEND ŠXDEFƒTIMECNTŠXDEFƒUCBMAXLUŠXDEFƒUCBPRIBTŠXDEFƒUCBPRICHŠXDEFƒUCBPRILI* *ˆ**�EQUATES*SPCCMD„EQU„\SPCCMDCHAINBAT‚EQU„\CHAINBATSECURITY‚EQU„\SECURITYTOTTERMƒEQU„\TOTTERMCONBATCH‚EQU„\CONBATCHBATCHPGE‚EQU„\BATCHPGENOLOGONƒEQU„\NOLOGONMAXLU…EQU„\MAXLUTERMOCNT‚EQU„\TERMOCNTBATDLY„EQU„\BATDLYNOLOGONS‚EQU„\NOLOGONS*EETPNAMƒEQU„'&EET'DCLSHR„EQU„7’DECLARE�SHAREABLEA GTASQ…EQU„31‘GET�ASQSGATRO„EQU„$4000ŽREAD�ONLY$SGATGS„EQU„$1000ŽGLOBALLY�SHAREBABLE AQSTQE„EQU„16SOSYSMSG‚EQU„1’BIT�POSITION�FOR�INITIALIZING�CHAINFILE'IOUCBK„EQU„$8001ŽCLAIM�UNCLAIMED�BREAKS+ISECLVLƒEQU„0’INITIAL�SECURITY�LEVEL�(NONE)*ISWORD1ƒEQU„0’INITIAL�SECURITY�WORD�PART�1*ISWORD2ƒEQU„0’INITIAL�SECURITY�WORD�PART�2*MAXVNTLN‚EQU„26‘NO.�BYTES�SCT�EVENTS�(MAX)DMAXTSKNO‚EQU„8‡MAX�NO.TASKS�COMMUNICATING�WITH�SCT�(TERM,ABORT,ATTN)#IPRIUTSK‚EQU„66‘INITIAL„"ƒUSER�TASKLPRIUTSK‚EQU„127�LIMIT…"…"ƒ".IPRICTSK‚EQU„66‘INITIAL„"„CHAIN�MODE�USER�TASK-LPRICTSK‚EQU„127�LIMIT…"„CHAIN�MODE�USER�TASK.IPRIBTSK‚EQU„65‘INITIAL„"„BATCH�MODE�USER�TASK,LPRIBTSK‚EQU„65‘LIMIT†"„BATCH�MODE�USER�TASK*2*ˆ**�OPTION�BITS�FOR�SYSOPT�(1=INCLUDE,�0=EXCLUDE)*KINITFILE‚EQU„1�ACTIVATE�INITIALIZING�CHAINFILE�(PRIV.UPSYSTEM.NW)�SESSION�1*ŠPAGE*ˆ**�IDENTIFICATION�MESSAGE.LOGM†DC.Bƒ$D8,'\LOGMSG1\REVNUMBR‹\$DATE\$TIME'ŠDS.W†0ŠDS.BƒLOGM+80-***ˆ**�INITIALIZATION�INFORMATION*"INITPARƒDC.BƒTOTTERMŒNO.�TERMINALS2ŠDC.BƒCONBATCH‹NO.�CONCURRENT�BATCH�JOBS�EXECUTING9ŠDC.BƒBATCHPGE‹NO.�PAGES�BATCH�QUEUING�(32�JOBS�PER�PAGE)$ŠDC.BƒISECLVLŒINITIAL�SECURITY�LEVEL1INSWORDƒDC.LƒISWORD1ŒINITIAL�SYSTEM�SECURITY�WORD ŠDC.LƒISWORD2%Q.H6g>6INDFVOLN‚DC.Lƒ'„'�System�default�volume�name�(dynamic)ŠDC.Lƒ0’RESERVEDŠDC.Lƒ0’RESERVED?COMTSKNO‚DC.BƒMAXTSKNO‹MAXIMUM�NO.�TASKS�COMMUNICATING�WITH�SCT9LOGTRYNO‚DC.BƒNOLOGONŒNO.�LOGON�TRIES�BEFORE�REJECT�LOGONFUCBPRILI‚DC.BƒIPRIUTSK,LPRIUTSK‚PRIORITIES�FOR�ON�LINE�MODE�USER�TASKSDUCBPRICH‚DC.BƒIPRICTSK,LPRICTSK‚PRIORITIES�FOR�CHAIN�MODE�USER�TASKSDUCBPRIBT‚DC.BƒIPRIBTSK,LPRIBTSK‚PRIORITIES�FOR�BATCH�MODE�USER�TASKS,UCBMAXLU‚DC.BƒMAXLUŽNUMBER�MAX�LUNS�PER�TASK;TIMECNTƒDC.BƒTERMOCNT‹LOG�OFF�AFTER�SPECIFIED�NO.�TIME�OUTS1SYSOPT„DC.BƒINITFILE<LODRETRY‚DC.LƒBATDLY�WAIT�TO�RETRY�LOAD�IF�NO�MEMORY�AVAILABLEŠDC.Lƒ0,0�RESERVEDPATCH…DS.Bƒ$80�PATCH�AREA.DEFAULTƒDC.Bƒ'\DEFAULT'‰Default�volume:usn.catŠDC.Bƒ$0D,$0AŒCr,LfŠDS…0’Force�even�byte�boundaryŠPAGE**:*ˆGENERAL�USAGE�FLAG�FOR�'YES'�OR�'NO'�TYPE�CONSIDERATIONS** EET_GFLG:‰DC.W†\AUTOLOGN *œBIT‡MEANING *ž0‡AUTOLOGN*¦0�-->�Auto�break�denied*¦1�-->�Auto�break�requested*ž1*¦0�-->�Auto�vol:usn.cat�denied"*¦1�-->�Auto�vol:usn.cat�requested**œ2-15†Available�for�use* LOGNTERM:‰DC.B†\AUTOTERM'*œTERMINAL�ID�AUTO�LOGON�IS�TO�OCCUR�ONŠPAGEH************************************************************************&*ˆ**�TABLE�OF�SESSION�CONTROL�COMMANDS*”========================H************************************************************************ SYSCMDSƒEQU„***ˆ**�BASIC�CONTROL�COMMANDS*/ŠXREFƒLOGOFF,LOGBYE,LOAD,USTRT,STOPTASK,CONTINU&ŠXREFƒTRMINATE,PROC260,LOGDATE,LOGTIMEŠXREFƒUSE,DEFAULTS,ARG,NOARGŠXREFƒBREAKS,BREAKT,OPTCMDŠXREFƒEETSXT,EETSBATESYSCMD„DC.Bƒ'LOG�OF',$E6,0…F ŠDC.LƒLOGOFFŠDC.Bƒ'LOGOF',$E6,0†F ŠDC.LƒLOGOFF ŠDC.Bƒ'OFF',0 ŠDC.LƒLOGOFF ŠDC.Bƒ'BYE',0 ŠDC.LƒLOGBYEŠDC.Bƒ'LOAD',0 ŠDC.LƒLOADŠDC.Bƒ'STAR',$F4,0‡T ŠDC.LƒUSTRTŠDC.Bƒ'STOP',0ŠDC.LƒSTOPTASK#ŠDC.Bƒ'CONT',$E9,$EE,$F5,$E5,0�INUE ŠDC.LƒCONTINU(ŠDC.Bƒ'TERM',$E9,$EE,$E1,$F4,$E5,0�INATEŠDC.LƒTRMINATEŠDC.Bƒ'^',0ŽHALT�TERMINAL�INPUTŠDC.LƒPROC260ŒGO�WAIT�FOR�EVENTŠDC.Bƒ'DATE',0 ŠDC.LƒLOGDATEŠDC.Bƒ'TIME',0 ŠDC.LƒLOGTIME ŠDC.Bƒ'USE',0 ŠDC.LƒUSE'ŠDC.Bƒ'DEF',$E1,$F5,$EC,$F4,$F3,0�AULTSŠDC.LƒDEFAULTS,ŠDC.Bƒ'ARG',$F5,$ED,$E5,$EE,$F4,$F3,0�UMENTS ŠDC.LƒARG.ŠDC.Bƒ'NOARG',$F5,$ED,$E5,$EE,$F4,$F3,0�UMENTS ŠDC.LƒNOARGŠDC.Bƒ'BSTO',$F0,0‡P ŠDC.LƒBREAKSŠDC.Bƒ'BTER',$ED,0‡M ŠDC.LƒBREAKT"ŠDC.Bƒ'OPT',$E9,$EF,$EE,$F3,0�IONS ŠDC.LƒOPTCMD*ˆ**�OPTIONAL�COMMANDS ŠIFNEƒSPCCMDŠXREFƒNEWS,HELP,ASSIGN,CLOSEŠDC.Bƒ'NEWS',0 B ŠDC.LƒNEWSŠDC.Bƒ'HELP',0 ŠDC.LƒHELPŠDC.Bƒ'ASSI',$E7,$EE,0ƒGN ŠDC.LƒASSIGNŠDC.Bƒ'CLOS',$E5,0‡E ŠDC.LƒCLOSEŠENDC"*ˆ**�CHAIN/BATCH�OPTIONAL�COMMANDSŠIFNEƒCHAINBAT)ŠXREFƒCHAIN,CMDEND,RETRY,PROCEED,REGCHAINŠDC.Bƒ'CHAI',$EE,0‡N ŠDC.LƒCHAIN ŠDC.Bƒ'END',0 ŠDC.LƒCMDENDŠDC.Bƒ'RETR',$F9,0‡Y ŠDC.LƒRETRYŠDC.Bƒ'PROC',$E5,$E5,$E4,0�EED ŠDC.LƒPROCEED ŠDC.Bƒ'R?',0ŠDC.LƒREGCHAINŠXREFƒBATCH,CANCEL,ELIM,QUERYŠDC.Bƒ'BATC',$E8,0‡H ŠDC.LƒBATCHŠDC.Bƒ'CANC',$E5,$EC,0ƒEL ŠDC.LƒCANCELŠDC.Bƒ'QUER',$F9,0‡Y ŠDC.LƒQUERY(ŠDC.Bƒ'ELIM',$E9,$EE,$E1,$F4,$E5,0�INATE ŠDC.LƒELIMŠENDC*ˆ**�SECURITY�OPTIONAL�COMMANDSŠIFNEƒSECURITY%ŠXREFƒPASS,SWORD,SECURE,PWVAL,ACCTINNŠDC.Bƒ'PASS',$F7,$EF,$F2,$E4,0 ŠDC.LƒPASSŠDC.Bƒ'SWORD',0 ŠDC.LƒSWORDŠDC.Bƒ'SECURE',0 ŠDC.LƒSECUREŠENDCSYSTBEND‚DC.Wƒ0,0,0*#*ˆ**�TRANSFER�FOR�BATCH�TERMINATION*ŠIFEQƒCHAINBATEETSBATƒBRA„EETSXT�IGNOREŠENDCŠIFNEƒCHAINBATEETSBATƒBRA„EETSBATEŠENDC*%*ˆ**�TRANSFER�FOR�PASSWORD�VALIDATION*ŠIFEQƒSECURITY CMDPWVAL‚RTS**D*ˆENTRY�POINT�''''CMDACCTT''''�MUST�HAVE�A6=SCT�DATA�SEGMENT�ADDRESS*C*ˆEXIT�FROM�''''CMDACCTT''''�WILL�HAVE�A3=SCT�DATA�SEGMENT�ADDRRESS** CMDACCTT: ‰MOVE.L„A6,A3*œA3=SCT�DATA�SEGMENT�ADDRRESSŠRTSŠENDCŠIFNEƒSECURITYCMDPWVAL‚BRA„PWVAL**D*ˆENTRY�POINT�''''CMDACCTT''''�MUST�HAVE�A6=SCT�DATA�SEGMENT�ADDRESS*C*ˆEXIT�FROM�''''CMDACCTT''''�WILL�HAVE�A3=SCT�DATA�SEGMENT�ADDRRESS**CMDACCTT‚BRA„ACCTINNŠENDC*ŠDS.BƒLOGM+$300-* ŠSECTION�19ŠXDEFƒBEGQUEUE,ENDQUEUE,STTABL,STTABLND,JOBQUEUE,JOBQUEND&ŠXDEFƒTESEGPGM,TESEGSTT,TASQPAR,BRKPAR ŠXREFƒEETASRBEGQUEUE‚DC.LƒJOBQUEUEENDQUEUE‚DC.LƒJOBQUEND STTABL„EQU„* STTABLND‚EQU„STTABL+(8*NOLOGONS)JOBQUEUE‚EQU„STTABLND*:*ˆ**�FOLLOWING�EXEC�&�FHS�CALLS�EXECUTED�AT�INITIALIZATION9*ˆ**�THEN�CLEARED�TO�BECOME�STT�TABLE�AND�BATCH�JOB�QUEUE*@TESEGPGM‚DC.LƒDCLSHR,0,0,SGATRO+SGATGS,EETPNAM�DECLARE�SHAREABLE?TESEGSTT‚DC.LƒDCLSHR,0,0,SGATRO+SGATGS,'.STT'�DECLARE�SHAREABLE$TASQPARƒDC.LƒGTASQ,EETPNAM,0„GET�ASQŠDC.BƒAQSTQE,MAXVNTLN,ŠDC.Lƒ0’QUEUE�LENGTH�INITIALIZED�AT�START�UPŠDC.LƒEETASR,0BRKPAR„DC.WƒIOUCBK,0ŠDC.Lƒ0ŠDS.BƒBEGQUEUE+$100-*ŠDS.BƒBATCHPGE*$100JOBQUEND‚EQU„*ŠENDééééé-INITDATƒIDNTƒ3,1�System�Initializer�DATA�Area*-*„THE�FOLLOWING�EQUATES�ARE�USED�FOR�BUILDING%*„A�MEMORY�TABLE�FOR�THE�INIT�ROUTINE*MTYP0…EQU„0’RAM�MEMORY�TYPE�0 MTYP1…EQU„1*16�RAM�MEMORY�TYPE�1 MTYP2…EQU„2*16�RAM�MEMORY�TYPE�2 MTYP3…EQU„3*16�RAM�MEMORY�TYPE�3 MTYP4…EQU„4*16�RAM�MEMORY�TYPE�4 MTYP5…EQU„5*16�RAM�MEMORY�TYPE�5 MTYP6…EQU„6*16�RAM�MEMORY�TYPE�6 MTYP7…EQU„7*16�RAM�MEMORY�TYPE�7*PART0…EQU„0’PARTITION�NUMBER�0PART1…EQU„1’PARTITION�NUMBER�1PART2…EQU„2’PARTITION�NUMBERB �2PART3…EQU„3’PARTITION�NUMBER�3PART4…EQU„4’PARTITION�NUMBER�4PART5…EQU„5’PARTITION�NUMBER�5PART6…EQU„6’PARTITION�NUMBER�6PART7…EQU„7’PARTITION�NUMBER�7PART8…EQU„8’PARTITION�NUMBER�8PART9…EQU„9’PARTITION�NUMBER�9!PART10„EQU„10‘PARTITION�NUMBER�10!PART11„EQU„11‘PARTITION�NUMBER�11!PART12„EQU„12‘PARTITION�NUMBER�12!PART13„EQU„13‘PARTITION�NUMBER�13!PART14„EQU„14‘PARTITION�NUMBER�14!PART15„EQU„15‘PARTITION�NUMBER�15 (* Get board specific memory type equates INCLUDE MTYPE.SIŠPAGE*#*†MACRO�TO�BUILD�MEMORY�TABLE�ENTRY* MTENTRYƒMACRO \@A‡SET„0ŠIFC„'\1','RAM' �DC.Bƒ\4+\5,0 �DC.Lƒ\2,\3�DC.Bƒ\6�DC.Bƒ0 \@AŠSET„1ŠENDCŠIFC„'\1','ROM' �DC.Bƒ$FF,0 �DC.Lƒ\2,\3�DC.Wƒ0 \@AŠSET„1ŠENDC ŠIFEQƒ\@A �FAILƒ2000ŠENDCŠENDM* MTEND…MACRO ŠDC.Wƒ$FFFFŠENDM ŠPAGE ŠSECTION�8*4*ˆISSUE�RETURN�FOR�SYSTEM�INITIALIZER�EXECUTION�CODE*‰RTS  *%*ˆDATA�REQUIRED�BY�SYSTEM�INITIALIZER*ŠPAGE ŠXDEFƒASN ŠXDEFƒCACHEFŠXDEFƒCLOCKFRQŠXDEFƒDISPATCHŠXDEFƒDUMMYPTR ŠXDEFƒEEND ŠXDEFƒENDMEMT ŠXDEFƒESTACK ŠXDEFƒESTART ŠXDEFƒGSTSIZ ŠXDEFƒIOVSIZ ŠXDEFƒMEMTABL ŠXDEFƒMEMTYPA ŠXDEFƒMEMTYPS ŠXDEFƒMEMTYPT ŠXDEFƒMEMTYPUŠXDEFƒPAGESIZE ŠXDEFƒPANELA ŠXDEFƒPATSIZ ŠXDEFƒRDYHEAD ŠXDEFƒSMEMHI ŠXDEFƒSMEMLO ŠXDEFƒTCBHEAD ŠXDEFƒTIMERAŠXDEFƒTIMINTVA ŠXDEFƒTIMSLIC ŠXDEFƒTRCFLAG ŠXDEFƒTRCSIZ ŠXDEFƒUDRSIZ ŠXDEFƒUSTSIZŠXDEFƒWHERLOADŠPAGETCBHEADƒDC.Lƒ\$TCBLST‹TCBHD RDYHEADƒDC.Lƒ\$TCBRDY‹READYHD FmOM#ESTART„DC.Lƒ\STARTRMSŠSTART�OF�EXEC EEND†DC.Lƒ\MEMBEGŒEND�OF�EXEC %ESTACK„DC.Lƒ\STACK�EXEC�STACK�ADDRESS &PANELA„DC.Lƒ\PANEL�FRONT�PANEL�ADDRESS SMEMLO„DC.Lƒ0’SECMEMLO SMEMHI„DC.Lƒ0’SECMEMHI "DISPATCH‚DC.Lƒ\STARTRMSŠDISPATCHER GSTSIZ„DC.Lƒ\GST�GST�#�OF�PAGES USTSIZ„DC.Lƒ\UST�UST�#�OF�PAGES UDRSIZ„DC.Lƒ\UDR�UDR�#�OF�PAGES PATSIZ„DC.Lƒ\PAT�PAT�#�OF�PAGES )TRCSIZ„DC.Lƒ\TRACE�TRACE�TABLE�#�OF�PAGES TRCFLAGƒDC.Wƒ\TRCFLAG #TIMERA„DC.Lƒ\TIMER�ADDRESS�OF�TIMER ;TIMINTVA‚DC.Wƒ\TIMINTV‹#�MILLISECS�BETWEEN�TIMER�INTERRUPTS ?TIMSLICƒDC.Wƒ\TIMSLIC‹#�TIMER�INTERRUPTS�BEFORE�TASK�RELINQUISH 1CLOCKFRQ‚EQU„\CLOCKFRQŠ#�CLOCK�TICKS�PER�MILLISEC $IOVSIZ„DC.Lƒ\IOV�SIZE�OF�IOVCT�TABLE 0MEMTYPAƒDC.BƒMTYP0ŽDEFAULT�MEMORY�TYPE�FOR�ASQ'S 0MEMTYPTƒDC.BƒMTYP0ŽDEFAULT�MEMORY�TYPE�FOR�TCB'S MMEMTYPS‚DC.B�MTYPE$SRO,MTYPE$SRW�DEFAULT�MEMORY�TYPE�FOR�SYSTEM�TASKS�(RO,RW) KMEMTYPU‚DC.B‚MTYPE$URO,MTYPE$URW�DEFAULT�MEMORY�TYPE�FOR�USER�TASKS�(RO,RW) ADUMMYPTR‚EQU„$A00‹USE�AS�DUMMY�POINTER�FOR�NON-EXISTANT�ADDRESSES /WHERLOAD‚DC.Lƒ\WHERLOADŠWHERE�MACSBUG�WILL�LOAD 7PAGESIZE‚DC.Lƒ\PAGESIZEŠPAGESIZE�FOR�SEGMENT�ALLOCATION ;ASN‡DC.Lƒ\ASN�NUMBER�OF�ADDRESS�SPACES�(CURRENTLY�0�OR�127) ACACHEF„DC.Lƒ\CACHEFŠAdress�to�use�for�selectively�flushing�bank1, *œbank2,�or�both�banks�of�cache.ŠPAGE*9*‚MEMORY�TABLE�-�USED�BY�INIT�TO�SET�UP�FREE�MEMORY�LISTS* ŠSECTION�8 ŠOPT„NOCL* TOP‡SET„0 BOTTOM„SET„1* MEMTABLƒEQU„* /ŠMTENTRY�RAM,$00000,\MEMEND1,MTYPE$P0,PART0,TOPŠIFNEƒ\MEMEND24�MTENTRY�RAM,\MEMEND2,\MEMEND3,MTYPE$P1,PART1,BOTTOMŠENDC ŠIFNEƒ\$ROPT �MTENTRY�ROM,\ROMSADDR,\ROMEADDRŠENDCŠMTENDŠDS.Lƒ10 ENDMEMTƒEQU„*ŠENDé**ˆ&.ROMIOI1.AG*=*ˆTHIS�ROUTINE�IS�REFERENCED�FROM�THE�SYSTEM�INITIALIZER�IOI.* *ˆROUTINE�TO*’PERFORM�SPECIFIED�FUNCTIONS7*’IF�A�ROM�BASED�SYSTEM�THE�DESIRED�ROM�ROUTINE�WILL�BE *—EXECUTED*’ELSE&*—AN�IMMEDIATE�RETURN�WILL�BE�EXECUTEDC **ˆINPUT *’A5�=�ZERO8*’A6�=�ADDRESS�OF�I/O�COMMON�DATA�SEGMENT�AT�SYSGEN�TIME**ˆOUTPUT$*’A5�=�NON-ZERO�-->�ROM�BASED�SYSTEM*›ZERO�-->�RAM�BASED�SYSTEM**ˆREGISTER�ALTERATION**’IF�ROM�BASED�SYSTEM*—A0�=�DESTROYED*—A1�=�DESTROYED*—A2�=�DESTROYED*—A5�=�DESTROYED*—D0�=�DESTROYED*—D1�=�DESTROYED*’ELSE*—NO�REGISTER�ALTERATION* ‰XDEF†ROMIOI1‰XDEF†ROMIOI02 ‰XREF†INITROMR ‰SECTIONƒ1 ROMIOI1: „IFNE‹\$ROPT‰XREF†ROMIOI90 ‰BRA‡ROMIOI90.*œROUTINE�TO�PERFORM�THOSE�FUNCTIONS�THAT�WILL-*œESTABLISH�THE�REQUIRED�RAM�WITH�THE�DESIRED*œINITIALIZATION„ENDC ROMIOI02: ‰BRA‡INITROMR‰ENDééééW4FMSG‰******************************************************************6MSG‰**„---‚Generic�SYSGEN�command�file‚---‹02/28/85‚**MSG‰**�&.VERSADOS.CD¢** MSG‰**¾**5MSG‰**‚Set�sysgen�parameters�from�passed�arguments‘**FMSG‰*******************************************************************E*ƒUse�in�conjunction�with�"STD.SYSGEN.CF"�or�"&.SYSGEN.CF"�or�execute(*ƒdirectly�with�the�following�arguments:*=*†ARG1�-�listing�file�or�device�for�assemblies�and�link�edits*(*†ARG2�-�switch:ƒ0�=�ARG1�is�a�file�name*—1�=�ARG1�is�a�device�name* *†ARG3�-�Reserved�for�future�use*?*†ARG4�-�working�file�for�use�with�"COPY�;A"�to�produce�listing*G*ƒNOTE:‚Arguments�are�not�in�the�same�order�as�for�the�SYSGEN.CF�files!N******************************************************************************"**”------‚C�A�U�T�I�O�N‚-------˜**G**…SYSGEN�now�assumes�the�catalog�was�set�to�the�proper�system�type,„**(**…i.e.�EXORMACS,�VMES10,�VM02,�etc.!£**N******************************************************************************  (ASMLSW„=�\2‹Assembly�listing�file�switch*›0�=�ASMLS�is�a�file*›1�=�ASMLS�is�a�device%LINKLSWƒ=�\2‹Link�listing�file�switch*›0�=�LINKLS�is�a�file*›1�=�LINKLS�is�a�device IFEQˆ\ASMLSW#ƒASMLS…=�"\4"‰ASM�listing�work�fileENDC IFNEˆ\ASMLSW ƒASMLS…=�"\1"‰ASM�listing�deviceENDC IFEQˆ\LINKLSW%ƒLINKLS„=�"\4"‰LINK�listing�work�fileENDC IFNEˆ\LINKLSW"ƒLINKLS„=�"\1"‰LINK�listing�deviceENDC )WORKLS„=�"\1"‰Overall�listing�file/device FMSG‰******************************************************************EMSG‰**‚Initialize�.VERSAPT.CF�and�.OSLIST.AG�files�**AMSG‰**‚so�we�can�dynamically�build�them�with�COPY�;A�commands.…**FMSG‰******************************************************************#=COPY‡VERSAPT.BEGIN.CF,VERSAPT.CF;Y!=COPY‡OSLIST.BEGIN.AG,OSLIST.AG;Y  2&TOTDSKƒ=�0ŒTotal�number�of�disks�(floppy�&�hard):5*˜This�redefinable�parameter�is�built�as�disk�driversC `<i.q0y;�2‰-‘4™,¡1©0± ,*˜are�included.‚Each�volume�defined�requires%*˜approximately�2.25�bytes�of�memory.6&TOTTERM‚=�0ŒTotal�number�of�terminals�(local�&�MCCM):6*˜This�redefinable�parameter�is�built�as�terminals�are *˜included.4&TOTPRTƒ=�0ŒTotal�number�of�printers�(local�&�MCCM):6*˜This�redefinable�parameter�is�built�as�terminals�are *˜included.@&PIAFLAG‚=�0ŒFlag�to�include�PIADRV.‚If�non-zero�then�PIADRV�has*˜already�been�included.>&SERFLAG‚=�0ŒFlag�to�define�the�number�of�serial�port�drivers.@&SPRFLAG‚=�0ŒFlag�to�include�SPR�driver.‚If�non-zero�MPSCSPR�has*˜already�been�included.@&SUPFLAG‚=�0ŒFlag�to�include�SUP�driver.‚If�non-zero�MPSCSUP�has*˜already�been�included.A&MPSCFLG‚=�0ŒFlag�to�include�MPSC�driver.‚If�non-zero�MPSCDRV�has*˜already�been�included.B&M420FLG‚=�0ŒFlag�to�include�M420DRV.‚If�non-zero�then�M420DRV�has*˜already�been�included.'&PCDRV„=�0ŒProcess�Control�Driver�Flag:8*˜This�redefinable�parameter�is�built�as�Process�Control+*˜Drivers�(VME6xx,�RAD,�RIO)�are�processed.<&CRTDV„=�$434E3030„Starting�CRT�Terminal�Device�Code=�'CN00"*˜(CN01,CN02,CN03,�etc.)6&PRTDV„=�$50522020„Starting�Printer�Device�Code=�'PR‚'*˜(PR1,PR2,PR3,�etc.)2*˜(Must�be�unique�in�1st�three�characters�and�same *˜format.)I&DSKDV„=�$00002F00„Starting�Disk�Device�Number=�'__/_'�(1�less�than�__0_)0*˜(gets�built�into�HD00,HD01,...,�FD14,FD15,...)*D*ƒThe�following�parameters�are�used�in�the�disk�controller�IOC�files)*ƒto�determine�the�starting�drive�number.+ZERO†=�"0"ŠStarting�disk�number�for�drive�0*TWO‡=�"2"ŠStarting�disk�number�for�drive�2+FOUR†=�"4"ŠStarting�disk�number�for�drive�4*SIX‡=�"6"ŠStarting�disk�number�for�drive�6 3MSG‰***********************************************+MSG‰**ƒSYSGEN�parameters�for�table�sizes‡**3MSG‰*********************************************** 3DCQPGE„=�2ŒNumber�of�pages�of�memory�for�the�device,*˜connection�queue�(DCQ).‚Minimum�of�1�page,)*˜maximum�of�10�pages.‚The�DCQ�is�used�to.*˜save�concurrent�requests�to�the�same�file�or-*˜device.‚Each�page�of�the�DCQ�can�accomodate*˜approximately�9�entries.*4UST‡=�2ŒNumber�of�pages�in�the�user�semaphore�table.,*˜Minimum�of�1,�maximum�of�10.‚Each�page�can&*˜accomodate�approximately�11�entries.*5TRACE…=�0Œ*No.�of�pages�in�trace�table.‚TRACE�must�be**˜nonzero�if�TRCFLAG�is�nonzero.‚Each�page**˜can�accomodate�approximately�10�entries.*1UDR‡=�1ŒNumber�of�pages�in�user-defined�directive**˜table,�minimum�of�0,�maximum�of�10.‚Each/*˜page�can�accomodate�approximately�25�entries.*5IOV‡=�1Œ#�of�pages�in�I/O�vector�table,�minimum�of�1.4*˜Each�page�can�accomodate�approximately�12�entries.2*˜For�each�vector�claimed�by�a�task�using�the�CISR3*˜directive�(Configure�Interrupt�Service�Routine)�a4*˜separate�entry�is�made�into�this�table.‚The�system1*˜imposes�no�maximum�size�for�this�parameter.‚For5*˜efficient�use�of�system�space,�however,�the�formula)*˜for�computing�the�table�size�should�be:7*˜1+(C/12)�where�'C'�is�the�number�of�different�vectors4*˜that�the�user�expects�to�claim�via�CISR�directive.*!PAT‡=�1+(3+\TOTTERM)/7�#�of�pages-*˜in�periodic�activation�table.‚Each�page�can%*˜accomodate�approximately�8�entries.*šPAT�size�is�\PAT�.*GNOTASKSƒ=�6+(3*\TOTTERM)�Maximum�number�of�tasks�in�system�at�one�time,0*˜minimum�of�1.‚VERSAdos�contains�a�maximum�of�63*˜resident�tasks.‚Allowing�for�that,�plus�three�for.*˜each�terminal�will�accomodate�most�requests.*šNOTASKS=�\NOTASKS*CLUMAX…=�\TOTDSK+3„Logical�unit�number�maximum.‚LUMAX�is�a�temporary5*˜symbol�used�to�set�the�value�of�MAXLU,�which�is�the2*˜maximum�logical�unit�number�that�can�be�assigned0*˜for�each�task�in�the�system.‚Restrictions�are:(*œ8�<=�LUMAX�<=�31‡(range�checked�below)*œLUMAX�>=�TOTDSK3*˜NOTE:‚If�you�have�any�VME300�(GPIB)�D boards�in�the)*Ÿsystem�you�will�want�to�add�14�to�LUMAX/*Ÿfor�each�VME300�board�you�have�in�the�system.7*˜The�maximum�logical�unit�number�allowed�in�a�VERSAdos3*˜system�is�254.‚Note�that�the�PASCAL�compiler�will6*˜only�generate�code�that�uses�logical�unit�numbers�as6*˜high�as�31.‚(You�may�have�more�logical�units�defined7*˜for�your�system�however�even�if�you�are�using�PASCAL.*1*˜MAXLU�is�kept�to�the�minimum�value�to�allow�our/*˜standard�sysgens�to�work�in�384K.‚If�you�want2*˜more,�change�the�"+3"�to�add�whatever�additional4*˜amount�you�need,�or�assign�it�to�a�specific�value.#*˜(The�"+3"�was�arbitarily�chosen).1*˜MAXLU�and�NOTASK�determine�the�amount�of�memory,*˜required�for�the�logical�unit�table�(LUT)./*˜The�algorithm�for�determining�the�LUT�size�is *˜as�follows:&*œLUT�=�16*NOTASKS+8*NOTASKS*(MAXLU+1)+*˜There�must�be�one�LU�for�each�disk�volume+*˜(FMS�assigns�a�different�logical�unit�for+*˜each�disk.)‚This�means�that�MAXLU�must�be"*˜greater�than�or�equal�to�TOTDSK.IFGTˆ\LUMAX-254ƒMSG‰5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰LUMAX�must�be�<=�254.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFLTˆ\LUMAX-8ƒMSG‰5ƒMSG‰--------‚SYSGEN�parameter�size�warning‚---------ƒMSG‰LUMAX�must�be�>=�8.'ƒMSG‰Forcing�MAXLU=�8�and�continuing... ƒMAXLU…=�8ENDC IFGEˆ\LUMAX-8ƒMAXLU…=�\LUMAXENDC**BNOFILESƒ=�2*\NOTASKSƒMaximum�number�of�files�that�can�be�opened�in'*˜the�system�at�one�time.‚Limit�of�200.*@NODIFFIL‚=�2*\NOTASKSƒMaximum�number�DIFFERENT�files�that�can�be,*˜opened�at�one�time.‚Cannot�be�greater�than+*˜NOFILES.‚For�every�three�different�files,+*˜approximately�1K�of�memory�is�required.‚A$*˜ratio�of�5�files�for�each�terminal*˜accomodates�most�requests.*>GST‡=�(\NOFILES/14)+1�Number�of�pages�in�global�segment�table.(*˜Minumum�of�1,�maximum�of�10.‚Each�page**˜can�accomodate�approximately�14�entries.*F&DEFVOLƒ=�2*\TOTTERMƒCompute�#�default�volumes�for�the�system,�minimum*˜is�4.ƒ(See�NODEFVOL�below.)IFGTˆ\&DEFVOL-(\NOTASKS+3)5ƒMSG‰--------‚SYSGEN�parameter�size�warning‚---------!ƒMSG‰&DEFVOL�must�be�<=�NOTASKS+31ƒMSG‰Forcing�&DEFVOL=�NOTASKS+3�and�continuing...ƒ&DEFVOLƒ=�\NOTASKS+3ENDCIFLTˆ\&DEFVOL-45ƒMSG‰--------‚SYSGEN�parameter�size�warning‚---------ƒMSG‰&DEFVOL�must�be�>=�4.)ƒMSG‰Forcing�&DEFVOL=�4�and�continuing... ƒ&DEFVOLƒ=�4ENDC*ANODEFVOL‚=�\&DEFVOL…Maximum�number�of�default�volumes�that�can�be,*˜defined.‚Cannot�be�greater�than�NOTASKS+3.*8DEFFAB„=�1ŒDefault�File�Allocation�Block�(FAB)�length�in.*˜sectors�(256�bytes�per�sector).‚Used�by�file,*˜handler�when�no�FAB�size�is�given.‚Minimum *˜size�is�1,�maximum�size�is�20.*:DEFDAT„=�4ŒDefault�data�block�length�in�sectors�(256�bytes0*˜per�sector).‚Used�by�file�handler�when�no�data.*˜block�size�is�given�at�file�allocation�time.)*˜Minumum�size�is�4,�maximum�size�is�255. 3MSG‰***********************************************(MSG‰**ƒSYSGEN�parameters�for�terminalŠ**-MSG‰**ƒConfiguration�parameters/attributes…**-MSG‰**ƒ(TCP�=�Terminal�Config.�Parameters)…**3MSG‰***********************************************MSG‰FMSG‰******************************************************************EMSG‰**�NOTE:‚To�modify�a�single�port(s),�use�the�"CONFIG"�utility.�**FMSG‰*******************************************************************1TCP$RECƒ=�80‹Width�of�terminal�(characters/line).,TCP$RSZƒ=�24‹Depth�of�terminal�(lines/page).BTCP$WTOƒ=�900000‡(15�minutes)�#�of�millisec�to�allow�before�timing*˜out�a�write.BTCP$RTOƒ=�900000‡(15�minutes)�#�of�millisec�to�allow�before�timing *˜out�a�read.=TCP$XOFƒ=�$13ŠXOFF�char;�when�received,�suspends�transmission *˜(0=none).>TCP$XONƒ=�0ŒXON�char;�when�received,�cancels�a�prior�XOFF�char*˜(0=any�char).?TCP$BRCƒ=�$03ŠChar�to�be�interpreted�like�a�break�when�received *˜(0=none).;TCP$DOPƒ=�$0FŠChar�which�causes�output�to�be�discarded�when*˜received�(0=none).9TCP$RLNƒ=�$1AŠChar�which�causes�line�to�be�rD eprinted�when*˜received�(0=none).@TCP$CLCƒ=�$18ŠChar�which�causes�line�to�be�deleted�when�received *˜(0=none)..TCP$RTVƒ=�$0DDE0000„Read�terminators�(CR,$DE)./TCP$EOLƒ=�$0D0A0000„End�of�line�string�(CR,LF).;TCP$BRTƒ=�$0EŠBaud�rate�code�($0E=9600�baud).‚The�following1*˜codes�may�be�used�to�set�the�desired�baud�rate.)*›Code‚RateƒCode�RateƒCode�RateƒCode�Rate"*›$00ƒ50…$05‚300„$09‚2000ƒ$0E‚9600#*›$01ƒ75…$06‚600„$0A‚2400ƒ$0F‚19200#*›$02ƒ110„$07‚1200ƒ$0C‚4800ƒ$10-$FF&*›$03ƒ134.5‚$08‚1800ƒ$0D‚7200ƒReserved>TCP$NLSƒ=�0Œ#�of�ASCII�NUL�char's�to�send�after�each�CR�or�LF.*TCP$TRCƒ=�$00ŠTerminator�class�($0X=none).-TCP$TTPƒ=�$00ŠTerminal�type�(0=EXORterm�155).I*‚Each�of�the�following�is�a�flag--the�only�allowable�values�are�0�and�1.=TCP$HCPY‚=�0Œ1�means�the�terminal�is�a�hardcopy�device,�not�a*˜CRT.7TCP$XCTL‚=�0Œ1�means�use�XON/XOFF�to�control�terminal's*˜transmission,�not�CTS.?TCP$BITS‚=�0Œ1�means�transmit�&�receive�7�bits/char�rather�than*˜8.;TCP$STPB‚=�0Œ1�means�follow�each�char�sent�with�2�stop�bits*˜rather�than�1..RMS.LO *AMSG‰*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*INCLUDE…RMS.CIPROCESS…RMS.LOEND‰EXEC IFEQˆ\LINKLSWƒ=COPY‡RMS.LL,\WORKLS;AENDC IFNEˆ\SERFLAGAƒMSG‰************************************************************ƒMSG‰**‰Driver�library¡**AƒMSG‰************************************************************ƒINCLUDE…&.DRVLIB.CIAƒMSG‰************************************************************#ƒMSG‰**‰Generic�terminal�library—**E AƒMSG‰************************************************************ƒINCLUDE…&.TERMLIB.CIENDC @MSG‰************************************************************?MSG‰**‚Make�IOC�generator�link�chain�file�(&.XIOCGEN.LG)�for�**?MSG‰**‚this�sysgen�(1�time�here�instead�of�for�each�driver).�**@MSG‰************************************************************SUBSˆ&.IOCGEN.LG*M*----------------------------------------------------------------------------G*�NOTE:‚The�restart�option�on�sysgen�should�not�be�set�from�here�to�the?*ˆdefinition�of�MEMBEG.‚This�is�because�the�IOC�file�gets�built;*ˆdynamically�and�cannot�be�split�up�by�the�restart�option.MSG‰@MSG‰************************************************************0MSG‰**‚Produce�starting�.IOC.RO�file.�**:MSG‰**„Relocatable�modules�added�as�drivers�are�needed.„**;MSG‰**„ASM�&�LINK�listings�built�as�we�go�before�puttingƒ**#MSG‰**„in�output�file�(\WORKLS).›**@MSG‰************************************************************SUBSˆIOC.BEGIN.AG)ASM‰IOC.BEGIN.AG,IOC.RO,IOC.LIST.TF;RZ=70(*‚Above�creates�1st�part�of�ASM�listing!*M*---------------------------------------------------------------------------- @MSG‰************************************************************+MSG‰**‹INCLUDE�BOARD/SYSTEM�DEPENDENCIESŒ**1MSG‰**‚This�file�contains�all�the�board/system�**5MSG‰**‚dependencies�for�the�system�being�sysgened.‹** MSG‰**¸**.SYSTEM.CIƒProcessor�board/system‹**&MSG‰**—dependencies�including�local…**!MSG‰**—terminals�and�printers.Š**@MSG‰************************************************************INCLUDE…SYSTEM.CI @MSG‰************************************************************=MSG‰**‚Validate�parameters�about�table�sizes,�etc.�definedƒ**%MSG‰**‚in�.SYSTEM.CI�file.›**@MSG‰************************************************************INCLUDE…&.VALPAR.CI FMSG‰******************************************************************DMSG‰**ƒINCLUDE�DRIVER�CONFIGURATION�file�-�".CNFGDRVR.CI"�**@MSG‰**�This�system�dependent�file�contains�the�flags�that�are‡**BMSG‰**�setup�as�to�which�drivers�(and�devices)�will�be�included…***MSG‰**�via�the�driver�conditional�file.�** MSG‰**¾**EMSG‰**�The�user�can�edit�this�file�to�control�which�device�drivers‚**,MSG‰**�will�be�be�included�in�the�sysgen.›** MSG‰**¾**FMSG‰**�All�items�pertaining�to�individual�drivers�are�in�individual�**EMSG‰**�driver�files�of�type�&.nnnnDRV.CI�where�"nnnn"�is�the�board‚**DMSG‰**�number�or�driver�type,�i.e.�"M605"�or�"IPC".‚This�file�can‚**DMSG‰**�be�edited�by�the�user�to�custom�configure�for�non-standardƒ**MSG‰**�hardware.´**FMSG‰******************************************************************INCLUDE…CNFGDRVR.CI FMSG‰******************************************************************@MSG‰**…INCLUDE�DRIVER�CONDITIONAL�file�-�".IFDRVR.CI"ƒ**EMSG‰**‚This�file�operates�on�the�flags�setup�in�the�driver�config-�**?MSG‰**‚uration�file�to�conditionally�include�specific�device‡**MSG‰**‚drivers.´**7MSG‰**‚The�user�should�never�have�to�edit�this�file.�**FMSG‰******************************************************************INCLUDE…IFDRVR.CI M*----------------------------------------------------------------------------FMSG‰******************************************************************EMSG‰**‚Produce�ending�IOC.RO�file�and�merge�into�final�IOC.RO�file�**-MSG‰**…-�NULL�driver�must�be�the�last�one!–**FMSG‰******************************************************************MSG‰SUBSˆIOC.END.AG"ASM‰IOC.END.AG,NEW.RO,\ASMLS;RZ=70 IFEQˆ\ASMLSWƒ=COPY‡\ASMLS,IOC.LIST.TF;AENDC2*‚Generate�merged�IOC.RO�by�appending�new�.RO�fileINCLUDE…&.IOCGEN.CI IFEQˆ\LINKLSWƒ=COPY‡\LINKLS,IOC.LIST.TF;AENDCIFEQˆ\ASMLSW+\LINKLSWƒ=COPY‡IOC.LE IST.TF,\WORKLS;AENDC=DELˆTEMP.RO/IOC.LIST.TF=DELˆ*.NEW.RO;Y*O*------------------------------------------------------------------------------$MEMBEG„=�*ŒStart�of�available�memory @MSG‰************************************************************;MSG‰**„INCLUDE�TASK�CONFIGURATION�file�-�"&.CNFGTASK.CI"ƒ**.VERSAPT.CF�and�makeŠ**.MSG‰**‚substitutions�with�sysgen�parameters˜**FMSG‰******************************************************************!=COPY‡VERSAPT.END.CF,VERSAPT.CF;ASUBSˆVERSAPT.CF CMSG‰***************************************************************+MSG‰**‰E�N�DƒO�Fƒ"&.VERSADOS.CD"‚F�I�L�EŒ**CMSG‰**-----------------------------------------------------------**AMSG‰**‚Now�going�to�process�&�build�.VERSADOS.SY�file.‚**MSG‰**“Have�a�nice�day!˜**CMSG‰****************************************************************D*‚Define�absolute�parameters�from�the�redefineable�ones�we've�built.IOCBASEƒ=�\&IOCBASETOTDSK„=�\&TOTDSKTOTTERMƒ=�\&TOTTERMPCDRV…=�\&PCDRVSERFLAGƒ=�\&SERFLAG END‰SYSGENéééééF é**ˆ&.INITGEN.CI*(* Build SYSINIT.RO in relocatable piecesLINKˆ&.SYSINGEN.LG=COPY‡TEMP.RO,SYSINIT.RO;Yééééééé¹* *ˆ&.ROGEN.CI*&* Build .RO file in relocatable piecesLINKˆ&.ROGEN.LG=COPY‡TEMP.RO,ROGEN.RO;Y IFEQˆ\LINKLSWƒ=COPY‡\LINKLS,\WORKLS;AENDCéééééF éé * *ˆ&.IOI.CI*?MSG‰***********************************************************MSG‰**ˆIOCOM�&�IOI¤**?MSG‰*********************************************************** 5* Build VERSAdos patch chain file .VERSAPT.CF!=COPY‡VERSAPT.IOI.CF,VERSAPT.CF;A TASKˆ&.IOI.LO,.IOISTATE…=�'READ'ATTRIB„=�'CRIT'ATTRIB„=�'SYST' SESSIONƒ=�1PRIORITY‚=�$DA IOCSTR„=�* =COPY‡OSLIST.END.AG,OSLIST.AG;ASUBSˆOSLIST.AG#ASM‰OSLIST.AG,OSLIST.RO,\ASMLS;Z=80 IFEQˆ\ASMLSWƒ=COPY‡\ASMLS,\WORKLS;AENDC SUBSˆFMS.IOI.AG&ASM‰FMS.IOI.AG,FMS.IOI.RO,\ASMLS;RZ=83 IFEQˆ\ASMLSWƒ=COPY‡\ASMLS,\WORKLS;AENDC SUBSˆEET.START.AG&ASM‰EET.START.AG,EET.START.RO,\ASMLS;R IFEQˆ\ASMLSWƒ=COPY‡\ASMLS,\WORKLS;AENDC SUBSˆ&.ROMIOI1.AG'ASM‰&.ROMIOI1.AG,.&.ROMIOI1.RO,\ASMLS;R IFEQˆ\ASMLSWƒ=COPY‡\ASMLS,\WORKLS;AENDC �IFNE…\$ROPT…IOCM�=�"IOSF"…SUBSˆ&.IOI.LG ENDC �IFEQ…\$ROPT…IOCM�=�"IOSG"…SUBSˆ&.IOI.LG ENDC LINKˆ&.IOI.LG IFEQˆ\LINKLSWƒ=COPY‡\LINKLS,\WORKLS;AENDCEND‰IOIéééË:* *ˆ&.VALPAR.CI*-* Validate parameters about table sizes, etc.*IFLTˆ\DCQPGE-1ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰DCQPGE�must�be�>=�1.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDCIFGTˆ\DCQPGE-10ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰DCQPGE�must�be�<=�10.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFLTˆ\GST-1ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰GST�must�be�>=�1.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFGTˆ\GST-20ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰GST�must�be�<=�20.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFLTˆ\UST-1ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰UST�must�be�>=�1.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFGTˆ\UST-10ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚G -----------ƒMSG‰UST�must�be�<=�10.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFNEˆ\TRCFLAG ƒIFEQˆ\TRACE†MSG5†MSG‰--------‚SYSGEN�parameter�size�error‚-----------.†MSG‰TRACE�must�be�>�when�TRCFLAG�is�non-zero.5†MSG‰Please�adjust�parameters�and�start�sysgen�again.†ABORTƒENDCENDC IFLTˆ\UDR-0ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰UDR�must�be�>=�0.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFGTˆ\UDR-10ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰UDR�must�be�<=�10.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFLEˆ\IOVƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰IOV�must�be�>�0.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFLEˆ\NOTASKSƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰NOTASKS�must�be�>�0.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ÔXÝFƒABORT‡ENDC IFLTˆ\NOFILES-1ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰NOFILES�must�be�>=�1.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDCIFGTˆ\NOFILES-200ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰NOFILES�must�be�<=�200.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFLEˆ\NODIFFILƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰NODIFFIL�must�be�>�0.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDCIFGTˆ\NODIFFIL-\NOFILESƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------!ƒMSG‰NODIFFIL�must�be�<=�NOFILES.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFGTˆ\NODEFVOL-(\NOTASKS+3)ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------#ƒMSG‰NODEFVOL�must�be�<=�NOTASKS+3.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFLTˆ\DEFFAB-1ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰DEFFAB�must�be�>=�1.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDCIFGTˆ\DEFFAB-20ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰DEFFAB�must�be�<=�20.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDC IFLTˆ\DEFDAT-4ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰DEFDAT�must�be�>=�4.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDCIFGTˆ\DEFDAT-255ƒMSG5ƒMSG‰--------‚SYSGEN�parameter�size�error‚-----------ƒMSG‰DEFDAT�must�be�<=�255.5ƒMSG‰Please�adjust�parameters�and�start�sysgen�again.ƒABORT‡ENDCé* *ˆ&.IFTASK.CI*FMSG‰******************************************************************$MSG‰**‚Process�O/S�tasks�as�requiredFMSG‰******************************************************************IFNEˆ\FHS$IOS$+\FMS$ƒSUBSˆGET.TASKID.AG)ƒASM‰GET.TASKID.AG,GET.TASKID.RO,\ASMLS;R ƒIFEQˆ\ASMLSW†=COPY‡\ASMLS,\WORKLS;AƒENDCENDCIFNEˆ\FHS$IOS$ƒINCLUDE…FHSIOS.VERSADOS.CIENDC IFNEˆ\FMS$ƒINCLUDE…FMS.VERSADOS.CIENDC IFNEˆ\EET$ƒINCLUDE…EET.VERSADOS.CIENDC IFNEˆ\LDR$ ƒIFNEˆ\MMU†INCLUDE…MMULDR.VERSADOS.CIƒENDC ƒIFEQˆ\MMU†INCLUDE…NOMMULDR.VERSADOS.CIƒENDCENDCG éééééå* *ˆ&.IOCGEN.CI*$* Build IOC.RO in relocatable piecesLINKˆ&.IOCGEN.LG=COPY‡TEMP.RO,IOC.RO;Yéééééééî**ˆ&.SYSINIT.CI*=*‹***********************************************************5*‹**‚SYSINIT�--�System�Initializer�for�all�systemsˆ**=*‹*********************************************************** 5* Build VERSAdos patch chain file H .VERSAPT.CF%=COPY‡VERSAPT.SYSINIT.CF,VERSAPT.CF;A PROCESS…SYSINIT.LO INTSTR„=�* '* SUBS the link files before using them*SUBSˆ&.ROGEN.LGSUBSˆ&.ROGEN.CI )*‚Assemble�board�dependent�initialization=*….ROGEN.RO�will�be�link/merged�to�produce�SYSINIT.LO*SUBSˆINITIO1.AG'ASM‰INITIO1.AG,INITIO1.RO,\ASMLS;RMZ=70 IFEQˆ\ASMLSWƒ=COPY‡\ASMLS,\WORKLS;AENDC H*‚Produce�starting�.ROGEN.RO�module.‚All�.NEW.RO�modulesI*‚will�be�link/merged�into�the�ROGEN�module�when�then�becomes�SYSINIT.LO.*SUBSˆ&.INITIO1.LGLINKˆ&.INITIO1.LG IFEQˆ\LINKLSWƒ=COPY‡\LINKLS,\WORKLS;AENDC FMSG‰******************************************************************5MSG‰**‚Check�for�VME316�I/O�Channel:‡Add�initializer?FMSG‰****************************************************************** IFNEˆ\NVME316ƒ=COPY‡&.INIT316.RO,NEW.RO;YƒINCLUDE…&.ROGEN.CIENDC FMSG‰******************************************************************:MSG‰**‚Check�for�Process�Control�Drivers:‚Add�initializer?FMSG‰****************************************************************** IFNEˆ\PCDRVƒIFEQˆ\IOCBASE6†MSG‰****�FAIL:‚SYSTEM�REQUIRES�I/O�CHANNEL�TO�RUN�I/O(†MSG•CHANNEL�BOARDS!!‚FIND�"&IOCBASE"�IN%†MSG•.SYSTEM.CI�FOR�MORE�INFO†ABORT‡ƒENDCEƒ*„Change�below�to�test�individual�VME6xx�bds.�&�merge�in�their�.RO's0ƒ*„to�&.ROGEN.RO�to�build�SYSINIT.RO�as�we�go!!!ƒINCLUDE…&.PCDRV.CIENDC MSG‰FMSG‰******************************************************************=MSG‰**‚Add�ending�INIT�code�RTS�and�data:‚This�must�be�last!!FMSG‰******************************************************************SUBSˆ&.INITDAT.AG&ASM‰&.INITDAT.AG,&.INITDAT.RO,\ASMLS;R IFEQˆ\ASMLSWƒ=COPY‡\ASMLS,\WORKLS;AENDC÷D SUBSˆSYSINIT.LGLINKˆSYSINIT.LG IFEQˆ\LINKLSWƒ=COPY‡\LINKLS,\WORKLS;AENDC END‰SYSINIT * Delete files no longer needed =DELˆROGEN.RO =DELˆTEMP.RO =DELˆNEW.RO éééééééH **ˆ&.CNFGTASK.CI*7MSG‰***************************************************(MSG‰**‚OPERATING�SYSTEM�TASK�SWITCHES�**7MSG‰****************************************************AFHS$IOS$‚=�1ŒSet�=0�for�skip�FHS/IOS�module,�not�=0�to�include�it9FMS$†=�1ŒSet�=0�for�skipƒFMSƒmodule,�not�=0�to�include�it9EET$†=�1ŒSet�=0�for�skipƒEETƒmodule,�not�=0�to�include�it9LDR$†=�1ŒSet�=0�for�skipƒLDRƒmodule,�not�=0�to�include�itéééééé  **ˆ&.M316DEF.CI*GMSG‰*******************************************************************7MSG‰**…MVME316�DRIVER�-�VMEbus�to�I/O�Channel�InterfaceGMSG‰******************************************************************* H*�NOTE:‚We�do�not�directly�support�usage�of�the�VME316�board�as�a�second=*ˆI/O�channel�when�the�CPU�card�already�has�one.‚You�will�get?*ˆduplicate�parameter�errors�on�"CMULT",�"IOCBASE",�and�all�the:*ˆ"Lxxx$nn"'s�in�the�"IOC.ADDRESS.CI"�file�if�you�do�this.<*ˆ(The�other�reference�is�in�the�".SYSTEM.CI"�file).**ˆTo�add�a�second�I/O�channel::*Œ1.�Remove�"CMULT"�and�"IOC.ADDRESS.CI"�lines�from�below.A*Œ2.�Change�"IOCBASE"�to�"IOC316"�and�set�to�the�address�desired.@*Œ3.�Change�the�"IOC.ADDRESS.CI"�file�to�use�"IOC316"�instead�of*�"IOCBASE"�where�desired. 6CMULT…=�2ŒI/O�channel�multiplier�(see�IOC.ADDRESS.CI):,*œ=�1�for�IOC�run�directly�on�the�MC68020�or,* MC68008�address�bus�of�a�user's�custom�CPU$* board�(because�of�byte�addressing).*œ=�2�for�all�others�where�byte�address�is�not,* available�(only�odd�addresses�are�used)�or(* if�running�the�IOC�from�a�VME316�board*9&IOCBASE‚=�$FFE000†Base�address�of�I/O�channel�for�VME3168INCLUDE…IOC.ADDRESS.CI�get�I/O�channel�addresses�offsetsééI é =/* =/*†&.EET.LG=/*2=/* Link chain file run at sysgen time to link EET=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*G=/* Sysgen parameter EETSTR = \EETSTR = address at which to link driver=/*=LINK ,&.EET.LO,\LINKLS;HAMIXSSEGMENT .EET:0 \EETSTRSEGMENT .STT(G):1SEGMENT &EET(RG):8,14INPUT &.DAT.ROINPUT &.CMDLIST.ROINPUT &.EET.ROINPUT &.SCTSASR.ROINPUT &.USM.ROINPUT &.SYSCNTRL.ROLIB &.USMOPT.ROLIB &.UTILIB.ROEND=/*=ENDééééé =/* =/*†&.FHS.LG=/*2=/* Link chain file run at sysgen time to link FHS=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*G=/* Sysgen parameter FHSSTR = \FHSSTR = address at which to link driver=/*=LINK ,&.FHS.LO,\LINKLS;HAMIXSSEGMENT .FHS:0 \FHSSTRINPUT DEVICE.FHS.ROINPUT FILE.FHS.ROINPUT GET.TASKID.ROINPUT FHS.IXR.ROEND=/*=ENDéééI ééé #=/* =/*†&.FMS.LG=/*2=/* Link chain file run at sysgen time to link FMS=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*G=/* Sysgen parameter FMSSTR = \FMSSTR = address at which to link driver=/*=LINK ,&.FMS.LO,\LINKLS;HAMIXSEGMENT .FMS:0 \FMSSTRINPUT &.FFHS.ROINPUT &.FIOS.ROINPUT &.FUTY.ROINPUT &.FIOM.ROINPUT &.FDTA.ROINPUT FMS.IXR.ROINPUT GET.TASKID.ROEND=/*=ENDéééééé ,=/*=/*†&.IOCGEN.LG=/*K=/* Link chain file run at sysgen time to link IOC.RO in relocatable pieces=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*=LINK ,TEMP.RO,\LINKLS;RI INPUT IOC.RO INPUT NEW.ROEND=/*=ENDéJ ééééé 5' IOI LG J JqqIOS LG S SqqROGEN LG \ \ qqINITIO1 LG e e qqSYSINIT LG n nqqMTYPE SI w w qqF5DDDSI SI € €qqF8DDDSI SI ‰ ‰qqF8SDDSM SI ’ ’qqF8SDSSI SI › ›qqF8SDSSM SI ¤ ¤qqFXCMD16 SI ­ ­qqFXCMD80 SI ¶ ¶qqFXLRK08 SI ¿ ¿qqFXLRK25 SI È ÈqqH5WIN05 SI Ñ ÑqqH5WIN10 SI Ú ÚqqH5WIN15 SI ã ãqqH5WIN40 SI ì ìqqH8WIN10 SI õ õqq=/* =/*†&.IOI.LG=/*2=/* Link chain file run at sysgen time to link IOI=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*G=/* Sysgen parameter IOCSTR = \IOCSTR = address at which to link driver=/*=LINK ,&.IOI.LO,\LINKLS;HAMIXSSEGMENT \IOCM:0 \IOCSTRSEGMENT .IOI:1 INPUT IOC.ROINPUT &.IOI.ROINPUT OSLIST.ROINPUT FMS.IOI.ROINPUT &.ROMIOI1.ROINPUT EET.START.ROLIB &.ROMIOI90.ROEND=/*=ENDééééJ éé B=/* =/*†&.IOS.LG=/*2=/* Link chain file run at sysgen time to link IOS=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*G=/* Sysgen parameter IOSSTR = \IOSSTR = address at which to link driver=/*=LINK ,&.IOS.LO,\LINKLS;HAMIXSSEGMENT .IOS:0 \IOSSTRINPUT DEVICE.IOS.ROINPUT FILE.IOS.ROINPUT GET.TASKID.ROEND=/*=ENDéééééé K=/*=/*†&.ROGEN.LG=/*J=/* Link chain file run at sysgen time to link new .RO modules to ROGEN.RO=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*=LINK ,TEMP.RO,\LINKLS;RIINPUT ROGEN.RO INPUT NEW.ROEND=/*=ENDééK éééé T=/*=/*†&.INITIO1.LG=/*E=/*�Important�note:‚The�order�of�the�INPUT�modules�for�this�LINK�must=/*’be�as�specified�below.=/*=LINK ,ROGEN.RO,\LINKLS;IXHMRINPUT M68XXX.INIT.ROINPUT INITIO1.ROEND=/*=ENDééééééé ] =/*=/*†&.SYSINIT.LG=/*L=/* Link chain file run at sysgen time to link SYSINIT.LO with no PREINIT.RO=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*?=/* Sysgen parameter PC = \PC = address at which to link driver=/* =LINK ,SYSINIT.LO,\LINKLS;HAMIXSSEG .INT:8 \PCINPUT ROGEN.ROINPUT &.INITDAT.ROINPUT &.SYSPAR.ROEND=/*=ENDK éééééé f;* &.MTYPE.SI - Memory type assignments for standard systems**‚System�memoryMTYPE$SRO‚EQU�MTYP0�read�onlyMTYPE$SRW‚EQU�MTYP0�read/write* *‚User�memoryMTYPE$URO‚EQU�MTYP0�read�onlyMTYPE$URW‚EQU�MTYP0�read/write**‚Partition�typesMTYPE$P0ƒEQU�MTYP0�partition�#0MTYPE$P1ƒEQU�MTYP0�partition�#1éééééé o L O******************************************************************************* *ƒF5DDDSI.SI*J*ƒDCB�values�for�5�1/4"�Floppy�disk,�double�density,�double�sided,�IBM�fmtO********************************************************************************ATT_WORD‹SET‡$004FSECT_PER_TRACK…SET‡16NUM_HEADSŠSET‡2CYL_DISK‹SET‡80SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡256START_HEAD_NUM…SET‡0CYL_DRIVEŠSET‡80PRE_COMP‹SET‡40SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡0éééééé xO******************************************************************************* *ƒF8DDDSI.SI*F*ƒDCB�values�for�8"�Floppy�disk,�double�density,�double�sided,�IBM�fmtO********************************************************************************ATT_WORD‹SET‡$020DSECT_PER_TRACK…SET‡26NUM_HEADSŠSET‡2CYL_DISK‹SET‡77SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡256START_HEAD_NUM…SET‡0CYL_DRIVEŠSET‡77PRE_COMP‹SET‡38SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡44éééééL é �O******************************************************************************* *ƒF8SDDSM.SI*K*ƒDCB�values�for�8"�Floppy�disk,�single�density,�double�sided,�Motorola�fmtO********************************************************************************ATT_WORD‹SET‡$0204SECT_PER_TRACK…SET‡26NUM_HEADSŠSET‡2CYL_DISK‹SET‡77SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡128START_HEAD_NUM…SET‡0CYL_DRIVEŠSET‡77PRE_COMP‹SET‡38SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡44éééééé ŠO******************************************************************************* *ƒF8SDSSI.SI*F*ƒDCB�values�for�8"�Floppy�disk,�single�density,�single�sided,�IBM�fmtO********************************************************************************ATT_WORD‹SET‡$0208SECT_PER_TRACK…SET‡26NUM_HEADSŠSET‡2CYL_DISK‹SET‡77SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡128START_HEAD_NUM…SET‡0CYL_DRIVEŠSET‡77PRE_COMP‹SET‡38SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡44éééM ééé “O******************************************************************************* *ƒF8SDSSM.SI*K*ƒDCB�values�for�8"�Floppy�disk,�single�density,�single�sided,�Motorola�fmtO********************************************************************************ATT_WORD‹SET‡$0200SECT_PER_TRACK…SET‡26NUM_HEADSŠSET‡2CYL_DISK‹SET‡77SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡128START_HEAD_NUM…SET‡0CYL_DRIVEŠSET‡77PRE_COMP‹SET‡38SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡44éééééé œO******************************************************************************* *ƒFXCMD16.SI*5*ƒDCB�values�for�fixed�CMD�disk,�16�megabyte�capacityO********************************************************************************ATT_WORD‹SET‡$10SECT_PER_TRACK…SET‡64NUM_HEADSŠSET‡1CYL_DISK‹SET‡823SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡256START_HEAD_NUM…SET‡16CYL_DRIVEŠSET‡823PRE_COMP‹SET‡0SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡0éM ééééé ¥O******************************************************************************* *ƒFXCMD80.SI*5*ƒDCB�values�for�fixed�CMD�disk,�80�megabyte�capacityO********************************************************************************ATT_WORD‹SET‡$10SECT_PER_TRACK…SET‡64NUM_HEADSŠSET‡5CYL_DISK‹SET‡823SPIRAL_OFF‰SET‡2BYTES_PER_SECTORƒSET‡256START_HEAD_NUM…SET‡16CYL_DRIVEŠSET‡823PRE_COMP‹SET‡0SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡0éééééé ®O******************************************************************************* *ƒFXLRK08.SI*5*ƒDCB�values�for�fixed�LARK�disk,�8�megabyte�capacityO********************************************************************************ATT_WORD‹SETN ‡$90SECT_PER_TRACK…SET‡64NUM_HEADSŠSET‡2CYL_DISK‹SET‡206SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡256START_HEAD_NUM…SET‡2CYL_DRIVEŠSET‡206PRE_COMP‹SET‡0SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡0éééééé ·O******************************************************************************* *ƒFXLRK25.SI*6*ƒDCB�values�for�fixed�LARK�disk,�25�megabyte�capacityO********************************************************************************ATT_WORD‹SET‡$90SECT_PER_TRACK…SET‡64NUM_HEADSŠSET‡2CYL_DISK‹SET‡624SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡256START_HEAD_NUM…SET‡2CYL_DRIVEŠSET‡624PRE_COMP‹SET‡0SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡0ééééééN  ÀO******************************************************************************* *ƒH5WIN05.SI*A*ƒDCB�values�for�5�1/4"�Winchester�hard�disk,�5�megabyte�capacityO********************************************************************************ATT_WORD‹SET‡$0010SECT_PER_TRACK…SET‡32NUM_HEADSŠSET‡2CYL_DISK‹SET‡306SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡256START_HEAD_NUM…SET‡0CYL_DRIVEŠSET‡306PRE_COMP‹SET‡153SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡307éééééé ÉO******************************************************************************* *ƒH5WIN10.SI*B*ƒDCB�values�for�5�1/4"�Winchester�hard�disk,�10�megabyte�capacityO********************************************************************************ATT_WORD‹SET‡$0010SECT_PER_TRACK…SET‡32NUM_HEADSŠSET‡4CYL_DISK‹SET‡306SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡256START_HEAD_NUM…SET‡0CYL_DRIVEŠSET‡306PRE_COMP‹SET‡153SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡307ééééO éé ÒO******************************************************************************* *ƒH5WIN15.SI*B*ƒDCB�values�for�5�1/4"�Winchester�hard�disk,�15�megabyte�capacityO********************************************************************************ATT_WORD‹SET‡$0010SECT_PER_TRACK…SET‡32NUM_HEADSŠSET‡6CYL_DISK‹SET‡306SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡256START_HEAD_NUM…SET‡0CYL_DRIVEŠSET‡306PRE_COMP‹SET‡153SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡307éééééé ÛO******************************************************************************* *ƒH5WIN40.SI*B*ƒDCB�values�for�5�1/4"�Winchester�hard�disk,�40�megabyte�capacityO********************************************************************************ATT_WORD‹SET‡$0010SECT_PER_TRACK…SET‡32NUM_HEADSŠSET‡6CYL_DISK‹SET‡830SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡256START_HEAD_NUM…SET‡0CYL_DRIVEŠSET‡830PRE_COMP‹SET‡400SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡831ééO éééé äO******************************************************************************* *ƒH8WIN10.SI*>*ƒDCB�values�for�8"�Winchester�hard�disk,�10�megabyte�capacityO********************************************************************************ATT_WORD‹SET‡$0210SECT_PER_TRACK…SET‡32NUM_HEADSŠSET‡4CYL_DISK‹SET‡256SPIRAL_OFF‰SET‡0BYTES_PER_SECTORƒSET‡256START_HEAD_NUM…SET‡0CYL_DRIVEŠSET‡256PRE_COMP‹SET‡128SECT_DRIVE‰SET‡0STEP_RATEŠSET‡0R_W_PRE_COMP‡SET‡257éééééé íéé