/ OS-278 RX01/02 (PAIR A) HANDLER / LAST EDIT: 25-JUN-1986 17:00:00 CJL / RX01/RX02 NON-SYSTEM HANDLER FOR DRIVES ZERO AND ONE FROM THE DISTRIBUTED / VERSION OF OS-278. / DISASSEMBLED BY HAND BY: / CHARLES J. LASNER / CHARLES LASNER ASSOCIATES, 1986 / SOURCE COPYRIGHT 1986, CHARLES LASNER ASSOCIATES / BASED ON CORE IMAGE OF DECUS DM-101 OS-278 FOR DECMATE II / SYSTEM HANDLER. / NOTE: THIS IS THE DEC VERSION, NOT THE OPTIMAL VERSION! / EQUATED SYMBOLS. / BOOT= 7600 /BOOTSTRAP ADDRESS DEVNUM= 32 /LOGICAL DEVICE NUMBER NL0004= CLA CLL IAC RTL /LOAD AC WITH 0004 NL4000= CLA CLL CML RAR /LOAD AC WITH 4000 NL7775= CLA CLL CMA RTL /LOAD AC WITH 7775 VERSHI= "B /HIGH VERSION LETTER VERSLO= "2&77 /LOW VERSION LETTER / RX50 EQUATED SYMBOLS. DEVCODE=75^10+6000 /SKELETON IOT CODE OF DISK SEL= DEVCODE+0 /LOAD DRIVE PAIR PER AC[11] LCD= DEVCODE+1 /LOAD COMMAND REGISTER XDR= DEVCODE+2 /TRANSFER DATA REGISTER STR= DEVCODE+3 /SKIP ON, CLEAR TRANSFER FLAG SER= DEVCODE+4 /SKIP ON, CLEAR ERROR FLAG SDN= DEVCODE+5 /SKIP ON, CLEAR DONE FLAG INTR= DEVCODE+6 /INTERRUPT ENABLE/DISABLE PER AC[11] INIT= DEVCODE+7 /INITIALIZE CONTROLLER, RECALIBRATE DRIVES / NOTES ON THIS HANDLER: / THIS HANDLER READS AND WRITES THE DISK IN "12-BIT" MODE, IN WHICH ONLY / SIX BITS OF EVERY EIGHT-BIT BYTE ARE USED. AN RX01 DISKETTE CONTAINS 494 / OS/8 RECORDS USING THIS METHOD. / FOR COMPATIBILITY WITH THE PAST (THOUGH CLEARLY NOT OPTIMAL), THE HANDLER / READS AND WRITES RX01 DATA ON EVERY TRACK VIA AN IDENTICAL SCHEME USING A / TWO-WAY INTERLEAVE - I.E. SECTORS 1-26 ARE ACCESSED IN THE FOLLOWING / SEQUENCE: / 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, / 21, 23, 25, 2, 4, 6, 8, 10, 12, 14, / 16, 18, 20, 22, 24, 26 / RX02 (DOUBLE-DENSITY) MEDIA ARE ACCESSED VIA A SIMILAR METHOD, EXCEPT A / THREE-WAY INTERLEAVE IS USED: / 1, 4, 7, 10, 13, 16, 19, 22, 25, 2, / 5, 8, 11, 14, 17, 20, 23, 26, 3, 6, / 9, 12, 15, 18, 21, 24 / TRACK-SECTOR CALCULATIONS ARE DONE WHILE WAITING FOR I/O TO COMPLETE TO / ALLOW OVERLAP. / BUILD HEADER BLOCK. *0 /BUILD WANTS IT THAT WAY -2 /TWO ENTRIES IN THIS HANDLER DEVICE RX2A /GROUP NAME DEVICE RX20 /PERMANENT NAME DEVNUM^10+4000 /DCB WORD RX2A&177+4000 /ENTRY POINT WORD; TWO-PAGE ZBLOCK 2 /BUILD WANTS IT THIS WAY DEVICE RX2A /GROUP NAME DEVICE RX21 /PERMANENT NAME DEVNUM^10+4000 /DCB WORD RX2B&177+4000 /ENTRY POINT WORD; TWO-PAGE ZBLOCK 2 /BUILD WANTS IT THIS WAY / HANDLER CODE. *200 /BUILD WANTS IT THIS WAY / INITIALIZATION CODE. POINT, HLT /WILL BE LOWEST ADDRESS OF SECOND PAGE UNIT, JMS I POINT/(THERE) /GO RELOCATE OUR SECOND PAGE POINTERS / LIST OF POINTERS TO BE RELOCATED. PLIST= . /POINTER LIST STARTS HERE LQUO, QUO-. /POINTER TO QUOTIENT LRETRY, RETRY-. /POINTER TO RETRY COUNT LREC, REC-. /POINTER TO LOGICAL RECORD LSIZE, SIZE-. /POINTER TO DEVICE SIZE LREMD, REMD-. /POINTER TO REMAINDER LFN, FN-. /POINTER TO FUNCTION LRESELE,RESELECT-. /POINTER TO RESELECT ROUTINE LDENSW, DENSW-. /POINTER TO DENSITY SWITCH LENTRY, ENTRY-. /POINTER TO SECOND PAGE ENTRY POINT PCOUNT= .-PLIST /COUNT OF POINTERS TO RELOCATE / COMES HERE FROM ZOO TO PROCESS DEVICE TYPE, ETC. WHICH, NL4000 /SETUP PRIMARY RX01/02 PAIR BIT SEL /SELECT THE PAIR NOW SDN /SKIP ON, CLEARING THE DONE FLAG NOW NOP /THIS CAN BE SKIPPED SER /SKIP ON, CLEARING THE ERROR FLAG NOW NOP /THIS CAN BE SKIPPED NL7775 /SETUP THE DCA I LRETRY/(RETRY) /RETRY COUNTER TAD I ZOO /GET UNIT NUMBER^20+402 DCA UNIT /SAVE FOR LATER ISZ ZOO /BUMP TO INITIALIZE FLAG TAD I ZOO /GET INITIALIZE FLAG L7700, SMA CLA /SKIP IF NOT INITIALIZED YET JMP NORMAL /JUMP IF ALREADY INITIALIZED RSTART, JMP BOUNCE /HOP OVER ENTRY POINTS / ENTRY POINTS: MUST BE AT 032 AND 036. IFZERO .&177-32-1&4000 RX2A, VERSHI^100+VERSLO /DRIVE ZERO ENTRY POINT JMS ZOO /CALL COMMON ROUTINE 402 /UNIT ZERO, DOUBLE-DENSITY PLUS 2 -1 /NOT YET INITIALIZED RX2B, .-. /DRIVE ONE ENTRY POINT JMS ZOO /CALL COMMON ROUTINE L422, 422 /UNIT ONE, DOUBLE-DENSITY PLUS 2 DOOR, JMP WHICH /NOT YET INITIALIZED (THIS IS A NEGATIVE LITERAL) / INITIALIZATION CODE CONTINUES HERE. BOUNCE, TAD L10/(12-2) /GET EXTRA BITS TAD UNIT /FORM "READ STATUS DOUBLE-DENSITY" FUNCTION LCD /LOAD THE COMMAND SDN /WAIT FOR IT JMP .-1 /TO FINISH XDR /GET THE STATUS AND L32/(32) /JUST DENSITY ERROR, RX02, RX03 BITS TAD L10/(10) /ADJUST POSSIBLE CASES AND L422/(22) /SINGLE=0, DOUBLE=20, QUAD=22 (WHAT ABOUT 2?) DCA I ZOO /PLACE TYPE CODE OVER NEGATIVE VALUE SER /SKIP ON, CLEARING THE ERROR FLAG L10, 10 /CONSTANT 0010; THIS CAN BE SKIPPED NORMAL, TAD I ZOO /GET TYPE CODE SZA CLA /SKIP IF SINGLE-DENSITY TAD L7700/(-100) /GET EXTRA AMOUNT IF DOUBLE-DENSITY SECTOR TAD L7700/(-100) /GET BASIC AMOUNT EITHER WAY DCA I LDENSW/(DENSW) /SAVE AS SECTOR WORD COUNT TAD I ZOO /GET TYPE CODE CLL RTR /DOUBLE-SIDED (QUAD) BIT TO LINK SNA CLA /SKIP IF NOT SINGLE-DENSITY TAD L1734/(1734) /MAKE IT 6044 IF SINGLE-DENSITY TAD L4110/(4110) /WILL BE 4110 IF DOUBLE OR QUAD SNL /SKIP IF QUAD STL RAR /ELSE DIVIDE BY TWO DCA I LSIZE/(SIZE) /STORE CORRECT -SIZE VALUE TAD I LDENSW/(DENSW) /GET SECTOR LENGTH CLL CMA RTL /374 IF SINGLE, 774 IF DOUBLE AND UNIT /NOW HAVE (400^DOUBLE) + (20^UNIT) DCA I LFN/(FN) /STORE AS FUNCTION WORD NL7775 /BACKUP ZOO CALLER BY THREE TAD ZOO /NOW HAVE ORIGINAL CALLER DCA T1 /STORE FOR NOW TAD I T1 /AC CONTAINS CALLER'S ADDRESS CLLFLD, HLT /WILL BE CDF CALLING FIELD JMS I LENTRY/(ENTRY) /CALL SECOND PAGE MAIN ROUTINE / NOTE: THE ADDRESS OF "DIVSUB", WHICH FOLLOWS IMMEDIATELY IS NOW AVAILABLE / IN "ENTRY" ON THE OTHER PAGE! / DIVIDE AND ERROR RECOVERY SUBROUTINE. / CALL WITH: / AC POSITIVE OR ZERO: DIVIDE, ETC. CALL / AC NEGATIVE: ERROR RETRY CALL DIVSUB, .-. /DIVIDE SUBROUTINE CDF 00 /ENSURE FIELD ZERO SPA CLA /SKIP IF REALLY A DIVIDE CALL JMP RSTART /NO, IT WAS AN ERROR RETRY! DCA I LQUO/(QUO) /CLEAR DIVIDE QUOTIENT TAD I ZOO /GET TYPE CODE RTR /MOVE QUAD BIT TO LINK SNL CLA /SKIP IF QUAD (DOUBLE-SIDED) DISKETTE JMP SHUNT /JUMP IF NOT QUAD TYPE TAD I LREC/(REC) /GET CURRENT SECTOR TAD L4110/(-3670) /COMPARE TO FIRST SIDE LIMIT SZL CLA /SKIP IF SECOND SIDE NEEDED JMP SHUNT /JUMP IF NOT TAD I LFN/(FN) /GET CURRENT FUNCTION WORD AND L422/(422) /MAINTAIN DENSITY, UNIT, READ/WRITE BITS TAD L1000/(1000) /ADD ON SECOND SIDE BIT DCA I LFN/(FN) /STORE BACK COMPOSITE TAD L4110/(-3670) /REDUCE RECORD SIZE BY ONE SIDE'S WORTH SHUNT, TAD I LREC/(REC) /GET CURRENT SECTOR (POSSIBLY REDUCED) DIVLOOP,ISZ I LQUO/(QUO) /BUMP UP QUOTIENT TAD L7746/(-32) /REMOVE 26 SMA /SKIP IF DONE JMP DIVLOOP /ELSE KEEP GOING TAD L32/(32) /RESTORE LOST 26 DCA T1 /SAVE REMAINDER FOR NOW TAD I ZOO /GET TYPE CODE AGAIN SZA CLA /SKIP IF SINGLE-DENSITY TAD T1 /ELSE MULTIPLY BY THREE FOR DOUBLE-DENSITY TAD T1 /GET AT LEAST TWICE TAD T1 /FOR NORMAL CASE CLL IAC /CLEAR LINK FOR TEST AND MAKE ORIGIN ONE TAD L7746/(-32) /REMOVE 26 SMA SZA /SKIP IF DONE JMP .-2 /ELSE GO BACK TAD L32/(32) /RESTORE POSITIVE VALUE DCA I LREMD/(REMD) /STORE (UNCORRECTED) REMAINDER RAL /GET THE LINK TAD I ZOO /ADD ON TYPE CODE SNA CLA /SKIP IF OTHER THAN HALF OF THE SINGLE-DENSITY CASES ISZ I LREMD/(REMD) /CORRECT SINGLE-DENSITY CASES JMP I DIVSUB /RETURN / CONSTANTS. L416, 416 /CONSTANT 0416 L32, 32 /CONSTANT 0032 L1000, 1000 /CONSTANT 1000 L7746, 7746 /CONSTANT 7746 L1734, 1734 /CONSTANT 1734 L4110, 4110 /CONSTANT 4110 *.&7600+167 /GET NEAR END OF PAGE / COMMON ENTRY POINT SUBROUTINE. ZOO, .-. /COMMON ROUTINE CLA /CLEAN UP RDF /GET CALLING FIELD TAD LCDF/(CDF) /TURN INTO CDF CALLING FIELD DCA CLLFLD /STORE IN-LINE LCDF, CDF 00 /GOTO FIELD ZERO NOW CLOSE, TAD DOOR /GET CLOSING INSTRUCTION T1, DCA CLOSE /PREVENT FURTHER ONCE-ONLY EXECUTION JMS POINT /ACQUIRE ADDRESS OF SECOND PAGE AND CONTINUE IN /FURTHER ONCE-ONLY CODE THERE / SECOND PAGE OF HANDLER. *400 /BUILD WANTS IT THIS WAY / VARIABLES; INITIALIZE SUBROUTINE WILL LIVE HERE ALSO. BUF, .-. /POINTER TO CALLER'S BUFFER RETRY, .-. /RETRY COUNTER SIZE, .-. /SIZE OF DEVICE (NEGATIVE) CALLER, .-. /CALLER'S ADDRESS QUO, .-. /DIVIDE QUOTIENT REC, .-. /LOGICAL SECTOR NUMBER BC, .-. /BUFFER CONTROL COUNTER FN, .-. /FUNCTION WORD; BITS ARE: /(HEAD^1000)+(DENSITY^400)+(UNIT^20)+(READ^2) DENSW, .-. /SECTOR SIZE IN WORDS (NEGATIVE) ENTRY, .-. /WILL BE ADDRESS OF DIVSUB WHEN THEY GET HERE HERE= . /WHERE WE ARE NOW *BUF /DEFINE ONCE-ONLY CODE OVER VARIABLES / INITIALIZATION ROUTINE; RELOCATES IN-LINE ADDRESS ARGUMENTS AND RETURNS / PAST THE END OF THE LIST. THERE, .-. /WILL POINT TO RELOCATION LIST RELOOP, TAD THERE /GET THEIR ADDRESS TAD I THERE /UPDATE A POINTER DCA I THERE /STORE BACK ISZ THERE /BUMP TO NEXT POINTER ISZ RESELECT /DONE WITH POINTER LIST? JMP RELOOP /NO, KEEP GOING JMP I THERE /YES, RETURN TO CODE WAITING PAST THE LIST / MAIN ROUTINE; ENTRY VIA JMS TO SETUP "DIVSUB" POINTER. *HERE /RESET ORIGIN TO FORMER VALUE DCA CALLER /SAVE POINTER TO CALLER'S ARGUMENTS RDF /GET CALLING FIELD TAD (CIF CDF 00) /MAKE INTO CIF CDF CALLING FIELD DCA EXFLD /STORE IN-LINE FOR EXIT LATER NL4000 /CLEAR LINK AND SET AC[0] TAD I CALLER /READ/WRITE BIT TO LINK AND L70/(70) /JUST TRANSFER FIELD BITS TAD LCDF0/(CDF) /MAKE INTO CDF TRANSFER FIELD DCA BUFCDF /STORE IN-LINE CML RTL /0=WRITE, 2=READ TAD FN /ADD ON FUNCTION DCA FN /STORE BACK COMPOSITE TAD I CALLER /GET FUNCTION WORD AGAIN RAL /MOVE UP AND L7600/(7600) /JUST PAGE BITS CIA /INVERT FOR COUNTING DCA BC /SAVE AS BUFFER COUNT ISZ CALLER /BUMP TO TRANSFER ADDRESS TAD I CALLER /GET TRANSFER ADDRESS DCA BUF /STASH IT ISZ CALLER /BUMP TO RECORD NUMBER TAD L175/(175) /GET GOOD VALUE TAD DENSW /CHECK IF SINGLE OR DOUBLE SIZE SECTOR SMA CLA /SKIP IF DOUBLE SIZE SECTOR TAD I CALLER /ELSE WANT TWICE TWICE RECORD NUMBER TAD I CALLER /GET IT AT LEAST ONCE EITHER WAY ISZ CALLER /BUMP TO ERROR RETURN CLL RAL /DOUBLE IT (OR QUAD IT!) DCA REC /SAVE FOR NOW SZL /SKIP IF LEGAL SECTOR NUMBER JMP ERREX /JUMP IF ILLEGAL VALUE OR SIZE REQUEST JMS I ENTRY/(DIVSUB) /CALCULATE SECTOR NOW TAD FN /GET FUNCTION WORD RTR /READ/WRITE BIT TO LINK SZL CLA /SKIP IF WRITING JMP STREAD /JUMP IF READING / TOP OF MAIN LOOP. TOP, TAD FN /GET FUNCTION LCD /ASK TO FILL OR EMPTY THE SILO TAD DENSW /GET SECTOR SIZE DCA RESELECT /SETUP SECTOR WORD COUNTER BUFCDF, HLT /WILL BE CDF BUFFER FIELD TRLOOP, JMS TESTFLAGS /CHECK RX FLAGS NOW SKP /SKIP IF OK JMP FLGERROR /BARF IF NOT TAD I BUF /GET A WORD IF WRITING XDR /TRANSFER IT DCA I BUF /STORE BACK IN CASE READING ISZ BUF /BUMP TO NEXT REMD, .-. /DIVIDE REMAINDER; THIS CAN BE SKIPPED ISZ RESELECT /DONE ENOUGH WORDS? JMP TRLOOP /NO, KEEP GOING JMS TESTFLAGS /CHECK RX FLAGS NOW JMP FLGERROR /BARF IF NOT OK TAD DENSW /GET SECTOR SIZE CMA /INVERT IT TAD BC /COMPARE TO BUFFER COUNT SNA /SKIP IF NOT DONE YET JMP OKEX /JUMP IF DONE READING DCA BC /UPDATE BUFFER COUNT / COMES HERE TO START READ (OR WRITE OUT FILLED BUFFER). STREAD, NL0004 /SET READ (OR WRITE) INCREMENT TAD FN /NOW HAVE COMPOSITE FUNCTION LCD /LOAD THE READ (OR WRITE) COMMAND JMS TESTFLAGS /CHECK RX FLAGS NOW SKP /SKIP IF OK JMP FLGERROR /BARF IF NOT OK TAD REMD /GET PRECOMPUTED SECTOR NUMBER XDR /SEND IT L7600, CLA!400 /CLEAN UP JMS TESTFLAGS /CHECK RX FLAGS NOW SKP /SKIP IF OK JMP FLGERROR /BARF IF NOT OK TAD QUO /GET PRECOMPUTED TRACK NUMBER XDR /SEND IT ISZ REC /BUMP TO NEXT SECTOR JMS I ENTRY/(DIVSUB) /CALCULATE NEXT SECTOR AND TRACK NOW JMS TESTFLAGS /CHECK RX FLAGS NOW JMP FLGERROR /BARF IF NOT OK ISZ BC /DONE WRITING? JMP TOP /NO, KEEP GOING / COMES HERE WHEN FINISHING ENTIRE READ OR WRITE. OKEX, ISZ CALLER /BUMP PAST ERROR RETURN SKP /DON'T COMPLAIN WITH NEGATIVE SIZE ON GOOD CALL ERREX, TAD SIZE /GET SIZE OF DEVICE BADEXIT,DCA REMD /STORE FOR NOW JMS RESELECT /SELECT NORMAL PAIR FOR OTHERS TAD REMD /GET EXIT VALUE EXFLD, HLT /WILL BE CIF CDF CALLING FIELD JMP I CALLER /RETURN TO CALLER TESTFLA,.-. /FLAG TEST ROUTINE FLGLOOP,STR /TRANSFER FLAG UP? SKP /SKIP IF NOT JMP I TESTFLAGS /YES, JUST RETURN SDN /DONE FLAG UP? JMP FLGLOOP /NO, JUST KEEP GOING ISZ TESTFLAGS /BUMP RETURN ON DONE FLAG SER /ERROR FLAG? JMP FLAGOK /NO PROBLEM FLGERRO,NL4000 /INDICATE PROBLEMS ISZ RETRY /TOO MANY RETRIES? JMS I ENTRY/(DIVSUB) /NO, GO RETRY (NEGATIVE AC) JMP BADEXIT /YES, FORGET IT FLAGOK, CLA CLL /CLEAN UP KSF /KEYBOARD FLAG UP? JMP I TESTFLAGS /NO, JUST RETURN KRB /YES, READ IT IN TAD (-3) /COMPARE TO <^C> SZA CLA /SKIP IF IT MATCHES JMP I TESTFLAGS /ELSE JUST RETURN JMS RESELECT /SELECT NORMAL PAIR FOR OTHERS LCDF0, CDF 00 /GOING TO FIELD ZERO JMP I L7600/(BOOT) /BACK TO THE KEYBOARD MONITOR RESELEC,-PCOUNT /RESELECT PAIR ROUTINE; PRELOADED FOR RELOCATION SEL /SELECT NORMAL PAIR SDN /SKIP ON, CLEARING DONE FLAG L70, 70 /CONSTANT 0070; THIS CAN BE SKIPPED L175, 175 /CONSTANT 0175 JMP I RESELECT /RETURN $ /THAT'S ALL FOLK!