// DCP-Multibus.bcpl -- Multibus FSM Roms for Dicentra Central Processor
// Loaded with DCP-Proms.bcpl
// Last modified October 28, 1983  1:22 AM by Boggs

external Multibus

manifest [ high = 1; low = 0 ]

//-----------------------------------------------------------------------------------------
let Multibus(addr, data) be
//-----------------------------------------------------------------------------------------
[
manifest
   [
   // FSM states
   C1FH = 0
   C1SH = 1
   C2FH = 2
   C2SH = 3
   C3FH = 4
   C3SH = 5
   C1Wait = 6
   Ref2FH = 7
   Ref2SH = 8
   Read3FH = 9
   Read3SH = 10
   Write3FH = 11
   Write3SH = 12
   C1WFH = 13
   C1WSH = 14
   C2WFH = 15
   ]

structure Addr:
   [
   blank bit 7
   CurState bit 4
   IORef bit
   MapRef bit
   XACK bit		//low true
   InitTrap bit		//low true
   Master bit		//low true
   ]

structure Data:
   [
   NextState bit 4
   Cycle1 bit
   Cycle2 bit
   Cycle3 bit
   DoIt bit
   WriteMar bit
   WriteMDR bit
   BCLK bit
   WriteMD bit
   ReadMAx bit		//low true
   MBIdle bit
   blank bit 2
   IOCmd bit
   ClearCmd bit		//low true
   ReadCmd bit
   WriteCmd bit
   ClearAD bit
   ReadMar bit		//low true
   ReadMap bit		//low true
   ReadMDR bit		//low true
   blank bit 8
   ]

let CurrentState = addr<<Addr.CurState
let IORef = addr<<Addr.IORef eq high
let MapRef = addr<<Addr.MapRef eq high
let XACK = addr<<Addr.XACK eq low
let InitTrap = addr<<Addr.InitTrap eq low
let Master = addr<<Addr.Master eq low

let NextState = nil
let Cycle1, Cycle2, Cycle3, DoIt = false, false, false, false
let WriteMar, WriteMDR, BCLK, WriteMD = false, false, nil, false
let ReadMAx, MBIdle = false, false
let IOCmd, ReadCmd, WriteCmd, ClearCmd = false, false, false, false
let ReadMar, ReadMap, ReadMDR, ClearAD = false, false, false, false

if InitTrap & CurrentState ne C1FH then CurrentState = C1Wait

switchon CurrentState into
   [
   case C1FH:
      [
      Cycle1 = true
      ClearAD = true
      BCLK = low
      test InitTrap
         ifso
            [
            DoIt = true
            NextState = C1Wait
            ]
         ifnot test IORef % MapRef
            ifnot
               [
               DoIt = true
               NextState = C1SH
               ]
            ifso test Master
               ifso
                  [
                  WriteMar = true
                  DoIt = true
                  NextState = C1SH
                  ]
               ifnot NextState = C1Wait
      endcase
      ]
   case C1Wait:
      [
      Cycle1 = true
      BCLK = high
      ClearCmd = true
      NextState = C1FH
      endcase
      ]
   case C1SH:
      [
      Cycle2 = true
      test IORef % MapRef
         ifnot
            [
            ClearAD = true
            BCLK = high
            NextState = C2FH
            ]
         ifso
            [
            BCLK = low
            IOCmd = IORef & not MapRef
            test MapRef & not IORef
               ifso ReadMap = true
               ifnot ReadMar = true
            ReadMAx = true
            NextState = Ref2FH
            ]
      endcase
      ]

   case Ref2FH:
      [
      Cycle2 = true
      BCLK = low
      test IORef & MapRef
         ifnot ReadCmd = true
         ifso WriteMDR = true
      ReadMAx = true
      DoIt = true
      NextState = Ref2SH
      endcase
      ]
   case Ref2SH:
      [
      Cycle3 = true
      BCLK = low
      ReadMAx = true
      test IORef & MapRef
         ifnot NextState = Read3FH
         ifso
            [
            ReadMDR = true
            NextState = Write3FH
            ]
      endcase
      ]

   case Read3FH:
      [
      Cycle3 = true
      BCLK = low
      WriteMD = true
      ReadMAx = true
      test XACK
         ifnot NextState = Read3FH
         ifso
            [
            DoIt = true
            NextState = Read3SH
            ]
      endcase
      ]
   case Read3SH:
      [
      Cycle1 = true
      BCLK = high
      ReadMAx = true
      ClearCmd = true
      NextState = C1FH
      endcase
      ]

   case Write3FH:
      [
      Cycle3 = true
      BCLK = low
      WriteMD = true
      ReadMAx = true
      unless IORef & MapRef do WriteCmd = true
      DoIt = true
      NextState = Write3SH
      endcase
      ]
   case Write3SH:
      [
      Cycle1 = true
      ReadMAx = true
      if IORef & MapRef then XACK = true
      test XACK
         ifnot
            [
            BCLK = low
            NextState = C1WFH
            ]
         ifso
            [
            ClearCmd = true
            BCLK = high
            NextState = C1FH
            ]
      endcase
      ]

   case C1WFH:
      [
      Cycle1 = true
      ReadMAx = true
      BCLK = low
      test XACK
         ifnot test IORef % MapRef
            ifnot
               [
               DoIt = true
               NextState = C1WSH
               ]
            ifso NextState = C1WFH
         ifso
            [
            ClearCmd = true
            test IORef % MapRef
               ifso
                  [
                  BCLK = high
                  NextState = C1FH
                  ]
               ifnot
                  [
                  DoIt = true
                  NextState = C1SH
                  ]
            ]
      endcase
      ]
   case C1WSH:
      [
      Cycle2 = true
      ReadMAx = true
      test XACK
         ifso
            [
            BCLK = high
            ClearCmd = true
            NextState = C2FH
            ]
         ifnot
            [
            BCLK = low
            NextState = C2WFH
            ]
      endcase
      ]
   case C2WFH:
      [
      Cycle2 = true
      ReadMAx = true
      BCLK = low
      test XACK
         ifso
            [
            DoIt = true
            ClearCmd = true
            NextState = C2SH
            ]
         ifnot NextState = C2WFH
      endcase
      ]

   case C2FH:
      [
      DoIt = true
      Cycle2 = true
      ClearAD = true
      BCLK = low
      NextState = C2SH
      endcase
      ]
   case C2SH:
      [
      Cycle3 = true
      MBIdle = true
      ClearAD = true
      BCLK = high
      NextState = C3FH
      endcase
      ]
   case C3FH:
      [
      DoIt = true
      Cycle3 = true
      BCLK = low
      NextState = C3SH
      endcase
      ]
   case C3SH:
      [
      Cycle1 = true
      BCLK = high
      NextState = C1FH
      endcase
      ]
   ]

data>>Data.NextState = high? NextState, not NextState
data>>Data.Cycle1 = Cycle1? high, low
data>>Data.Cycle2 = Cycle2? high, low
data>>Data.Cycle3 = Cycle3? high, low
data>>Data.DoIt = DoIt? high, low
data>>Data.WriteMar = WriteMar? high, low
data>>Data.WriteMDR = WriteMDR? high, low
data>>Data.BCLK = BCLK
data>>Data.WriteMD = WriteMD? high, low
data>>Data.ReadMAx = ReadMAx? low, high
data>>Data.MBIdle = MBIdle? high, low
data>>Data.IOCmd = IOCmd? high, low
data>>Data.ClearCmd = ClearCmd? low, high
data>>Data.ReadCmd = ReadCmd? high, low
data>>Data.WriteCmd = WriteCmd? high, low
data>>Data.ClearAD = ClearAD? high, low
data>>Data.ReadMar = ReadMar? low, high
data>>Data.ReadMap = ReadMap? low, high
data>>Data.ReadMDR = ReadMDR? low, high
]