<> <> <> <> <> DIRECTORY Terminal, InterminalBackdoor, CKViewerTables, DoradoInputOutput USING [InputNoPE, Output, IOAddress], Basics, Process; CKViewerTablesImpl: CEDAR PROGRAM IMPORTS Basics, Process, Terminal, InterminalBackdoor, DoradoInputOutput EXPORTS CKViewerTables = BEGIN OPEN CKViewerTables, DIO: DoradoInputOutput; <> OutIOA: TYPE = DIO.IOAddress; --TIOA hardware address for output InIOA: TYPE = DIO.IOAddress; --TIOA hardware address for input statics: OutIOA = 377B; --TIOA=Statics for wakeup control nlcb: OutIOA = 376B; --next line control block, takes an NLCBData word hRam: OutIOA = 375B; --sync/blank RAM, takes an NLCBData word; needed to disable blanking aTable: OutIOA = 361B; --either address or data, depending on word sent to the table bTable: OutIOA = 365B; --either address or data, depending on word sent to the table cTable: OutIOA = 362B; --either address or data, depending on word sent to the table colorHi: InIOA = 360B; --MType.0..3, Green.0..7, Red.0..4 colorLo: InIOA = 361B; --Keyboard.0..3, Red.4..7, Blue.0..7 <> NLCBData: TYPE = MACHINE DEPENDENT RECORD [ address (0: 0..3): CARDINAL[0..17B], zeroes (0: 4..11): CARDINAL[0..0], data (0: 12..15): CARDINAL[0..17B] ]; tableModeAddr: CARDINAL[0..17B] = 5; --NLCB[5] _ ModeBits tableMode: CARDINAL[0..17B] = 13B; -- 24Bit, BByPass, A8B2 modes tableEnable: NLCBData = [address: tableModeAddr, zeroes: 0, data: tableMode]; --sets 24Bit, BByPass, A8B2 modes vcwAddr: CARDINAL[0..17B] = 0; --NLCB[0] _ 0; turn off VBlank and VSync vcwOff: CARDINAL[0..17B] = 0; vcwEnable: NLCBData = [address: vcwAddr, zeroes: 0, data: vcwOff]; wakeupsOff: CARDINAL[0..17B] = 3; --DHTShutUp,,DWTShutUp wakeupsOn: CARDINAL[0..17B] = 0; TAddress: TYPE = MACHINE DEPENDENT RECORD [ --all Tables output address format NotKeep (0: 0..0): [0..1], NotWrite (0: 1..1): [0..1], LoadAddr (0: 2..2): [0..1], zeroes (0: 3..4): [0..0], address (0: 5..15): CARDINAL[0..3777B] ]; TData: TYPE = MACHINE DEPENDENT RECORD [ --all Tables output data format NotKeep (0: 0..0): [0..1], NotWrite (0: 1..1): [0..1], LoadAddr (0: 2..2): [0..1], zeroes (0: 3..3): [0..0], data (0: 4..15): CARDINAL[0..7777B] ]; <> terminal: Terminal.Virtual ~ InterminalBackdoor.terminal; InitializeTest: PUBLIC PROC [] = TRUSTED { <> <> <> Terminal.TurnOffColorDisplay[terminal]; Process.Pause[Process.MsecToTicks[40]]; --wait at least 2 field times TakeTable[H]; --taking HRam kills HWindow, HBlank and HSync, ASYNCHRONOUSLY! Process.Pause[Process.MsecToTicks[1]]; --wait at least 2 line times for microcode to quiet DIO.Output[datum: LOOPHOLE[wakeupsOff], register: statics]; --Statics_DHTShutUp,,DWTShutUp DIO.Output[datum: LOOPHOLE[tableEnable], register: nlcb]; --NLCB _ scan control DIO.Output[datum: LOOPHOLE[vcwEnable], register: nlcb]; --NLCB _ VCW turn off everything ReleaseTable[H]; --let HWindow happen so CLCB_NLCB; keep microcode OFF Process.Pause[Process.MsecToTicks[1]]; --wait at least 10 line times TakeTable[H]; --taking HRam kills HBlank and HSync again DIO.Output[datum: LOOPHOLE[wakeupsOn], register: statics]; --don't really want wakeups; must kill DDCReset to get rid of VBlank !! }; FinalizeTest: PUBLIC PROC [] = { <> ReleaseAllTables[]; ReleaseTable[H]; --releasing HRam starts HBlank and HSync Terminal.TurnOnColorDisplay[terminal]; }; TakeTable: PUBLIC PROC [t: Table] = TRUSTED { <> ioa: OutIOA _ SelectTable[t]; tAdd: TAddress _ [NotKeep: 0, NotWrite: 1, LoadAddr: 0, zeroes: 0, address: 0]; DIO.Output[datum: LOOPHOLE[tAdd], register: ioa]; }; TakeAllTables: PUBLIC PROC [] = { <> TakeTable[A]; TakeTable[B]; TakeTable[C]; }; <<>> ReleaseTable: PUBLIC PROC [t: Table] = TRUSTED { <> ioa: OutIOA _ SelectTable[t]; tAdd: TAddress _ [NotKeep: 1, NotWrite: 1, LoadAddr: 0, zeroes: 0, address: 0]; DIO.Output[datum: LOOPHOLE[tAdd], register: ioa]; }; ReleaseAllTables: PUBLIC PROC [] = { <> ReleaseTable[A]; ReleaseTable[B]; ReleaseTable[C]; }; LoadTableAddress: PUBLIC PROC [t: Table, a: Address] = TRUSTED { --table address <> <> ioa: OutIOA _ SelectTable[t]; tAdd: TAddress _ [NotKeep: 0, NotWrite: 1, LoadAddr: 1, zeroes: 0, address: IF t=A THEN a*2 ELSE a]; DIO.Output[datum: LOOPHOLE[tAdd], register: ioa]; }; WriteTableData: PUBLIC PROC [t: Table, d: TableData] = TRUSTED { <> halfData: CARDINAL; -- 12 bits tData: TData; ioa: OutIOA _ SelectTable[t]; SELECT t FROM A => { halfData _ (d.red*400B --leftshift 8 -- + d.blue) MOD 10000B; -- 12 bits tData _ [NotKeep: 0, NotWrite: 0, LoadAddr: 0, zeroes: 0, data: halfData]; DIO.Output[datum: LOOPHOLE[tData], register: ioa]; --increments address to high half halfData _ (d.green*20B --leftshift 4 -- + (d.red/20B) -- rightshift 4--); tData.data _ halfData; DIO.Output[datum: LOOPHOLE[tData], register: ioa]; --increments address to next low half }; B => { -- eight bit blue data to B Table tData _ [NotKeep: 0, NotWrite: 0, LoadAddr: 0, zeroes: 0, data: d.blue]; DIO.Output[datum: LOOPHOLE[tData], register: ioa]; --increments address to next word }; C => {-- eight bit green data to C Table tData _ [NotKeep: 0, NotWrite: 0, LoadAddr: 0, zeroes: 0, data: d.green]; DIO.Output[datum: LOOPHOLE[tData], register: ioa]; --increments address to word }; ENDCASE => ERROR; }; ReadTables: PUBLIC PROC [] RETURNS [d: TableData] = TRUSTED { <> hiWord, lowWord: CARDINAL; lowWord _ DIO.InputNoPE[colorLo]; d.blue _ Basics.LowByte[lowWord]; --lower byte of word d.red _ (lowWord/256) MOD 16; --lower nibble hiWord _ DIO.InputNoPE[colorHi]; d.red _ (hiWord MOD 16)*16 + d.red; d.green _ Basics.LowByte[(hiWord/16)]; }; ClearTable: PUBLIC PROC [t: Table] = { <> tD: TableData _ [red:0,green:0,blue:0]; TakeTable[t]; LoadTableAddress[t,0]; FOR x: Address IN [0..GetSize[t]) DO WriteTableData[t, tD]; --all zero data ENDLOOP; ReleaseTable[t]; }; ClearAllTables: PUBLIC PROC [] = { <> ClearTable[A]; ClearTable[B]; ClearTable[C]; }; VerifyClearedTable: PUBLIC PROC [t: Table] RETURNS [ok: BOOLEAN, index: Address, d: TableData] = { <> TakeTable[t]; FOR x: Address IN [0..GetSize[t]) DO LoadTableAddress[t,x]; d _ ReadTables[]; IF d.red#0 OR d.green#0 OR d.blue#0 THEN { ReleaseTable[t]; RETURN [FALSE, x, d]; --for now }; ENDLOOP; ReleaseTable[t]; RETURN [TRUE, LAST[Address], [0,0,0]]; }; <<>> VerifyClearedTables: PUBLIC PROC [] RETURNS [ok: BOOLEAN, t: Table, index: Address, d: TableData]= { <> [ok, index] _ VerifyClearedTable[A]; IF NOT ok THEN RETURN[ok,A,index,d]; [ok, index] _ VerifyClearedTable[B]; IF NOT ok THEN RETURN[ok,B,index,d]; [ok, index] _ VerifyClearedTable[C]; IF NOT ok THEN RETURN[ok,C,index,d]; RETURN[TRUE, A, LAST[Address], [0,0,0]]; }; <<>> Compare: PUBLIC PROC [t: Table, a: Address, cd: TableData] RETURNS [ok: BOOLEAN, rd: TableData] = { <> IF a >= GetSize[t] THEN RETURN [FALSE, [377B,377B,377B]]; TakeTable[t]; LoadTableAddress[t,a]; rd _ ReadTables[]; IF cd=rd THEN ok_TRUE ELSE ok_FALSE; ReleaseTable[t]; }; SelectTable: PROC [t: Table] RETURNS [DIO.IOAddress] = { RETURN [ SELECT t FROM A => aTable, B => bTable, C => cTable, H => hRam, ENDCASE => ERROR ] }; GetSize: PUBLIC PROC [t: Table] RETURNS [Address] = { RETURN [ SELECT t FROM A => 1024, B => 256, C => 256, H => 1024, ENDCASE => ERROR ] }; IncAddress: PROC [t: Table] = { <> TakeTable[t]; }; END. <<>>