.MCALL .MODULE .MODULE FX,VERSION=00,COMMENT=,AUDIT=YES ; COPYRIGHT 1990 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ; ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE ; INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ; COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ; OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ; TRANSFERRED. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ; AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ; CORPORATION. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. .SBTTL Conditional assembly summary ;+ ;COND ; ; ; FX$SUP (0) U-I space support only ; 1 U-I, U-D, S-I and S-D space support ; ; MMG$T 1 std conditional (no code effects) ; required to be 1 (XM only) ; TIM$T std conditional (no code effects) ; ERL$G std conditional (no code effects) ;- .IIf NDF FX$SUP FX$SUP=0 ;28-Feb-90 JFW 00 Initial version. .SbTtl Macro Library References .MCall .DrDef .MCall .CKxx .Assume .Addr .Library "Src:System" .SbTtl PSECT ordering .PSect FXDvr ; Memory resident part .PSect FXBoot ; Bootstrap .PSect Pad001 ; Filler for block alignment .PSect SetOvr ; Aligned SET code .PSect Pad002 ; Filler for block alignment .PSect FXLoad ; Aligned LOAD code ; $Rel PSect ordering .PSect RelL1L,D ; Label for LOW--LOW LstL2L: .PSect RelL2L,D LstL9L: ; end of list .PSect RelLZL,D .Word 000000 .PSect RelL1R,D ; Label for LOW--RMON LstL2R: .PSect RelL2R,D LstL9R: ; end of list .PSect RelLZR,D .Word 000000 .PSect Pad003 ; Filler for block alignment .PSect ATHigh ; High memory area .PSect $Last$ ; last defined PSect ; Any following PSects are "Rogues" .SbTtl Equates S.1st=1000 ;test value for stack alignment A.RMON=123456 ;test value for RMON address JmpAtN =: JMP+37 ;JMP @# opcode value AllSys =: ^b11111111 ;all possible sysgen bits Dummy =: -1 ;value to be filled in later .SbTtl Macro definitions .Macro $Rel Offset Value Type ?L1 ...V2=. .=Offset .If Idn , L1: .Word Value-BasLo .=...V2 .Save .PSect RelL2L .Word L1-BasLo .Restore .MExit .EndC .If Idn , L1: .Word Value .=...V2 .Save .PSect RelL2R .Word L1-BasLo .Restore .MExit .EndC .=...V2 .Error;?SYSMAC-E-Unexpected T y p e - 'Type'; .EndM $Rel .Macro ...... .EndM ...... ;>>>change id when assigned in SYSTEM .DrDef FX,377,0,0,020,177640,DMA=NO .IIf EQ MMG$T .Error ;?FX-F-FX can be generated for XM only; .IIf EQ MMG$T .End .DrPtr FETCH=*NO*,LOAD=Load,UNLOAD=Unload .DrESt CLASS=DVC.NL .SbTtl INSTALL code .Enable LSB .DrIns FX .Assume . eq InsDat Br 10$ ;data device installation .Assume . eq InsSys Br 20$ ;system device installation 10$: ;>>>here find the extended inpure area region? Mov @#$SYPtr,R0 ;find RMON Bit #CF?.??,??????(R0) ;Is Supervisor supported? .If NE FX$SUP Beq 20$ ;No, then don't install .IfF;NE FX$SUP Bne 20$ ;Yes, then don't install .EndC;NE FX$SUP Tst (PC)+ ;Ok 20$: Sec ;Error Return .Dsable LSB .SbTtl SET code .DrSet SYSGEN,AllSys,O.Sys, .SbTtl . Set FX [No]Sysgen O.Sys: Clr R3 ;normal entry Nop N.Sys: .Assume O.Sys+4 eq N.Sys Mov @#$SyPtr,R0 ;-> RMON MovB $Sysge(R0),R1 ;get SYSGEN byte Xor R3,R1 ;flip the bits or leave them alone MovB R1,H.Gen ;set the SYSGEN byte in the handler Clc ;no error Return ;done ...... .SbTtl UNLOAD code Unload: ;;; BPT ;**DEBUG** Nop ;place for BPT Mov @#$SyPtr,R0 ;-> RMON ;>>> Bic #Cf?.??,$Cnfg?(R0) ;Indicate service not available Clc ;no error here Return ...... .Assume . LE 1000 .SbTtl DRBEG code .SbTTl . Equivalent to "NL:" .Enabl LSB .DrBeg FX BasLo =: FXStrt+6 Mov #FXCQE,R4 ;Get addr of CQE $Rel .-2 FXCQE LOW Mov @R4,R5 ;-> Q element 3rd word. Tst Q$WCnt(R5) ;Test if read or write Bmi FXExit ;Write - done go to complete Bis #Eof$,@-(R5) ;Read - EOF then go to complete FXExit:: ;;; .DrFin FX ;Exit (R5 loaded above) Jmp @#Dummy ;finish I/O QCpFix =:.-2-BasLo ;substitute $QCOMP address ............... .Dsabl LSB .SbTtl Process an IOT interrupt ARtsPC: Return ...... FXInt:: ;IOT interrupt entry ;use previous RETURN as abort entry .Assume FXInt-2 EQ ARtsPC ;>>> ;save registers Mov @#$Cntxt,R4 ;Get impure area address $Rel .-2 $Cntxt LORMON Bit #?????$,@#$JSW ;Does the job want .FMAP? Beq UsrIOT ;no, pass the interrupt on .If NE FX$SUP ;>>> select the proper WCB set ;>>> clear out the FM.MOD bits .IfF;NE FX$SUP Bit #FM.Mod,R0 ;Selecting any space other than U-I? .Assume FM.UI eq 0 .Assume FM.UD ne 0 .Assume FM.SI ne 0 .Assume FM.SD ne 0 Bne SpaErr ;Yes, not supported .EndC;NE FX$SUP MovB R0,R0 ;clear high bit (200 bit is cleared) ;shift FM.PAR down to match PDR*2 numbers Asr R0 ;00ppp000->000ppp00 Asr R0 ;000ppp00->0000ppp0 .SbTtl . Check for defined windows (and process them if so) .Enabl LSB ;+ ; +-------+-------+ ;I.WPtr:| -> WCBs |-------+ ; +-------+-------+ | ; | ; +----------------------------+ ; | ; +--->+-------+-------+ ;I.WNum:| number of WCBs| ; +-------+-------+ ; | WCBs | ; : : ; | | ; +-------+-------+ ;- 30$: Add #Dummy,R4 ;get number of windows, then ->first WCB WPtFix=:.-2-BasLo ;Load code sets up offset??? Mov (R4)+,R5 ;number of windows .If NE FX$SUP ;>>>here bump pointer for other spaces based on FM.MOD .EndC;NE FX$SUP ;+ ; +-------+-------+ +-------+-------+ ;W.BRCB:| -> RCB |------->R.BAdd:| phy addr (32) | ; +-------+-------+ +-------+-------+ ;W.BLVR:| low virt addr | R.BSiz:| size in chunks| ; +-------+-------+ +-------+-------+ ;W.BHVR:| high virt addr| R.BSta: | status| ; +-------+-------+ +-------+-------+ ;W.BSiz:| size in chunks| R.BNWd:|# windw| ; +-------+-------+ +-------+ ;W.BOff:|base offset(32)| ; +-------+-------+ ;W.BFPd: |1st PDR| ; +-------+-------+ ;W.BNPd:|# PDRs | ; +-------+-------+ ;W.BLPd:|val in last PDR| ; +-------+-------+ ;- Ck.R4=W.BRCB 40$: Ck.R4 W.BRCB,+2 Mov (R4)+,R3 ;get RCB pointer Ck.R4a=Ck.R4 Beq 60$ ;window not in use ;>>>should this test be W.BSIZ = 0? ;>>>is this a bug in AT? do we care? Mov @R3,R3 ;get region base address Add #W.BFPd-W.BLVR,R4 ;point to first PDR number Ck.R4 ,+W.BFPd-W.BLVR Ck.R4 W.BFPD,+1 MovB (R4)+,R2 ;get PDR address Bic #^c<^b111*2>,R2 ;get just PDR # *2 Ck.R4 W.BNPd,+1 MovB (R4)+,R1 ;get number of PARs/PDRs for this window 50$: CmpB R2,R0 ;is this the base PDR in the request? Beq 80$ ;yes Add #2,R2 ;else maybe try another PDR number Sob R1,50$ Ck.R4 ,+2 Tst (R4)+ ;align pointer Br 70$ ;try another WCB .......... 60$: Add #W.BLGH-W.BLVR,R4 ;next WCB Ck.R4a ,+W.BLGH-W.BLVR 70$: Ck.R4 Ck.R4a Ck.R4 W.BLGH Sob R5,40$ ;do all windows ;>>>here window not found .SbTtl Found the window control block, verify request fits 80$: .Dsabl LSB .Enable LSB SwaB R1 ;PDR count *200 Asr R1 ;... Clr R2 ;assume length not specified Tst Old.R0(SP) ;Was the length specified? .Assume FM.LEN lt 0 Bpl 30$ ;no, then it can't be wrong! Mov Old.R2(SP),R2 ;get the specified length (in chunks) Cmp R1,R2 ;does it fit? Blos 30$ ;yes ;>>>here window too small error 20$: ;>>>here region too small error 30$: Mov Old.R1(SP),R5 ;get offset value Cmp R5,R.BSiz(R3) ;is the offset within the window? Bhi 20$ ;no, error Add R2,R5 ;high address (in chunks) Cmp R5,R.BSiz(R3) ;is the offset+size within the window? Bhis 20$ ;no, error 40$: Tst R2 ;size specified in request? Bne 50$ ;yes Mov R.BSiz(R3),R2 ;try region size Sub R5,R2 ;reduced by base offset Cmp R2,R1 ;inside window? Blos 50$ ;yes Mov R1,R2 ;else use window size 50$: .Dsabl LSB .SbTtl UsrIOT User wants to use IOT internally .Enable LSB UsrIOT: Mov I.?????(R4),R0 ;Get user's address for IOTs Beq 20$ ;None? Bit #1,R0 ;Supervisor mode routine? Beq 10$ ;No Bic #??????,Old.PS(SP) ;change to Supervisor mode in stacked PS Dec R0 ;Clear low bit in new PC 10$: Mov R0,Old.PC(SP) ;derail return to user routine ;>>> restore registers RTI ...... 20$: Mov #??????,R0 ;?Fx-F-No user IOT address supplied $Rel ?????? .Print BisB #??????,@#?????? ;Fatal .Exit ...... .Dsabl LSB .DrEnd FX,Force=AllSys ;Gen max comm vector (for SET FX [NO]SYSGEN) .SbTtl LOAD Code .PSect FXLoad .Enabl LSB ;+ ; Input: ; R0 -> LOAD: ; R1 -> GETVEC: ; R2 = $SLOT*2 ; R3 = type code (4) ; R4 -> read routine ; R5 -> $ENTRY word for handler ; ; Register Allocation: ; ; R0 -> RMON ; R1--R4 work ; R5 -> BasLo (mem resident handler code) ;- Load:: ;;; BPT ;**DEBUG** Nop ;Place for BPT .SbTtl . "Std" REL processing Clr @#IOTVec+2 ;Force to PR0 on entry Mov @#$SyPtr,R0 ;-> RMON Ck.R0=A.RMON Mov @R5,R5 ;-> handler memory resident part Ck.R5=A.AT .Addr #LstL2L,R2 ;-> LOW--LOW reloc list 10$: Mov (R2)+,R4 ;get offset to reference Beq 20$ ;EOL Ck.R5 A.AT Add R5,R4 ;-> reference word Ck.R5 A.AT Add R5,@R4 ;update reference word Br 10$ ;and try for next .......... 20$: ;-> LOW--RMON reloc list (follows LOW--LOW) 30$: Mov (R2)+,R4 ;get offset to reference Beq 40$ ;EOL Ck.R5 A.AT Add R5,R4 ;-> reference word Ck.R0 A.RMON Add R0,@R4 ;update reference word Br 30$ ;and try for next .......... 40$: Mov $QComp(R0),QCpFix(R5) ;Get Queue Completion address ; and put it in hand coded .DRFIN .Dsabl LSB .SbTtl . Find offset in Impure area to number of WCBs ;+ ; $MEMPT:(offset)--------> ... ; Ofs.RB: .Word I.WPtr+2 (offset)----+ ; | ; +---------------------------------------------------------------+ ; | ; | $CNTXT:-------------+ ; | | ; | +----------------------+ ; | | ; | +->I.Base ... --- ; | ... ^ ; | I.WPtr .Word ----+ | ; +--->I.???? BSS RCBs| | ; ... | | offset is result ; +------------------------+ | ; | ... v ; +--->I.WNum .Word count --- ; I.???? BSS WCBs ;- Ck.R0 A.RMON Mov R0,R1 ;copy RMON pointer Ck.R0 A.RMO: .Word I.WPtr+2 (offset)----+ ; | ; +---------------------------------------------------------------+ ; | ; | $CNTXT:-------------+ ; | | ; | +----------------------+ ; | | ; | +->I.Base ... --- ; | ... ^ ; | I.WPtr .Word ----+ | ; +--->I.???? BSS RCBs| | ; ... | | offset is result ; +------------------------+ | ; | ... v ; +--->I.WNum .Word count --- ; I.???? BSS WCBs ;- Ck.R0 A.RMON Mov R0,R1 ;copy RMON pointer Ck.R0 A.RMO: .Word I.WPtr+2 (offset)----+ ; | ; +---------------------------------------------------------------+ ; | ; | $CNTXT:-------------+ ; | | ; | +----------------------+ ; | | ; | +->I.Base ... --- ; | ... ^ ; | I.WPtr .Word ----+ | ; +--->I.???? BSS RCBs| | ; ... | | offset is result ; +------------------------+ | ; | ... v ; +--->I.WNum .Word count --- ; I.???? BSS WCBs ;- Ck.R0 A.RMON Mov R0,R1 ;copy RMON pointer Ck.R0 A.RMO get PC value Add R2,R3 ;-> $USRPH Add #2,R3 ;-> Address word in CALL $RELOC Mov (R3)+,R2 ;load PC offset and get PC value Add R2,R3 ;-> $RELOC Add #4,R3 ;-> $RELO4 Ck.R5 A.AT Mov R3,RelFix(R5) ;put address in memory resident part .SbTtl . Patch XMSUBS to use handler code Mov #JMPATN,$CJVPt(R1); change to JMP @# Ck.R5 A.AT Mov R5,R2 ;Copy AT Baslo pointer Add #JobLoc-BasLo,R2 ;-> JobLoc Mov R2,$CJVPt+2(R1) ;-> routine in handler .SbTtl . Indicate service available Ck.R0 A.RMON Bis #Cf3.AT,$Cnfg3(R0) ;Indicate service available Clc ;no error Return ...... .Dsabl LSB .END