//D0brkp.bcpl stuff associated with breakpoints
// Last edited: 2 January 1980
//Normal bp's are indicated in the IM word by MicroD (DVec!3[0:1]);
//Midas will make an ordinary entry in BPtable for instructions assembled
//this way, and also indicate the bp in VM tables so that Dump will
//work correctly without having to scan BPtable before writing each m-i.
//These bp's can be removed by the programmer from Midas singly, but
//the ClrBP action only removes bp's added after the Load.
//When Midas is in control, IM contains the unbreakpointed instructions,
//and bp addresses are remembered in a table. Just before the
//processor is started, m-i's at bp addresses are read and saved
//in the table, and breakpoint m-i's (BreakPoint, FreezeResult, Goto[.])
//are inserted in their places.
//SS is implemented by planting bp(s) at the successor(s) to the m-i
//being single-stepped. BP indices are used for this.
//It is illegal to continue if the m-i which contained a bp, or through
//which a SS occurred, contains a LoadPage.
get "mcommon.d"
get "d0.d"
manifest [ get "d0regmem.d" ]
external [
// OS
Puts
// MASM
@WssCSS; Wns; PutsCSS
// MSYM
SearchBlocks
// MMPRGN
UpdateMPDValues
// MCMD
ErrorAbort; WnsCSSD; CmdCommentStream; CmdCS1
// D0I0
BPTable
// D0ASM
stNotInVM; stNotIMA
// D0GO
AddBp; PrCCV; BreakAddr
// D0VM
LookUpAA; LookUpVA; ChangeVMBrkp; @VirtualP
// Defined here
BreakIML; ClrBp; ShowBP
]
//AVec is 0 to default the break address (to BreakAddr).
//BPflag is true to insert a break, false to remove one
//Called from InsertBreak and RemoveBreak in MBRKP.BCPL.
let BreakIML(AVec,MemX,BPflag,String) be
[ let BPindex = nil
let T = vec 2
let AA,VA = nil,nil
if AVec eq 0 do
[ MemX,AVec = IMXx,T; AVec!0 = 0; AVec!1 = BreakAddr & #7777
]
switchon MemX into
[
default: ErrorAbort(stNotIMA)
case IMXx: AA = AVec!1
VA = LookUpVA(AA); endcase
case IMx: VA = AVec!1
AA = LookUpAA(VA)
if AA < 0 then ErrorAbort(stNotInVM)
endcase
]
BreakAddr = AA //So that UnBrk will default address
//to bp we just inserted (???)
test BPflag
ifso //insert breakpoint
switchon AddBp(AA) into
[ case -1: ChangeVMBrkp(VA,true); endcase
case 0: ErrorAbort("BP table full")
case 1: ErrorAbort("Already breakpointed")
]
ifnot //remove breakpoint
[ //verify instruction is breakpoint and get index
BPindex = 0
for I = BPmin to BPlen-1 do
[ if (BPTable>>BP↑I.Addr eq AA) & (BPTable>>BP↑I.InUse) do
[ BPindex = I; BPTable>>BP↑BPindex.w3 = #7777
ChangeVMBrkp(VA,false); break
]
]
if BPindex eq 0 then ErrorAbort("Instruction not breakpointed")
]
WssCSS(String); WssCSS(" break at "); PrCCV((lv AA)-1,IMXx)
UpdateMPDValues()
]
//Action to clear all the bp's or all added since the load
and ClrBp(All,nil,nil) be
[ let Count,BPVec,VA,AA = 0,vec 22,nil,nil
for I = BPmin to BPlen-1 do
[ if BPTable>>BP↑I.InUse & (BPTable>>BP↑I.Added % All) do
[ AA = BPTable>>BP↑I.Addr
VA = LookUpVA(AA)
ChangeVMBrkp(VA,false)
BPTable>>BP↑I.w3 = #7777
if Count < 11 do //Report first 7 BP's cleared to user
[ BPVec!(Count+Count) = AA; BPVec!(Count+Count+1) = VA
]
Count = Count+1
]
]
WssCSS("Cleared "); WnsCSSD(Count)
if Count ge 8 then PutsCSS($.)
WssCSS(" BP's")
if Count ne 0 do
[ PutsCSS($:)
let S = CmdCommentStream
let AVec = vec 1; AVec!0 = 0
for I = 0 to Count-1 do
[ if I ge 11 then return
test I eq 5
ifso S = CmdCS1
ifnot Puts(S,$ )
AVec!1 = BPVec!(I+I+1)
test VirtualP & (AVec!1 ge 0)
ifso SearchBlocks(S,IMx,AVec)
ifnot
[ if VirtualP then Puts(S,$a)
Wns(S,BPVec!(I+I),0,8)
]
]
]
]
//Action to show first 10 bp's added since the load
and ShowBP(nil,nil,nil) be
[ let Count,BPVec,VA,AA = 0,vec 24,nil,nil
for I = BPmin to BPlen-1 do
[ if BPTable>>BP↑I.InUse & BPTable>>BP↑I.Added do
[ AA = BPTable>>BP↑I.Addr
VA = LookUpVA(AA)
if Count < 12 do
[ BPVec!(Count+Count) = AA; BPVec!(Count+Count+1) = VA
]
Count = Count+1
]
]
test Count eq 0
ifso WssCSS("No BP's added since last Load")
ifnot
[ WssCSS("BP's at:")
let S = CmdCommentStream
let AVec = vec 1; AVec!0 = 0
for I = 0 to Count-1 do
[ if I > 12 then return
test I eq 6
ifso S = CmdCS1
ifnot Puts(S,$*S)
AVec!1 = BPVec!(I+I+1)
test VirtualP & (AVec!1 ge 0)
ifso SearchBlocks(S,IMx,AVec)
ifnot
[ if VirtualP then Puts(S,$a)
Wns(S,BPVec!(I+I),0,8)
]
]
]
]