{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;