.MCALL .MODULE .MODULE AT,VERSION=01,COMMENT=,AUDIT=YES ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only 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 except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. .SBTTL Conditional assembly summary ;+ ;COND ; ; 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) ;- ; 7-Mar-88 JFW 00 Initial version. ;20-Apr-88 JFW 01 Changes from code review .SbTtl Macro Library References .MCall .DrDef .MCall .CKxx .Assume .Addr .Library "Src:System" Fix$ed =: 0 ;generate "full" definitions .MCall .SycDf .FixDf .HanDf .Cf3Df .WCBDf .IStDf .MCall .P1xDf .MemDf .Cf3Df .FixDf .HanDf .IStDf .MemDf .P1xDf .SycDf .WCBDf .CKxx .SbTtl PSECT ordering .PSect ATDvr ; Memory resident part .PSect ATBoot ; Bootstrap .PSect Pad001 ; Filler for block alignment .PSect SetOvr ; Aligned SET code .PSect Pad002 ; Filler for block alignment .PSect ATLoad ; 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 A.AT=23456 ;test value for mem resident AT JmpAtN =: JMP+37 ;JMP @# opcode value ;HARDWA::.MMUHD ParCk0 =: 000000 ;PAR0 addr in chunks ParCk1 =: 000200 ;PAR1 addr in chunks ParCk2 =: 000400 ;PAR2 addr in chunks ParCk3 =: 000600 ;PAR3 addr in chunks ParCk4 =: 001000 ;PAR4 addr in chunks ParCk5 =: 001200 ;PAR5 addr in chunks ParCk6 =: 001400 ;PAR6 addr in chunks PARCIo =: 177600 ;IOPage addr in chunks ParCkD =: 000200 ;Delta of 1 par in chunks 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 ...... .DrDef AT,102,0,0,0,0,DMA=NO .IIf EQ MMG$T .Error ;?AT-F-AT can be generated for XM only; .IIf EQ MMG$T .End .DrPtr FETCH=*NO*,LOAD=Load,UNLOAD=Unload .DrESt CLASS=DVC.NL ; .DrIns AT ;NO install code .SbTtl SET code .DrSet SYSGEN,AllSys,O.Sys, .SbTtl . Set AT [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 Tst R3 ;Which kind of entry? Beq 10$ ;*C*normal entry, match SYSGEN Xor R3,R1 ;*C*flip the bits 10$: MovB R1,H.Gen ;*C*set the SYSGEN byte in the handler Return ;done ...... .SbTtl UNLOAD code Unload: ;;; BPT ;**DEBUG** Nop ;place for BPT Mov @#$SyPtr,R0 ;-> RMON Mov P1$Ext(R0),R1 ;-> P1EXT Bic #Cf3.AT,$Cnfg3(R0) ;Indicate service not available Mov $RtsPc(R0),$CJVPt+2(R1) ;Always return carry set for ;all calls thru $CJVPtr Clc ;no error here Return ...... .Assume . LE 1000 .SbTtl DRBEG code .SbTTl . Equivalent to "NL:" .Enabl LSB .DrBeg AT BasLo =: ATStrt+6 Mov #ATCQE,R4 ;Get addr of CQE $Rel .-2 ATCQE LOW Mov @R4,R5 ;-> Q element 3rd word. Tst Q$WCnt(R5) ;Test if read or write Bmi ATExit ;Write - done go to complete Bis #Eof$,@-(R5) ;Read - EOF then go to complete ATExit:: ;;; .DrFin AT ;Exit (R5 loaded above) Jmp @#Dummy ;finish I/O QCpFix =:.-2-BasLo ;substitute $QCOMP address ............... .Dsabl LSB .SbTtl JOBLOC code .SbTtl . Job # & Virt Addr yield Phys Addr ;+ ; ; JOBLOC ; ; On entry ; ; R0 = virtual address to translate ; R1 = job number (0=bg, 2=lowest sys job, ... 14.=fg) ; NOTE: job number is NOT validated as to range or ; evenness ; R3 = size of area to check in chunks (FUTURE SUPPORT) ; ; On exit ; ; If CARRY clear ; ; R1 = PAR 1 relocation bias ; R2 = PAR 1 displacement (0200xx) ; R3 = size of area mapped in chunks (FUTURE SUPPORT) ; R3 = -1, size not checked ; ; If OVERFLOW clear, all of area is mapped (FUTURE SUPPORT) ; If OVERFLOW set, not all of area is mapped (FUTURE SUPPORT) ; ; If CARRY set ; ; R1,R2 random? JOB does not exist (or AT service not available) ;- .SbTtl . Build Pseudo-PARs .Enabl LSB Ck.SP=S.1st JobLoc:: ;Entry for by job number virt to phy convert Jsr R5,10$ ;Save R5, point to XISAR0 with R5 ; equiv to MOV R5,-(SP), MOV PC,R5 Ck.SP ,-2 Ck.R5=XISAR0 .IrpC x,<01234567> XISAR'x': .BlkW 1 .EndR ;pseudoPDRs not needed since no translation code currently ; looks at them! 10$: Mov R4,-(SP) ;Save Ck.SP ,-2 Mov R3,-(SP) ;Save Ck.SP ,-2 Mov #/2,R4 ;do all but PAR7 .Assume ParCk0 eq 0 Clr R3 ;Starting at 0 Ck.R3=ParCk0 20$: Mov R3,(R5)+ ;load a PAR, point to next Add #ParCkD,R3 ;next par load value Sob R4,20$ ;for all 7 .IRpC x,<0123456> Ck.R5 XISAR'x',+2 Ck.R3 ParCk'x' Ck.R3 ,+ParCkD .EndR Ck.R5 XISAR7 Mov #ParCIo,@R5 ;and special case the I/O page PAR .SbTtl . Check for job existance Sec ;Set carry in case job doesn't exist Mov Dummy(R1),R4 ;*C*Get impure area address ImpFix=:.-2-BasLo ;Load code sets up address of IMPURE in RMON Ck.SPa=Ck.SP Beq 90$ ;*C*No impure area, means no job ;NOTE: BG impure always exists Tst R1 ;Background job? Bne 30$ ;No, then can't be KMON .SbTtl . Check for KMON Tst @#$KmonI ;Is KMON the background job? $Rel .-2 $KmonI LORMON Bne 80$ ;Yes, use kernel mapping .SbTtl . Check for defined windows (and process them if so) ;+ ; +-------+-------+ ;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 ;+ ; +-------+-------+ +-------+-------+ ;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 Mov @R3,R3 ;get region base address Add #W.BOFF-W.BLVR,R4 ;point to offset value Ck.R4 ,+W.BOFF-W.BLVR Ck.R4 W.BOFF,+2 Add (R4)+,R3 ;add in window offset Ck.R4 W.BFPD,+1 MovB (R4)+,R2 ;get PDR address Ck.R4 W.BNPD,+1 Bic #^c<^b111*2>,R2 ;get just PDR # *2 Add #XISAR0,R2 ;add in base address $Rel .-2 XISAR0 LOW MovB (R4)+,R1 ;get number of PARs/PDRs for this window 50$: Mov R3,(R2)+ ;update a PAR value Add #ParCkD,R3 ;next PAR value 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 .SbTtl . Use $RELO4 to process pseudo-PARs 80$: Mov #RetLoc,-(SP) ;punch return address $Rel .-2 RetLoc LOW Ck.SP ,-2,S.RET Mov #XISAR0,-(SP) ;Pseudo-PARs $Rel .-2 XISAR0 LOW Ck.SP ,-2,S.XIS Ck.SP S.XIS .Assume CK.SP+2 eq S.RET Jmp @#Dummy ;Use "std" $RELO4' RelFix=:.-2-BasLo ;Load code sets up address of $RELO4 in ; XMSUBS ;NOTE this is a "CALL", stack is set up ; earlier. Ck.SP S.XIS,+2 ;done in RELOC Ck.SP S.RET,+2 ;done in RELOC .SbTtl . Restore registers and return RetLoc: Clc ;no error, clear carry ; Clv ;cleared by following MOVs 90$: Ck.SP Ck.SPa Mov (SP)+,R3 ;*C*Restore Ck.SP ,+2 Mov #-1,R3 ;*C*Indicate no size checking done Mov (SP)+,R4 ;*C*Restore Ck.SP ,+2 Mov (SP)+,R5 ;*C*Restore Ck.SP ,+2 Ck.SP S.1st ARtsPC: Return ...... ATInt: ;use previous RETURN as abort entry .Assume ATInt-2 EQ ARtsPC .Dsabl LSB .DrEnd AT,Force=AllSys ;Gen max comm vector (for SET AT [NO]SYSGEN) .SbTtl LOAD Code .PSect ATLoad .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 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 table of impure area pointers ;+ ; ; .Word -1 ; desired address-> .Word ->BG Imp --- ; .Word ... ^ ; .Word ... |c($Jobs)*2 ; .Word ->FG Imp v ; $IMPLOC:-------> .Word ? --- ;- Ck.R0 A.RMON Mov $ImpLo(R0),R1 ;-> end of impure area list (+2) Ck.R0 A.RMON MovB $Jobs(R0),R2 ;number of job slots Asl R2 ;make into byte count Sub R2,R1 ;-> first impure area pointer Ck.R5 A.AT Mov R1,ImpFix(R5) ;put in memory resident part .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.RMON Add $MEMPt(R0),R1 ;-> memory structure Mov Ofs.RB(R1),R2 ;get offset to RCBs Sub #2,R2 ;offset to word containing -> WCB in Impure Ck.R0 A.RMON Mov $CNTXT(R0),R1 ;->current impure area Mov R1,R3 ;copy impure area pointer Add R2,R3 ;point to -> WCBs in Impure Mov @R3,R2 ;get pointer value Sub R1,R2 ;Sub out base of Impure area Ck.R5 A.AT Mov R2,WPtFix(R5) ;put offset in memory resident part .SbTtl . Find $RELO4 ;+ ; change to Jmp @#JobLoc $JBREL: Jmp Errrtn ; ... ; $CVPPT: Jmp $USRPH--+ ; P1$Ext:----------------> ... | ; | ; +----------------------------(PC offset)--------------+ ; | ; +--->$USRPH: Call $Reloc (PC offset)--------------+ ; | ; +-----------------------------------------------------+ ; | ; +---->$Reloc: Mov #...,-(SP) ; $Relo4: ... addr of this for RELFIX ;- Ck.R0 A.RMON Mov P1$Ext(R0),R1 ;-> P1EXT Mov R1,R2 ;Copy P1EXT pointer Add #$CVPPT+2,R2 ;-> Address word in JMP $USRPH Mov (R2)+,R3 ;load PC offset and 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