// DisplayIOSubrs.bcpl - Subrs which deal with display
// Last change May 12, 1981 12:47 AM by Beau Sheil
// Last change March 1, 1981 8:56 PM by Beau Sheil
// Trill change February 24, 1981 1:58 PM by Beau Sheil
// Last change February 3, 1981 4:03 PM by Beau Sheil
// More XBitBlt changes January 28, 1981 6:14 PM by Beau Sheil
// XBitBlt change December 16, 1980 10:04 AM by Alan Bell
get "AltoDefs.d"
get "LispBcpl.decl"
get "KbdDefs.d"
get "Streams.d"
external [ // procedures defined here
Wc; Ws; DSPBOUT; FlashScreen; SETSCREENCOLOR; SHOWDISPLAY
SetScreenColor; BcplDisplay; StealFromBcplDisplay; AddToBcplDisplay
// statics defined here
@dlispDsp; @DisplayAddrHi; @dspStartAddr; @dspArea
@DLispDCB; @dspScanLines
]
external [ // procedures used
CallSwat; RAIDCode; Zero; CreateDisplayStream; ShowDisplayStream
Dismiss; LockPages; UnlockPages
SmallUnbox; EqNIL; MkSmallPosSubrRes; Version
Puts; Closes; CharWidth; EraseBits; GetBitPos; GetLmarg
]
external [ // statics used
dsp; sysFont; EmulatorSpace; @RMSK; VMDisplay
]
static [
@dlispDsp; @DisplayAddrHi=0; DisplayPages=0; @dspStartAddr; @DLispDCB
@dspArea; @dspScanLines
]
structure EDCB: [ // Extended DCB
@DCB = [ blank bit offset DCB.height
LongPtrFlg bit 1 // Overlaid on DCB.height
nScanLines bit 15
]
AddrLo word // to be D0 compatible
AddrHi word
]
// The following hack allows us to fetch the number of lines from a display
// stream. The complete declaration from which this is cribbed is in the OS
// source file DspStreamsB.bcpl
structure DispStrm [ blank word 29; nl word ]
manifest [ sourceGray = 3
LongDCBSeal = #177423 // checked by display ucode
]
let Ws(str) be for i = 1 to str>>String.length do Puts(dsp,str>>String.char↑i)
and Wc(ch) be Puts(dsp,ch)
and DSPBOUT(lvByte) = valof
[
let char = SmallUnbox(lvByte)&RMSK
test char eq ERASECHARCODE // Is char an eraser?
ifnot Puts(dsp, char)
ifso unless GetBitPos(dsp) le GetLmarg(dsp)
do EraseBits(dsp, -CharWidth(sysFont, $A), 0)
resultis lvByte
]
and FlashScreen() be
[
SetScreenColor(true)
Dismiss(60) // 60 x 10msec = .6 secs
SetScreenColor(false)
]
and SETSCREENCOLOR(lvVal) = valof
[ // was in Lisp but Lisp shouldnt know where bcpl core is
SetScreenColor(not EqNIL(lvVal))
resultis lvVal
]
and SetScreenColor(flg) be
[
let AdrDCB = @displayListHead // change to black/white
while AdrDCB do // else end of DCB chain
[ AdrDCB>>DCB.background = flg; AdrDCB = AdrDCB>>DCB.next ]
]
and SHOWDISPLAY(lvBlk, lvRasterWidth) = valof
[
if EqNIL(lvBlk) then // give all the space to dsp
[ BcplDisplay(808) // this turns off Lisp Display
DisplayAddrHi = 0 // this records that
resultis lvBlk
]
DisplayAddrHi = lvBlk>>VA.vahi
// fix up dcb for DLispDisplay - other fields are OK already
DLispDCB>>EDCB.width = SmallUnbox(lvRasterWidth)
DLispDCB>>EDCB.LongPtrFlg = true
DLispDCB>>EDCB.bitmap = LongDCBSeal
DLispDCB>>EDCB.nScanLines = 404
DLispDCB>>EDCB.AddrHi = lvBlk>>VA.vahi
DLispDCB>>EDCB.AddrLo = lvBlk>>VA.valo
ShowDisplayStream(dlispDsp, DSalone)
resultis lvBlk
]
and BcplDisplay(nScanLines) be
[
// Turns on dsp, giving it nScanLines of display space. If it is running,
// the DLisp display is turned off, because we are about to show dsp alone.
if DisplayAddrHi then ShowDisplayStream(dlispDsp, DSdelete)
dspScanLines = nScanLines
let nlines = (nScanLines/(sysFont!-2)) - 1
if (dsp ne 0) & (dsp>>DispStrm.nl ne nlines) then
[ ShowDisplayStream(dsp, DSdelete); Closes(dsp); dsp=0 ]
if (dsp eq 0) & (nlines gr 0) then
[ dsp = CreateDisplayStream(nlines, dspStartAddr, dspArea, sysFont)
ShowDisplayStream(dsp, DSalone)
]
]
and AddToBcplDisplay(ptr, N, S) be
[
// Add N words and S scanlines to dspArea if ptr is at end of dspArea
if ptr eq (dspStartAddr + dspArea) then dspArea = dspArea + N
BcplDisplay(dspScanLines + S)
if DisplayAddrHi then ShowDisplayStream(dlispDsp, DSbelow, dsp)
if VMDisplay then ShowDisplayStream(VMDisplay, DSabove, dsp)
]
and StealFromBcplDisplay(N, S) = valof
[
// Take N words and S scanlines from dspArea, if dspArea is bigger than N
if N ge dspArea then CallSwat("Too greedy")
dspArea = dspArea - N
BcplDisplay(dspScanLines - S)
if DisplayAddrHi then ShowDisplayStream(dlispDsp, DSbelow, dsp)
if VMDisplay then ShowDisplayStream(VMDisplay, DSabove, dsp)
let ptr = dspStartAddr + dspArea
Zero(ptr, N)
resultis ptr
]