DynDDCProg.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Created by Jean Gastinel, April 4, 1988 4:35:31 pm PDT
Bob Hagmann December 2, 1987 12:01:10 pm PST
Hoel, May 19, 1988 2:18:26 pm PDT
Hoel, April 8, 1988 8:06:51 pm PDT
This module creates the Atom which contains the program for the DynaBus exerciser chip to send and receive DynaBus packets to test the display controller chip (DDC).
DIRECTORY
Atom, DynaBusInterface, Rope; 
DynDDCProg: CEDAR PROGRAM
IMPORTS Atom
EXPORTS
~ BEGIN
Quad: TYPE = DynaBusInterface.Quad;
Cmd: TYPE = DynaBusInterface.Cmd;
L: PROC [c: BOOL] RETURNS [rc: REF ANY] = {rc ← NEW[BOOL ← c]};
C: PROC [c: CARD] RETURNS [rc: REF ANY] = {rc ← NEW[CARD ← c]};
Q: PROC [c: Quad] RETURNS [rc: REF ANY] = {rc ← NEW[Quad ← c]};
Com: PROC [c: Cmd] RETURNS [rc: REF ANY] = {rc ← NEW[Cmd ← c]};
R: PROC [c: Rope.ROPE] RETURNS [rc: REF ANY] = {rc ← NEW[Rope.ROPE ← c]};
The Program Starts Here
Atom.PutProp[$Simul2Sender, $PKList, LIST[
$Init,
$StartStop,
$ReceiveAll,
LIST[$Wait, C[1110]],  -- for waiting for DBus initialization
   -- wish I could wait for $ResetOff instead.
First Initialize MemCtl Chip (copied from /Dragon/Dragon7.0/SSMem/DynMemProg.mesa)
LIST[$IOWrite0, C[1], L[TRUE], L[TRUE], C[0],C[28],C[28],C[28],C[22],C[22]],
LIST[$IOWriteRqst, Q[[0, 0, 0030H, 0400H]], Q[[0, 0, 0E19EH, 72D6H]]],
$WaitMsgSent,
LIST[$Wait, C[9]], -- for snooping
LIST[$SendShOw,R["SO"]],
$WaitMsgReceived, -- for the Echo
$WaitReply,
LIST[$IOWrite1, C[1],C[10],C[0],C[0]],
LIST[$IOWriteRqst, Q[[0, 0, 0030H, 0401H]], Q[[0, 0, ****H, ****H]]],
$WaitMsgSent,
$WaitMsgReceived, -- for the Echo
$WaitReply,
LIST[$IOWrite2, C[1],C[10],C[0]],
LIST[$IOWriteRqst, Q[[0, 0, 0030H, 0402H]], Q[[0, 0, ****H, ****H]]],
$WaitMsgSent,
$WaitMsgReceived, -- for the Echo
$WaitReply,
LIST[$WriteBlockRqst, Q[[0,0,0,0]],Q[[3,3,3,3]],Q[[2,2,2,2]],Q[[1,1,1,1]],Q[[0,0,0,0]]],
$WaitMsgSent,
$WaitMsgReceived, -- for the Echo
$WaitReply,
LIST[$WriteBlockRqst, Q[[0,0,0,0]],Q[[0,0,0,0]],Q[[1,1,1,1]],Q[[2,2,2,2]],Q[[3,3,3,3]]],
$WaitMsgSent,
$WaitMsgReceived, -- for the Echo
$WaitReply,
Then Initialize Memory Locations
LIST[$WriteBlockRqst,   -- initialize memory
 Q[[ 0, 0, 0000H, 0000H ]], -- address
 Q[[ 0001H, 0203H, 0405H, 0607H ]], -- data
 Q[[ 0809H, 0A0BH, 0C0DH, 0E0FH ]], -- data
 Q[[ 1011H, 1213H, 1415H, 1617H ]], -- data
 Q[[ 1819H, 1A1BH, 1C1DH, 1E1FH ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $WriteBlockRqst
$WaitReply, -- *************************************
LIST[$WaitWriteBlockRplyandCheck,
 Q[[ 0, 0, 0000H, 0000H ]]],
LIST[$WriteBlockRqst,   -- initialize memory
 Q[[ 0, 0, 0000H, 0008H ]], -- address
 Q[[ 2021H, 2223H, 2425H, 2627H ]], -- data
 Q[[ 2829H, 2A2BH, 2C2DH, 2E2FH ]], -- data
 Q[[ 3031H, 3233H, 3435H, 3637H ]], -- data
 Q[[ 3839H, 3A3BH, 3C3DH, 3E3FH ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $WriteBlockRqst
$WaitReply, -- *************************************
LIST[$WaitWriteBlockRplyandCheck,
 Q[[ 0, 0, 0000H, 0008H ]]],
Then On to DDC:
Check Whether DDC Rejects Requests In User Mode -- 5-11-88
Actually, the code doesn't do any checking. It just sends out the requests in user mode and notices that replies were received. I have to check the logic analyzer display to verify that the Mode/Fault bit of the reply says error.
LIST[$IOWriteRqstUser,   -- framePtrBase ← 0
 Q[[ 0, 0, 0020H, 0A80H ]], -- address
 Q[[ 0, 0, 0000H, 0000H ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$IOReadRqstUser,   -- read back framePtrBase
 Q[[ 0, 0, 0020H, 0A80H ]]], -- address
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOReadRqst
LIST[$WaitIOReadRplyandCheck,
 Q[[ 0, 0, 0020H, 0A80H ]],
 Q[[ 0, 0, 0080H, 0001H ]]], -- data: FaultCode=1
     -- DevID=2
Register Initialization
 (For the following commands, devID=0 and mode=kernel always.)
LIST[$IOWriteRqst,   -- framePtrBase ← 0
 Q[[ 0, 0, 0020H, 0A80H ]], -- address
 Q[[ 0, 0, 0000H, 0000H ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$WaitIOWRplyandCheck,
 Q[[ 0, 0, 0020H, 0A80H ]]],
 Q[[ 0, 0, 0000H, 0000H ]]],
LIST[$IOWriteRqst,   -- framePtrLimit ← 8H
 Q[[ 0, 0, 0020H, 0A81H ]], -- address
 Q[[ 0, 0, 0000H, 0008H ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$WaitIOWRplytandCheck,
 Q[[ 0, 0, 0020H, 0A81H ]]],
 Q[[ 0, 0, 0000H, 0000H ]]],
LIST[$IOWriteRqst,   -- bitsPerPixel ← 3 (meaning 8 bits/pixel)
 Q[[ 0, 0, 0020H, 0A83H ]], -- address
 Q[[ 0, 0, 0000H, 0003H ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$WaitIOWRplyandCheck,
 Q[[ 0, 0, 0020H, 0A83H ]]],
 Q[[ 0, 0, 0000H, 0000H ]]],
LIST[$IOWriteRqst,   -- intOffset ← 0DH
 Q[[ 0, 0, 0020H, 0A88H ]], -- address
 Q[[ 0, 0, 0000H, 000DH ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$WaitIOWRplyandCheck,
 Q[[ 0, 0, 0020H, 0A88H ]]],
 Q[[ 0, 0, 0000H, 0000H ]]],
Register Readback -- just to show that IORRqst works
LIST[$IOReadRqst,   -- read back framePtrBase
 Q[[ 0, 0, 0020H, 0A80H ]]], -- address
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOReadRqst
LIST[$WaitIOReadRplyandCheck,
 Q[[ 0, 0, 0020H, 0A80H ]],
 Q[[ 0, 0, 0000H, 0000H ]]], -- data
LIST[$IOReadRqst,   -- read back intOffset
 Q[[ 0, 0, 0020H, 0A88H ]]], -- address
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOReadRqst
LIST[$WaitIOReadRplyandCheck,
 Q[[ 0, 0, 0020H, 0A88H ]],
 Q[[ 0, 0, 0000H, 000DH ]]], -- data
Microcode Initialization
World's dumbest microcode -- only generates one interrupt.
 00: Jump 01;
 01: Jump 02; Take8Cycles;
 02: Jump 03; ProgInt;
 03: Jump 03;
LIST[$IOWriteRqst,   -- vGen[0] ← 07FFC00
 Q[[ 0, 0, 0020H, 0A40H ]], -- address
 Q[[ 0, 0, 007FH,0FC00H ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$WaitIOWRplyandCheck,
 Q[[ 0, 0, 0020H, 0A40H ]]],
 Q[[ 0, 0, 0000H, 0000H ]]],
LIST[$IOWriteRqst,   -- vGen[1] ← 0BFE000
 Q[[ 0, 0, 0020H, 0A41H ]], -- address
 Q[[ 0, 0, 00BFH,0E000H ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$WaitIOWRplyandCheck,
 Q[[ 0, 0, 0020H, 0A41H ]]],
 Q[[ 0, 0, 0000H, 0000H ]]],
LIST[$IOWriteRqst,   -- vGen[2] ← 0FFFC01
 Q[[ 0, 0, 0020H, 0A42H ]], -- address
 Q[[ 0, 0, 00FFH,0FC01H ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$WaitIOWRplyandCheck,
 Q[[ 0, 0, 0020H, 0A42H ]]],
 Q[[ 0, 0, 0000H, 0000H ]]],
LIST[$IOWriteRqst,   -- vGen[3] ← 0FFFC00
 Q[[ 0, 0, 0020H, 0A43H ]], -- address
 Q[[ 0, 0, 00FFH,0FC00H ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$WaitIOWRplyandCheck,
 Q[[ 0, 0, 0020H, 0A43H ]]],
 Q[[ 0, 0, 0000H, 0000H ]]],
Generate An Interrupt
LIST[$IOReadRqst,   -- first clear interrupts
 Q[[ 0, 0, 0020H, 0A82H ]]], -- address
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOReadRqst
$WaitReply, -- don't check result, which should be X's
LIST[$IOWriteRqst,   -- intMask ← 4H; (enable only int 0)
 Q[[ 0, 0, 0020H, 0A82H ]], -- address
 Q[[ 0, 0, 0000H, 0004H ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$WaitIOWRplyandCheck,
 Q[[ 0, 0, 0020H, 0A82H ]]],
 Q[[ 0, 0, 0000H, 0000H ]]],
LIST[$IOWriteRqst,   -- vGenEn ← 1; (start microcode)
 Q[[ 0, 0, 0020H, 0A87H ]], -- address
 Q[[ 0, 0, 0000H, 0001H ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$WaitIOWRplyandCheck,
 Q[[ 0, 0, 0020H, 0A87H ]]],
 Q[[ 0, 0, 0000H, 0000H ]]],
LIST[$WaitIOWRqstandCheck,  -- here's the interrupt.
 Q[[ 0, 0, 0010H, 000DH ]], -- address
 Q[[ 0, 0, 0400H, 0000H ]]], -- data (2^(31-reason))
LIST[$IOWriteRply, 
 Q[[ 0, 0, 0010H, 000DH ]],
 Q[[ 0, 0, 0400H, 0000H ]]],
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRply
LIST[$IOReadRqst,   -- read and clear interrupts
 Q[[ 0, 0, 0020H, 0A82H ]]], -- address
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOReadRqst
LIST[$WaitIOReadRplyandCheck,
 Q[[ 0, 0, 0020H, 0A82H ]],
 Q[[ 0, 0, 0000H, 0024H ]]], -- data
Read Block Requests
LIST[$IOWriteRqst,   -- rBRqstEn ← 1; (enable RBRqst's)
 Q[[ 0, 0, 0020H, 0A86H ]], -- address
 Q[[ 0, 0, 0000H, 0001H ]]], -- data
$WaitMsgSent,
$WaitMsgReceived, -- echo of above $IOWriteRqst
$WaitReply, -- *************************************
LIST[$WaitIOWRplyandCheck,
 Q[[ 0, 0, 0020H, 0A86H ]]],
 Q[[ 0, 0, 0000H, 0000H ]]],
LIST[$WaitReadBlockRqstandCheck,  -- a RBRqst occurs.
 Q[[ 0, 0, 0000H, 0000H ]]], -- address
 Q[[ 0, 0, 0000H, 0000H ]]], -- victim address (invalid)
LIST[$WaitReadBlockRqstandCheck,  -- another RBRqst occurs.
 Q[[ 0, 0, 0000H, 0008H ]]], -- address
 Q[[ 0, 0, 0000H, 0000H ]]], -- victim address (invalid)
     -- SIGNAL here
LIST[$WaitReadBlockRplyandCheck,  -- a RBRply occurs.
Q[[ 0, 0, 0000H, 0000H ]], -- address (not checked. why?)
 Q[[ 0001H, 0203H, 0405H, 0607H ]], -- data
 Q[[ 0809H, 0A0BH, 0C0DH, 0E0FH ]], -- data
 Q[[ 1011H, 1213H, 1415H, 1617H ]], -- data
 Q[[ 1819H, 1A1BH, 1C1DH, 1E1FH ]]], -- data
LIST[$WaitReadBlockRplyandCheck,  -- another RBRply occurs.
Q[[ 0, 0, 0000H, 0008H ]], -- address (not checked. why?)
 Q[[ 2021H, 2223H, 2425H, 2627H ]], -- data
 Q[[ 2829H, 2A2BH, 2C2DH, 2E2FH ]], -- data
 Q[[ 3031H, 3233H, 3435H, 3637H ]], -- data
 Q[[ 3839H, 3A3BH, 3C3DH, 3E3FH ]]], -- data
Then Just Wait
$Nop,
LIST[$Jump, $Nop]
]];
END.
Notes:
1. For more information on what the atoms in the program list do, see:
[Dragon]<Dragon7.0>DynaBusInterface>Simul2SenderImpl.mesa.
Questions:
1. What is the address range of DDC in the simulation? 00200800H - 00200BFFH.
2. For $IOWriteRqst:
a. Why not call it $IOWRqst?
b. What is the mode bit? (I'd like mode = 0 = kernel, usually, but not always.)
c. What is the devID? (I'd guess devID = 1, based on the agreement with Jean of 4-13-88.) (On second thought, I'd guess devID = 0, based on the agreement with Jean of 4-22-88.)
d. What is the Reply/Shared bit's value? (I don't really care; just curious.)
3. May I also have:
a. $IOWriteRply (i.e., $IOWRply)?
- can program get the necessary bits from the corresponding IOWRqst?
b. $WaitIOWRqstAndCheck?
- let's think about what parameters are needed.
c. $WaitReadBlockRqstAndCheck (i.e., $WaitRBRqstAndCheck)?
- let's think about what parameters are needed.
d. $ReadBlockRply
- let's think about what parameters are needed.
e. $WaitResetOff
4. Can you ever be waiting for more than one thing, ready to take whatever happens first? For example:
a. After enabling vGenEn ← 1, we're waiting both for the reply and for the interrupt.
b. After enabling rBRqstEn ← 1, we're waiting both for the reply and for the RBRqst's.
5. Why is there a $WaitMsgSent? (Why isn't it just part of the previous command?)
----------------------------
Change Log
4-24-88: Tried filling in the program, using $opCodes supplied by Jean in msg of 4-20-88.
Still don't have:
$WaitIOWRplyandCheck so substitute $WaitRply.
$IOWriteRply    so hope nobody cares that we can't do an interrupt acknowledge.
$WaitResetOff    so wait for a carefully chosen number of cycles.
$IOWriteRqstUserMode  so don't test yet
$IOReadRqstUserMode  so don't test yet
$RBRplyFault    so don't test yet
$IOWRplyFault    so don't test yet
Questions:
$$WaitReadBlockRplyandCheck why not check address cycle too???
Progress:
Let memory addresses be 0H and 8H; see DynMemProg.mesa.
4-24-88: Decided to wait 1110 cycles, not 110 cycles.
4-25-88: Inserted MemCtl initialization stuff from:
/Dragon/Dragon7.0/SSMem/DynMemProg.mesa.
4-27-88: Tried to use ordinary $IOWriteRqst instead of exotic ones for MemCtl, so I can specify the right DevNum.
4-29-88: Oh, yes. Read interrupt register, to clear interrupt state, before enabling int 0. Also acknowledge interrupt after it happens.
5-2-88: Changed microcode to wait longer before interrupting; workaround to avoid having to fix $WaitReply in Simul2SenderImpl now.
5-2-88: Changed FramePtrBase to 0 (from 76543200H) and FramePtrLimit to 10H (from 76543210H). (I had previously changed the memory address values elsewhere in the program, but not here. Oops.)
5-3-88: Oops! Also have to change expected value of FramePtrBase when read back. While we're at it, add another read back, intOffset.
5-3-88: Bug fix: load fourth microcode word into location 3, not location2.
5-4-88: Temporarily make deliberate mismatch of victim address of second RBRqst, so we can see what's going on before plunging into the RBRply's.
5-4-88: Fix $WaitReadBlockRqstandCheck to match Simul2SenderImpl's: only one Q, for victim address, rather than two, for address and victim address.
5-8-88: Set second $WaitReadBlockRqstandCheck's victim address from 2 to 0, because we now don't want to raise a mismatch signal.
5-11-88: Added section to test whether DDC rejects requests in user mode.
5-11-88: Comment out the WaitReadBlockRqstandCheck list items, since Simul2SenderImpl has trouble finding them (timing bug).
5-12-88: Repaired expected FaultCode of IORRqst: 00800001H, not 1H.
5-18-88: Use WaitIOWRplyandCheck, now that I have a version of Simul2Sender that implements a viable one. (This version is awkward in that it requires a data word, but what of that?)
5-19-88: Changed my mind: let WaitIOWRplyandCheck require only the address word as a parameter.