{MiscDayBreak.mc, Last changed by RCH, 22-Jul-86 9:49:32 Based on MiscDicentra by HGM, November 1983 DayBreak specific portion of Misc.mc } { Copyright (C) 1984, 1985 by Xerox Corporation. All rights reserved.} {############################################################################# # # # MiscDayBreak change log: # # # RCH 7/22/86 Commented out INPUT, OUTPUT, WR, and DaybreakSpecificAdditions JPM 7/31/85 Fix possible bug in SoftwareLock JPM 7/3/85 Opie redesign conversion JPM 5/8/85 do software locking JPM 4/19/85 move some unused landing spots to MiscPCE JPM 3/15/85 reinstate SetLOCK & ClrLOCK JPM 2/7/85 redo @WRMP and @LOCKMEM to use U-regs JPM 12/4/84 temporarily remove SetLOCK & ClrLOCK (they cause trouble) JPM 11/13/84 un-simplified @LOCKMEM (timing constraint still holds) JPM 10/25/84 change @NOTIFYIOP to do set, clear rather than clear, set JPM 10/10/84 updated maintenance panel addresses JPM 10/9/84 simplified @LOCKMEM when timing constraint removed JPM 10/1/84 changed cycle for ClrLOCK (should be cycle 3 before last mem reference) JPM 9/25/84 @RRIT must reread counters if calculated low word is 0 (timing problem) JPM 9/24/84 fixed bugs in @RRIT (needed another stack push; high byte of counts must be masked off) JPM 9/19/84 moved label @LOCKMEM next to code (for analysis tool), added other labels for debugging JPM 9/6/84 added @BYTESWAP; added copyright notice JPM 8/24/84 corrected hardware address values in @RRIT JPM 6/26/84 changed @WRMP to do store & notify JPM 6/25/84 added @LOCKMEM and @NOTIFYIOP SXW 5/30/84 changed Read Interval timer @RRIT for 8254 Do we still need an I/O read and write command, @OUTPUT & @INPUT. Do we also still need a maintaince panel write @WRMP ( I don't think so ) Also the dicentra specific additions need to be checked for daybreak applicability remover RawRefs from @RawRead and @RawWrite deleted @SetPhoneLineCSB, @GetExternalStatus & @SetExtCtrl # # # # # # #############################################################################} {timer addresses and commands} Set[T1Count, 41]; Set[T2Count, 42]; Set[T012Control, 43]; Set[T12Latch, 0DC]; {***************************************************************************** INPUT Input *****************************************************************************} {@INPUT: rhRio ← TOS LRot0, c1, at[0,10,ESC8n]; Rio ← STK, pop, c2; pop, c3; IO ← [rhRio, Rio+0], push, GOTO[Ra] c1;} {***************************************************************************** OUTPUT Output *****************************************************************************} {@OUTPUT: rhRio ← TOS LRot0, c1, at[1,10,ESC8n]; Rio ← STK, pop, c2; T ← STK, pop, c3; IO ← [rhRio, Rio+0], GOTO[Wb], c1;} {***************************************************************************** WR - Write Registers *****************************************************************************} {YETCH. Pilot wants to smash the clock.} @WRIT: pop, c1, at[5,10,ESC7n]; IBDisp, GOTO[SLa], c2; {Write maintenance panel} @WRMP: TT ← uMaintPanel, {maint panel code} c1, at[7,10,ESC7n]; rhTT ← uIORgnHigh, c2; TOS ← TOS LRot8, {must byteswap} c3; MAR ← [rhTT, TT + 0], c1; MDR ← TOS, c2; TT ← TT + 1, {maint panel down-notify mask} c3; MAR ← [rhTT, TT + 0], c1; Noop, c2; TOS ← MD, GOTO[@NOTIFYIOP], c3; {***************************************************************************** RR - Read Registers *****************************************************************************} {Read Interval timer} @RRIT: rhRio ← T012Control, c1, at[0D,10,ESC7n]; Rx ← 0, push, c2; STK ← TOS, push, c3; { The two halves of the counter are synchronized by a latch command given to the 8254 control register. The counts are correct and synchronized to the command, not to when the counters are read. } ReadTimer: IO ← [rhRio, 0], {Control Register} c1; MDR ← T12Latch, {Latching the counts} c2; rhRio ← T2Count, c3; { read timer two, higher 16 bits } IO ← [rhRio, 0], {Cnt 2 LSB} c1; T ← 0FF, c2; Q ← MD and T, {mask high byte} c3; IO ← [rhRio, 0], {Cnt 2 MSB} c1; rhRio ← T1Count, c2; TOS ← MD and T, {mask high byte} c3; { read timer one, lower 16 bits, and finish higher (interlaced instructions)} IO ← [rhRio, 0], {Cnt 1 LSB} c1; TOS ← TOS LRot8 or Q, {combine timer 2 bytes} c2; Q ← MD and T, {mask high byte} c3; IO ← [rhRio, 0], {Cnt 1 MSB} c1; TOS ← 0 - TOS, {down count}, c2; T ← MD and T, {mask high byte} c3; T ← T LRot8 or Q, {combine timer 1 bytes} c1; T ← 1 - T, {down count, carries at 1} c2; [] ← T or Rx, NZeroBr, {timing glitch when T is 0} c3; STK ← T, BRANCH[$,RRx], {in Misc.mc} c1; Rx ← 1, {need only one repeat} c2; rhRio ← T012Control, GOTO[ReadTimer], c3; {------------------------------------------------------------------------- Daybreak Specific Additions -------------------------------------------------------------------------} {@RawRead: rhRio ← TOS LRot0, c1, at[04,10,ESC8n]; Rio ← STK, pop, c2; pop, c3; MAR ← [rhRio, Rio+0], push, GOTO[Ra], {In Read} c1; @RawWrite: rhRio ← TOS LRot0, c1, at[05,10,ESC8n]; Rio ← STK, pop, c2; T ← STK, pop, c3; MAR ← [rhRio, Rio+0], GOTO[Wb], c1;} {-------------------------------------------------------------------------} @BYTESWAP: TOS ← TOS LRot8, pop, c1, at[07,10,ESC8n]; push, IBDisp, GOTO[DISPNIonly], c2; {-------------------------------------------------------------------------} {@LOCKMEM: [operation, offset, value, mask] RETURNS [result]} {TOS contains lock mask} {T is loaded with value for operation} {TT is loaded with offset into IORegion, whose base address is in [uIORgnHigh, rIORgn]} {rhT is loaded with operation code} @LOCKMEM: T ← STK, pop, c1, at[08,10,ESC8n]; TT ← STK, pop, L4 ← SoftwareLockRets.LOCKMEM, c2; rhT ← STK, pop, c3; MAR ← [rhIORgn, rIORgn + iopRequestsLock], c1; TT ← TT + rIORgn, CANCELBR[SoftwareLockSideDoor,0], c2; MDR ← 0, IBDisp, push, CANCELBR[$,0], c2, at[SoftwareLockRets.LOCKMEM,10,SoftwareLockRets]; STK ← TOS, fXpop, fZpop, DISPNI[OpTable], c3; {-------------------------------------------------------------------------} @NOTIFYIOP: {TOS contains notify mask: byte-mask in high byte, byte offset in low} T ← uMesaProc, c1, at[09,10,ESC8n]; rhT ← uIORgnHigh, c2; TT ← LShift1 (T + downNotifyBits), LOOPHOLE[niblTiming], c3; MAR ← [rhT, T + notifiersLockMask], c1; STK ← TOS, T ← TOS and ~0FF, CANCELBR[$,0], c2; TOS ← MD, L4 ← SoftwareLockRets.NOTIFYIOP, c3; rhTT ← STK, pop, XLDisp, c1; {the following branch is reversal of Mesa byte order to do byte-swapping for IOP} TT ← RShift1 (TT + rhTT), LOOPHOLE[niblTiming], BRANCH[MaskInLowByte,$,2], c2; rhT ← lock.or, SetMPIntIOP, CALL[SoftwareLock], c3; MaskInLowByte: rhT ← lock.or, SetMPIntIOP, c3; MAR ← [rhIORgn, rIORgn + iopRequestsLock], c1; T ← T LRot8, CANCELBR[SoftwareLockSideDoor,0], c2; MDR ← 0, IBDisp, CANCELBR[$,0], c2, at[SoftwareLockRets.NOTIFYIOP,10,SoftwareLockRets]; ClrMPIntIOP, DISPNI[OpTable], c3; {-------------------------------------------------------------------------} @SetWakeupBits: T ← TOS, push, MesaIntRq, c1, at[0A,10,ESC8n]; STK ← TOS, pop, c2; TOS ← STK, pop, c3; T ← T or uWP, c1; uWP ← T, IBDisp, GOTO[DISPNIonly], c2; {-------------------------------------------------------------------------} {Catch unused landing spots.} @a206: PC ← PC - 1, GOTO[ESCb], c1, at[06,10,ESC8n]; {-------------------------------------------------------------------------} {SoftwareLock subroutine L4 contains return branch TOS contains mask T contains value TT contains low real address of word on which locked op is done rhT contains operation code in lower three bits on return, TOS contains result} SoftwareLock: MAR ← [rhIORgn, rIORgn + iopRequestsLock], c1; CANCELBR[$,0], c2; SoftwareLockSideDoor: Rx ← MD, c3; Rx ← TOS and Rx, c1; [] ← Rx, ZeroBr, {zero iff lock available} c2; BRANCH[SoftwareLock,$], c3; MAR ← [rhIORgn, rIORgn + mesaHasLock], c1; MDR ← TOS, CANCELBR[$,0], c2; rhTT ← uIORgnHigh, c3; LockAcquired: MAR ← [rhTT, TT + 0], c1; Xbus ← rhT, XDisp, c2; TOS ← MD, DISP4[LockedOp,08], c3; LockedAdd: MAR ← [rhTT, TT + 0], c1, at[lock.add,10,LockedOp]; MDR ← TOS ← T + TOS, GOTO[ClearLock], c2; LockedAnd: MAR ← [rhTT, TT + 0], c1, at[lock.and,10,LockedOp]; MDR ← TOS ← T and TOS, GOTO[ClearLock], c2; LockedOr: MAR ← [rhTT, TT + 0], c1, at[lock.or,10,LockedOp]; MDR ← TOS ← T or TOS, GOTO[ClearLock], c2; LockedXchg: MAR ← [rhTT, TT + 0], c1, at[lock.xchg,10,LockedOp]; MDR ← T, GOTO[ClearLock], c2; LockedWrIfNil: [] ← TOS, ZeroBr, c1, at[lock.wrIfNil,10,LockedOp]; BRANCH[ClearLock,$], c2; GOTO[LockedOr] {same as write, since TOS = 0}, c3; ClearLock: L4Disp, c3; MAR ← [rhIORgn, rIORgn + mesaHasLock], DISP4[SoftwareLockRets], c1;