// ResistDisplay.bcpl -- Display subroutines

// Last modified by McCreight June 25, 1984  10:42 AM

get "Resist.decl"
get "Streams.d"
get "AltoDefs.d"

external
[
// outgoing procedures
DisplaySingleOhms; DisplayIC; DisplayOhms; DisplayOhmsCode
ShowFullDisplay; FlashWindow
ResetLine; SetLinePos

// incoming procedures
DecodeOhms
SetBitPos; GetLmarg
SymbolsString; PinsNetString
Wss; Puts; Resets; PutTemplate
Zero; MoveBlock; DefaultArgs

// outgoing statics
statusDsp; singleDsp
dipDsp; lastShownDsp; lastIC; lastSingleOhms; bar1DCB; bar2DCB

// incoming statics
dsp
]

static
[
statusDsp; singleDsp
dipDsp; lastShownDsp; lastIC; lastSingleOhms; bar1DCB; bar2DCB
]


// ---------------------------------------------------------------------------
let DisplaySingleOhms(ohms) be
// ---------------------------------------------------------------------------
[
if ohms ne lastSingleOhms then
   [
   ResetLine(singleDsp)
   DisplayOhms(singleDsp, ohms)
   lastSingleOhms = ohms
   ]
]

// ---------------------------------------------------------------------------
and DisplayIC(ic, InTolerance) be
// ---------------------------------------------------------------------------
[
for pinNumber = 1 to ic>>IC.nPins do
   [
   let pin = lv ic>>IC.pins↑pinNumber
   let lastPin = lv lastIC>>IC.pins↑pinNumber
   unless pinNumber le lastIC>>IC.nPins & MultEq(pin, lastPin, lenPin) do
      DisplayPin(ic, pinNumber, (InTolerance(pin)? 0, 1))
   ]
for pinNumber = ic>>IC.nPins+1 to lastIC>>IC.nPins do
   [
   SetLinePos(dipDsp, pinNumber-1)
   dipDsp>>DS.cdcb>>DCB.background = 0
   ResetLine(dipDsp)
   Zero(lv lastIC>>IC.pins↑pinNumber, lenPin)
   ]
MoveBlock(lastIC, ic, lenIC + ic>>IC.nPins*lenPin)
]

// ---------------------------------------------------------------------------
and DisplayPin(ic, pinNumber, background) be
// ---------------------------------------------------------------------------
[
SetLinePos(dipDsp, pinNumber-1)
dipDsp>>DS.cdcb>>DCB.background = background
ResetLine(dipDsp)
PutTemplate(dipDsp, "$2D", pinNumber)
SetBitPos(dipDsp, 75)
let pin = lv ic>>IC.pins↑pinNumber
DisplayOhmsCode(dipDsp, pin>>Pin.expectedOhmsCode)
SetBitPos(dipDsp, 150)
DisplayOhmsCode(dipDsp, pin>>Pin.measuredOhmsCode)
unless pin>>Pin.expectedOhmsCode eq unknownCode do
   [
   SetBitPos(dipDsp, 225)
   Wss(dipDsp, PinsNetString(pin))
   ]
]

// ---------------------------------------------------------------------------
and DisplayOhmsCode(stream, ohmsCode) be
// ---------------------------------------------------------------------------
   DisplayOhms(stream, DecodeOhms(ohmsCode))

// ---------------------------------------------------------------------------
and DisplayOhms(stream, ohms) be
// ---------------------------------------------------------------------------
   PutTemplate(stream, (selecton ohms into
      [
      case unknown: "  --"
      case open:    "Open"
      default:      "$4D"
      ]), ohms)

// ---------------------------------------------------------------------------
and ResetLine(ds) be
// ---------------------------------------------------------------------------
// Fast ResetLine -- the one in the OS is unbelievably slow!
[
let dcb = ds>>DS.cdcb
Zero(dcb>>DCB.bitmap, 2*(dcb>>DCB.height)*(dcb>>DCB.width))
SetBitPos(ds, GetLmarg(ds))
]

// ---------------------------------------------------------------------------
and SetLinePos(ds, line) be
// ---------------------------------------------------------------------------
// Local version of SetLinePos -- because the one in the OS refuses to
// work if the DCB.indentation is nonzero.
[
ds>>DS.cdcb = ds>>DS.fdcb + line*lDCB
SetBitPos(ds, GetLmarg(ds))
]

// ---------------------------------------------------------------------------
and ShowFullDisplay(flag) be bar1DCB>>DCB.next = flag? bar2DCB, 0
// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
and FlashWindow(ds) be
// ---------------------------------------------------------------------------
[
for i = 1 to 6 do
   [
   let dcb = ds>>DS.fdcb
      [
      dcb>>DCB.background = not dcb>>DCB.background
      if dcb eq ds>>DS.ldcb break
      dcb = dcb>>DCB.next
      ] repeat
   let time = @realTimeClock+3
   until @realTimeClock-time gr 0 do loop
   ]
]

// ---------------------------------------------------------------------------
and MultEq(a, b, length) = valof
// ---------------------------------------------------------------------------
[
for i = 0 to length-1 do if a!i ne b!i resultis false
resultis true
]