{File name: <CoPilot>DLion>CedarMisc.mc Description: Miscellaneous Mesa opcodes, modified for Cedar Author: R. Garner, Created: April 3, 1980. Last edited: Fiala 5-Jun-86 18:23:56 Fiala 23-Jul-86 17:01:40: Remove assumption that right-half of uIOPage contains the bank number of the IOPage; use the constant cedarIOPageHigh instead. Fiala 18-Nov-86 15:52:32 Remove commented out old defn's of the old map opcodes. Fiala 20-Nov-86 17:22:26 Conditionally assemble of RCLK, SETMP, INPUT, and OUTPUT only when Config # 7 (not Dicentra). Fiala 30-Jan-87 15:08:37 Removed obsolete defn's for ASSOC, GETF, and SETF. Changed the displacement on SETMP from 41 to MaintenancePanelOffset for new IOP. Copyright (C) 1980, 1981, 1985, 1986, 1987 by Xerox Corporation. All rights reserved. } { MISC - Miscellaneous operations } @MISC: Xbus ← ibHigh, XDisp, c1, opcode[364'b]; Rx ← ib, XDisp, push, DISP4[MiscHigh], c2; STK ← TOS, pop, DISP4[Misc0n], c3, at[0,10,MiscHigh]; { The original Pilot 8.0 map opcodes, ASSOC, SETF, and GETF (Misc 0, 1, and 2), use short arguments in which the VP is the first argument word and the RP and 4 map flags are the second argument word; this results in a 32 megabyte VM limit and 2 megabyte RM limit. The equivalent SM, SMF, and GMF opcodes here use a 32-bit VP as the first argument, 32-bit RP as the second argument, and 16-bit flags as the third argument (protected, dirty, and referenced = bits 12 to 15), thereby permitting larger VM and RM configurations. However, the current implementation ignores the high-order RM and VM words, so the only effect is that the RM page specification increases from 12 bits to 16 bits (i.e., from 2 megabytes to 4 megabytes). The DTiger can handle up to 8 megabytes of real memory, or up to 22-bit RM addresses. The DLion limit of 20 bits of RM is partly due to the VM map design, which has 4 flag bits and 12 bits of real page address. The modification here extends the RM limit to 4 megabytes by converting 1 flag bit to an address bit. Mesa PrincOps defines 6 map flag states and reserves 2 more states, all encoded in 3 bits. Extension to 8 megabytes could be accomplished by putting some map flags in a separate storage table, as discussed in DTigerManual.memo. The map holds the 13-bit real page in bits [12..15] and [0..8] and the write protected, dirty, and referenced flags in bits [9..11]. The flags are interpreted as follows (see DLion Microcode Reference page 30): w d r Interpretation ReadOK WriteOK 0 0 0 untouched, unprotected no no 0 0 1 unwritten, read yes no 0 1 0 reserved for software -- -- 0 1 1 written yes yes 1 0 0 untouched, protected no no 1 0 1 protected, read yes no 1 1 0 vacant no no 1 1 1 reserved for software -- -- The ReadOk and WriteOK columns show whether or not read and write references can, respectively, proceed without modification to the map entry. The two "don't care" states are filled in to allow ReadOK to be based upon a branch on the r bit (XRefBr) and WriteOK to be based on a 4-way branch on the w and d bits (XwdDisp). } {SM Set Map} {The extra pops skip the high-order words of the real page and virtual page, which are assumed to be 0.} @SM: TOS {map flags} ← TOS and 7, pop, c1, at[08, 10, Misc6n]; TT {real page} ← STK, pop, c2; {XRefBr tests bit 11, so this is testing bit 3 in the real page word, the high-order bit of the real page.} TT ← TT LRot8, XRefBr, pop, c3; T {virtual page} ← STK, pop, BRANCH[SMe, SMf], {Check ext. adr bit} c1; SMe: TT ← TT and ~80, GOTO[SMg], c2; SMf: TT ← TT or 80, {add ext adr bit} c2; {Now have the high-order address bit in bit 8. Map flags will be formed in bits 9..11. Bits 8..12 become 0..3 of the value written into the map.} SMg: rhT ← T ← T LRot8, c3; PC ← PC + 1, fXpop, push, c1; TOS ← TOS LRot4 {map flags}, c2; Noop, c3; Noop, c1; TT {real page} ← TT and ~70, c2; TT ← TOS {map flags} or TT, c3; {Now have the real page in bits 12..15 and 0..8 of the map word and the write protected, dirty, and referenced flags in bits 9..11.} SMd: Map ← [rhT, T], c1; MDR ← TT, IBDisp, GOTO[SLTail], c2; {GMF Get Map Flags} @GMF: T {virtual page} ← STK, pop, L0 ← 1, c1, at[09, 10, Misc6n]; GOTO[SMFa], c2; GMFa: STK ← 0, IBDisp, GOTO[SLTail], c2; {SMF Set Map Flags. Preserve old real page in the map unless new flags = vacant; return old flags and real page as the result} @SMF: pop, L0 ← 0, c1, at[0A, 10, Misc6n]; T {virtual page} ← STK, pop, c2; SMFa: rhT ← T ← T LRot8, c3; TOS {new map flags} ← TOS and 7, fXpop, push, c1; PC ← PC + 1, c2; Noop, c3; Map ← [rhT, T], c1; TT {new map flags} ← TOS LRot4, c2; TOS {old map entry} ← MD, c3; Rx {old map flags} ← TOS LRot12, XDisp, c1; TOS ← TOS and ~70, DISP4[SMFb, 8], c2; {Here, TT gets new map flags or'ed with old real page unless new flags = vacant. If the map entry was vacant, it stays vacant, in spite of attempt to change the flags.} SMFb: TT ← TOS or TT, GOTO[SMFc], c3, at[08, 10, SMFb]; TT ← TOS or TT, GOTO[SMFc], c3, at[09, 10, SMFb]; TT ← TOS or TT, GOTO[SMFc], c3, at[0A, 10, SMFb]; TT ← TOS or TT, GOTO[SMFc], c3, at[0B, 10, SMFb]; TT ← TOS or TT, GOTO[SMFc], c3, at[0C, 10, SMFb]; TT ← TOS or TT, GOTO[SMFc], c3, at[0D, 10, SMFb]; TT ← TOS or 60, GOTO[SMFc], {vacant} c3, at[0E, 10, SMFb]; TT ← TOS or TT, GOTO[SMFc], c3, at[0F, 10, SMFb]; {Now unscramble the real page. The high-order bit in bit 8 must be moved to bit 11 before rotating the whole real page into bits [3..15].} SMFc: [] ← TOS LRot0, XLDisp, {check ext adr bit} c1; TOS ← TOS and ~80, BRANCH[SMFe, SMFf, 1], c2; SMFe: GOTO[SMFg], c3; SMFf: TOS ← TOS or 10 {add ext adr bit}, GOTO[SMFg], c3; SMFg: Rx {old map flags} ← Rx and 7, c1; TOS ← TOS LRot8 {real page}, push, c2; STK ← Rx, push, L0Disp, c3; STK ← TOS, push, BRANCH[SMFd, GMFa], c1; SMFd: STK ← 0, c2; GOTO[SMd], c3; T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[0, 10, Misc0n]; {was ASSOC} T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[1, 10, Misc0n]; {was SETF} T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[0E, 10, Misc0n]; {was GETF} {The Dicentra has a different implementation of interval timer, input, and output} IfEqual[Config, 7,,SkipTo[DLionIO]]; {Dicentra implements RCLK differently} {Dicentra implements SETMP differently} T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[5, 10, Misc0n]; T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[6, 10, Misc0n]; SkipTo[AllConfigs1]; {******End of Dicentra specific IO******} DLionIO! @RCLK: {must read all three clock regs in single click} TOS ← uClockHigh, push, c1, at[9,10,Misc0n]; T ← RShift1 uClockBits, SE←0, push, c2; TT ← uClockLow, c3; TT ← TT + T, CarryBr, push, fZpop, c1; STK ← TT, IBDisp, PC ← PC + 1, BRANCH[RCLKnc, RCLKc], c2; RCLKnc: DISPNI[OpTable], c3; RCLKc: TOS ← TOS + 1, DISPNI[OpTable], c3; @SETMP: PC ← PC + PC16,{+PC16 at SLns} fXpop, push, c1, at[8,10,Misc0n]; TT ← uIOPage, c2; TT ← TT + MaintenancePanelOffset {was 41}, c3; rhTT ← cedarIOPageHigh, c1; Noop, c2; Noop, c3; MAR ← [rhTT,TT+0], push{popped at SLns}, GOTO[SLns], c1; @INPUT: PC ← PC + 1, Xbus ← TOS LRot0, XDisp, c1, at[5,10,Misc0n]; fXpop, push, Ybus ← 0, EtherDisp, DISP4[Input], c2; Input: TOS ← EIData, CANCELBR[MiscDone,3], c3, at[0,10,Input]; TOS ← EStatus, CANCELBR[MiscDone,3], c3, at[1,10,Input]; TOS ← KIData, CANCELBR[MiscDone,3], c3, at[2,10,Input]; TOS ← KStatus, CANCELBR[MiscDone,3], c3, at[3,10,Input]; KStrobe, CANCELBR[MiscDone,3], c3, at[4,10,Input]; TOS ← MStatus, CANCELBR[MiscDone,3], c3, at[5,10,Input]; TOS ← KTest, CANCELBR[MiscDone,3], c3, at[6,10,Input]; TOS ← IOPIData, CANCELBR[MiscDone,3], c3, at[8,10,Input]; TOS ← IOPStatus, CANCELBR[MiscDone,3], c3, at[9,10,Input]; BRANCH[Ether, NoEther, 1], c3, at[0A,10,Input]; Ether: TOS ← 1, GOTO[IBDispOnly], c1; NoEther: TOS ← 0, GOTO[IBDispOnly], c1; MiscDone: GOTO[IBDispOnly], c1; @OUTPUT: T ← STK, pop, c1, at[6,10,Misc0n]; PC ← PC + 1, Xbus ← TOS LRot0, XDisp, c2; TOS ← STK, pop, DISP4[Output], c3; Output: IOPOData ← T LRot0, GOTO[IBDispOnly], c1, at[0,10,Output]; IOPCtl ← T LRot0, GOTO[IBDispOnly], c1, at[1,10,Output]; KOData ← T LRot0, GOTO[IBDispOnly], c1, at[2,10,Output]; KCtl ← T LRot0, GOTO[IBDispOnly], c1, at[3,10,Output]; EOData ← T LRot0, GOTO[IBDispOnly], c1, at[4,10,Output]; EICtl ← T LRot0, GOTO[IBDispOnly], c1, at[5,10,Output]; DCtlFifo ← T, GOTO[IBDispOnly], c1, at[6,10,Output]; DCtl ← T LRot0, GOTO[IBDispOnly], c1, at[7,10,Output]; DBorder ← T, GOTO[IBDispOnly], c1, at[8,10,Output]; PCtl ← T LRot0, GOTO[IBDispOnly], c1, at[9,10,Output]; MCtl ← T, GOTO[IBDispOnly], c1, at[0A,10,Output]; EStrobe, GOTO[IBDispOnly], c1, at[0B,10,Output]; EOCtl ← T LRot0, GOTO[IBDispOnly], c1, at[0C,10,Output]; KCmd ← T LRot0, GOTO[IBDispOnly], c1, at[0D,10,Output]; POData ← T LRot0, GOTO[IBDispOnly], c1, at[0F,10,Output]; AllConfigs1! {******End of DLion specific IO******} T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[2,10,Misc0n]; {ReadRam} T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[3,10,Misc0n]; {LoadRam} T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[4,10,Misc0n]; T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[0A,10,Misc0n]; {RPRINTER} T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[0B,10,Misc0n]; {WPRINTER} {IfEqual[Config, 1, SkipTo[BandBlt], ]; ****Raven w/o BandBlt...(bj)****} T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[0C,10,Misc0n]; {BANDBLT} {BandBlt!} {*****HES***** changed TextBlt here} T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[0D,10,Misc0n]; {TEXTBLT} MiscF: T ← Rx + 377'b + 1, GOTO[UnimpOpcode], c1, at[0F,10,Misc0n]; {STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[1,10,MiscHigh];} { 20'b to 37'b => CedarFpt.mc} {Unimplemented Misc Groups} STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[2,10,MiscHigh]; { 40'b to 57'b} {STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[3,10,MiscHigh];} { 60'b to 77'b => CedarB1.mc} {STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[4,10,MiscHigh];} {100'b to 117'b => CedarB1.mc} STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[5,10,MiscHigh]; {120'b to 137'b} {STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[6,10,MiscHigh];} {140'b to 157'b => CedarB1.mc} IfEqual[Config, 7, SkipTo[AllConfigs2], ]; {Special Dicentra IO operations} STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[7,10,MiscHigh]; {160'b to 177'b => MiscDicentraB1.mc} STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[8,10,MiscHigh]; {200'b to 217'b} AllConfigs2! STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[9,10,MiscHigh]; STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[0A,10,MiscHigh]; STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[0B,10,MiscHigh]; STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[0C,10,MiscHigh]; STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[0D,10,MiscHigh]; STK ← TOS, pop, CANCELBR[MiscF, 0F], c3, at[0F,10,MiscHigh]; { WR - Write Register } {Timing - 2 clicks} @WR: Xbus←ib, PC ← PC + 1, push, XDisp, c1, opcode[374'b]; STK ← TOS, T ← 0FF, pop, DISP4[WR1], c2; WR0: uPSB ← TOS, GOTO[WRTail], c3, at[0,10,WR1]; WR1: uWDC ← TOS and T, GOTO[WRTail], c3, at[1,10,WR1]; WR2: uXTS ← TOS, GOTO[WRTail], c3, at[2,10,WR1]; WR3: UvMDS ← TOS, c3, at[3,10,WR1]; rhMDS ← UvMDS, c1; L ← UvL, c2; G ← UvG, c3; Map ← Q ← [rhMDS, L], c1; T ← Q and 0FF, c2; L ← rhL ← MD, c3; Map ← Q ← [rhMDS, G], c1; L ← L and ~0FF, c2; G ← rhG ← MD, c3; MAR ← G ← [rhG, Q+0], c1; L ← L or T, IBDisp, GOTO[SLTail], c2; WR8: uPTC ← TOS, GOTO[WRTail], c3, at[8,10,WR1]; WRTail: TOS ← STK, pop, GOTO[IBDispOnly], c1; { RR - Read Register } {Timing - 1 click} @RR: T←ib, push, XDisp, c1, opcode[375'b]; STK ← TOS, PC ← PC+1, IBDisp, push, fZpop, DISP4[RR1], c2; RR0: TOS ← uPSB, DISPNI[OpTable], c3, at[0,10,RR1]; RR1: TOS ← uWDC, DISPNI[OpTable], c3, at[1,10,RR1]; RR2: TOS ← uXTS, DISPNI[OpTable], c3, at[2,10,RR1]; RR3: TOS ← UTrapParm{XTP}, DISPNI[OpTable], c3, at[3,10,RR1]; RR6: TOS ← UvMDS, DISPNI[OpTable], c3, at[6,10,RR1]; RR8: TOS ← uPTC{PTC}, DISPNI[OpTable], c3, at[8,10,RR1]; { Unimplemented Opcodes } Unimplemented: T ← 75'b, GOTO[UnimpOpcode], c1, opcode[75'b]; T ← 174'b, GOTO[UnimpOpcode], c1, opcode[174'b]; T ← 175'b, GOTO[UnimpOpcode], c1, opcode[175'b]; T ← 176'b, GOTO[UnimpOpcode], c1, opcode[176'b]; T ← 177'b, GOTO[UnimpOpcode], c1, opcode[177'b]; T ← 271'b, GOTO[UnimpOpcode], c1, opcode[271'b]; T ← 272'b, GOTO[UnimpOpcode], c1, opcode[272'b]; T ← 273'b, GOTO[UnimpOpcode], c1, opcode[273'b]; T ← 274'b, GOTO[UnimpOpcode], c1, opcode[274'b]; T ← 275'b, GOTO[UnimpOpcode], c1, opcode[275'b]; T ← 276'b, GOTO[UnimpOpcode], c1, opcode[276'b]; T ← 277'b, GOTO[UnimpOpcode], c1, opcode[277'b]; T ← 355'b, GOTO[UnimpOpcode], c1, opcode[355'b]; @STOP: T ← 362'b, GOTO[UnimpOpcode], c1, opcode[362'b]; {STOP} T ← 366'b, GOTO[UnimpOpcode], c1, opcode[366'b]; {STARTIO} T ← 367'b, GOTO[UnimpOpcode], c1, opcode[367'b]; {JRAM} T ← 373'b, GOTO[UnimpOpcode], c1, opcode[373'b]; T ← 377'b, GOTO[UnimpOpcode], c1, opcode[377'b]; UnimpOpcode: uNcTrapOffset ← T, c2; T ← NcUnImplementedTrap, c3; UTrapParm ← T, c1; {noop} c2; T ← sNcCedarTrapTable, GOTO[TrapContinue], c3; {******************************************************************** Transfer locations in bank1 for assorted exits from Cedar code ********************************************************************} TrapContinue: {first part executed in Bank0} {CedarFptAll.UnImplementedFP, CommonSubs.Trapc2} L2 ← L2.NcCedarOpCodeTrap2, c1, at[B1TrapContinue]; TT ← UvPCpage, L1 ← 0, GOTO[StashPC0], c2; {FixedXfer.TrapGo} uPCValid ← 0, BRANCH[$, NcXferFaultStandIn], c3, at[L2.NcCedarOpCodeTrap2, 10, StashRets]; rhT ← xtTrap, c1; {FixedXfer.SDFetch} TT ← uSDAddr, L2 ← L2.NcCedarOpCodeTrap3, c2; TT ← TT + T, c3; Map ← Q ← [rhMDS, TT], CALL[XMDSRead] {this read does not fault}, c1; [] ← T, ZeroBr, CANCELBR[$, 0F], c1, at[L2.NcCedarOpCodeTrap3, 10, XMDSReadRets]; TT ← uNcTrapOffset, L2 ← L2.EFCHaveLink, BRANCH[NcSDFetchxStandIn, $], c2; {cedar opcode trap table not defined, so treat as unimplemented op} T ← sUnimplemented, c3; GOTO[SDFetch], c1; {FixedXfer.XferFault} NcXferFaultStandIn: Rx ← pFault, GOTO[SaveRegs], c1; {FixedXfer.SDFetchx} {avoids a conflict when assembled with Cedar 4.4 version of the microcode} NcSDFetchxStandIn: TT ← TT + T, c3; Map ← Q ← [rhMDS,TT], c1; L ← UvL, L0←L0.XMStartRead, CALL[XMDSReadx], c2; CedarFault: Noop, c1, at[B1CedarFault]; GOTO[Faultc3] {In CommonSubs.mc}, c2; {Arrive here via GOTOABS from Bank 0 LongBlkZ, WriteMBus, ReadMBus, WritePCBus, ReadPCBus, and Checksum in BlockB0.mc.} IntContinue: Rx ← pInt {for a YDisp}, GOTO[SaveRegs {Process}], c1, at[B1IntContinue]; {edit log Early changes to remove TextBlt and to move floating point to CeddarFpt. Sandman, April 23, 1981 8:46 AM: Fix Stack on Misc ~IN[0..15]. Frandeen, March 16, 1981 11:51 AM: Allow Block to catch Checksum Misc Sturgis 18-Jul-83 9:58:03: add Input[6] case (TOS ← KTest). Fiala 12-Jul-85 17:23:07: restore trap mi for 300'b to 317'b; restore trap for opcodes 271'b and 272'b (formerly test versions of AssignRef and AssignRefNew); change name from NewCedarMisc.mc to CedarMisc.mc. Fiala 18-Jul-85 10:58:53: Make all unimplemented opcodes use the Cedar trap table. Fiala 7-Aug-85 17:25:27: Absorb Bank 0 reentries from CedarB1. Fiala 17-Apr-86 10:22:44 Make Checksum opcode jump to code in Bank 0 (in CedarB0.mc). Fiala 22-Apr-86 13:08:18: Replace jaw-breaking long names for Cedar interrupt and trap entries. Fiala 30-Apr-86 17:19:29: Moved Checksum entry to CedarB1.mc BJackson 17-Nov-85 20:03:42: Turned off BandBlt for Raven version (Config = 1). Fiala 20-May-86 14:52:08: Added long format map opcodes and revised existing short format map opcodes to use new format. }