// GateConDebug.bcpl - a simple remote debugger

// Last modified March 6, 1979  10:43 PM by Boggs

get "Pup0.decl"
get "Pup1.decl"
get "GateConServ.decl"

external
[
//outgoing procedures
Debugger

//incoming procedures
Gets; PutTemplate; Puts; Ws; Confirm
OpenLevel1Socket; CloseLevel1Socket
GetBuf; ReleasePBI; SendCommand

//incoming statics
dsp; keys
]

//----------------------------------------------------------------------------
let Debugger() be
//----------------------------------------------------------------------------
[
let printMode = 1
let address = 0
let number = 0
let contents = 0
let cellOpen = false
let gotNumber = false
let soc = vec lenPupSoc; OpenLevel1Socket(soc)
Ws("*NDebugger*N")
   [
   gotNumber = false
   let char = nil
   number = 0
      [
      char = Gets(keys)
      test char ge $0 & char le $7
         ifso
            [
            number = number lshift 3 + (char-$0)
            Puts(dsp, char)
            gotNumber = true
            ]
         ifnot
            [
            if char eq $. & not gotNumber then
               [
               Puts(dsp, $.)
               number = address
               gotNumber = true
               char = Gets(keys)
               ]
            break
            ]
      ] repeat
   switchon char into
      [
      case $*033:  //escape
         [
         if gotNumber then [ Ws("?*N"); endcase ]
         Puts(dsp, $$)
         switchon Gets(keys) into
            [
            case $=:  //octal
               [ printMode = 1; endcase ]
            case $←:  //bytes
               [ printMode = 2; endcase ]
            default: Ws("?*N")
            ]
         endcase
         ]
      case $←:
         [ Ws(" ←"); Print(contents, 2); endcase ]
      case $=:
         [ Ws(" ="); Print(contents, 1); endcase ]
      case $/:
         [
         Ws("/ ")
         address = gotNumber ? number, contents
         contents = Examine(soc, address, printMode)
         cellOpen = true
         endcase
         ]
      case $*N:
         [
         if gotNumber then
            test cellOpen
               ifso Deposit(soc, address, number)
               ifnot Puts(dsp, $?)
         cellOpen = false
         Puts(dsp, $*N)
         endcase
         ]
      case $*L:
         [
         if gotNumber then
            test cellOpen
               ifso Deposit(soc, address, number)
               ifnot [ Ws("?*N"); endcase ]
         address = address+1
         PutTemplate(dsp, "*N$5O/ ", address)
         contents = Examine(soc, address, printMode)
         cellOpen = true
         endcase
         ]
      case $↑:
         [
         if gotNumber then
            test cellOpen
               ifso Deposit(soc, address, number)
               ifnot [ Ws("?*N"); endcase ]
         address = address-1
         PutTemplate(dsp, "↑*N$5O/ ",address)
         contents = Examine(soc, address, printMode)
         cellOpen = true
         endcase
         ]
      case $*177:
         [
         Ws(" XXX ")
         endcase
         ]
      case $Q: case $q:
         [ if Confirm("*NQuit Debugger") break ]
      default:
         [ Ws(" ? "); endcase ]
      ]
   ] repeat
CloseLevel1Socket(soc)
]

//----------------------------------------------------------------------------
and Print(value, mode) be
//----------------------------------------------------------------------------
[
switchon mode into
   [
   case 1:
      [ PutTemplate(dsp, " $6UO ", value); endcase ]
   case 2:
      [
      PutTemplate(dsp, " $3O $3O ", value rshift 8, value & #377)
      endcase
      ]
   ]
]


//----------------------------------------------------------------------------
and Examine(soc, address, mode) = valof
//----------------------------------------------------------------------------
[
let pbi = GetBuf(soc)
pbi>>PBI.pup.words↑1 = address
pbi>>PBI.pup.words↑2 = 1
pbi = SendCommand(pbi, ptExamine, pupOvBytes + 4)
if pbi then
   [
   let value = pbi>>PBI.pup.words↑3
   ReleasePBI(pbi)
   Print(value, mode)
   resultis value
   ]
]


//----------------------------------------------------------------------------
and Deposit(soc, address, value) be
//----------------------------------------------------------------------------
[
let pbi = GetBuf(soc)
pbi>>PBI.pup.words↑1 = address
pbi>>PBI.pup.words↑2 = 1
pbi>>PBI.pup.words↑3 = value
pbi = SendCommand(pbi, ptDeposit, pupOvBytes + 6)
if pbi then ReleasePBI(pbi)
]