IOAddress Definitions
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
IOData definitions
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]
];
Procedures
terminal: Terminal.Virtual ~ InterminalBackdoor.terminal;
InitializeTest:
PUBLIC
PROC [] =
TRUSTED {
turn off display, turn off microcode wakeups
set table modes to tableEnable (above)
turn off vertical blanking by killing VCW, Wait one frame time to take effect,
turn off horizontal blanking by taking HRam.
ASSUMES FIFO's have zeroes because of glitch in ChannelOn in hardware
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𡤍HTShutUp,,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 [] = {
reenable Tables and HRam to give display back to microcode
ReleaseAllTables[];
ReleaseTable[H]; --releasing HRam starts HBlank and HSync
Terminal.TurnOnColorDisplay[terminal];
};
TakeTable:
PUBLIC
PROC [t: Table] =
TRUSTED {
does a dummy operation to capture the table data/address paths
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 [] = {
does a dummy operation to capture the table data/address paths
TakeTable[A];
TakeTable[B];
TakeTable[C];
};
ReleaseTable:
PUBLIC
PROC [t: Table] =
TRUSTED {
does a dummy operation to release the table data/address paths
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 [] = {
releases all tables
ReleaseTable[A];
ReleaseTable[B];
ReleaseTable[C];
};
LoadTableAddress:
PUBLIC
PROC [t: Table, a: Address] =
TRUSTED {
--table address
loads specified table with address; left shifts A address to simulate 1024X24 memory
A addresss should always be EVEN going out to hardware
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 {
writes data d at the current table address and increments that address
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 {
reads 24 bits of TableData from the currently addressed table(s)
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] = {
Clears the entire table to zeroes
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 [] = {
clears all tables to zero
ClearTable[A];
ClearTable[B];
ClearTable[C];
};
VerifyClearedTable:
PUBLIC
PROC [t: Table]
RETURNS [ok:
BOOLEAN, index: Address, d: TableData] = {
checks that entire table is zeroes
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]= {
checks all tables for all zeroes
[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] = {
checks t[a].rd = cd, returns OK=TRUE if TRUE and rgb TableData read
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] = {
increments the table address via a dummy operation
TakeTable[t];
};