; IfsXMOps.mu ; Copyright Xerox Corporation 1979, 1980 ; Last modified by Taft, February 26, 1980 5:46 PM ; - Add XMLoad, XMStore ; Last modified by Butterfield, September 7, 1979 11:24 AM ; - return to XBcplUtil's Start3 - 8/17/79 ; Extended memory operations: ; 63400-63417 DoubleBlt (see below) ; 63420 XMLoad: AC0 _ @AC1 in bank AC0 ; 63421 XMStore: (@AC1 in bank AC0) _ AC3 ; These operations all save and restore the emulator's bank register. ; As written, this microcode can be executed only on an XM Alto; however, ; for a non-XM Alto, system initialization turns all the XMAR_s into ; MAR_s, so in fact the microcode can be executed on a non-XM Alto also ; (but of course it can operate only on bank 0). ; Additionally, DoubleBlt can only be executed on an Alto-II since ; it does double-word stores. !1, 2, XLoadStore, DoubleBlt; !1, 2, DBLoop, XMOpsExit; XMOps: MAR_ 177740; Read bank register for task 0 NOP; L_ MD; MAR_ 177740; Set bank register for task 0 SINK_ DISP, SINK_ lgm20, BUS=0; What operation? XREG_ L, TASK, :XLoadStore; [XLoadStore, DoubleBlt] Save old value ; Common exit sequence to restore the bank register and finish XMOpsExit: MAR_ 177740; Restore bank register for task 0 TASK; MD_ XREG, :Start3; Return to Emulator ; Double-word block transfer, possibly using Extended Memory ; AC0: first destination address (must be even) ; AC1: first source address (must be even) ; AC3: number of double-words to transfer ; DISP[12-13]: destination bank number ; DISP[14-15]: source bank number ; Timing: 14 cycles (2.38 microseconds) per double-word. ; = 305 microseconds for 256 words ; = 1.22 milliseconds for 1024 words !1, 2, DBMayI, DBNoI; !1, 2, DBInt, DBDisI; DoubleBlt: MD_ DISP; Set normal bank from bits 12-13, ; Alternate bank from bits 14-15 ; Main loop of double-word transfer DBLoop: XMAR_ T_ AC1; Reference source address L_ NWW, BUS=0; Test for interrupts L_ 2+T, SH<0, :DBMayI; [DBMayI, DBNoI] Increment source by 2 DBNoI: AC1_ L; Update source address DBDisI: L_ MD; L_ First data word T_ MD; T_ Second data word MTEMP_ L, L_ T; MTEMP_ first, L_ second MAR_ T_ AC0; Reference destination address T_ ONE+T+1; Increment destination by 2 MD_ MTEMP; Store first data word MD_ M; Store second data word L_ AC3-1; Decrement and test double-word count AC3_ L, L_ T, SH=0, TASK; AC0_ L, :DBLoop; [DBLoop, XMOpsExit] Update dest adr ; Here if possible interrupt (SH<0 branch pending) DBMayI: AC1_ L, L_ T, :DBInt; [DBInt, DBDisI] ; Here if interrupt definitely pending DBInt: AC1_ L; Restore old source address L_ PC-1, TASK; Back up PC PC_ L, :XMOpsExit; ; Extended memory load/store ; XMLoad: AC0 _ @AC1 in bank AC0 ; XMStore: (@AC1 in bank AC0) _ AC3 !1, 2, XLoad, XStore; XLoadStore: MD_ AC0; Alternate bank from AC0[14:15] XMAR_ AC1; Start the reference SINK_ DISP, BUSODD; Which operation? :XLoad; [XLoad, XStore] XLoad: L_ MD; Complete the load AC0_ L, :XMOpsExit; XStore: MD_ AC3, :XMOpsExit; Complete the store