home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / debug / wadesrc.lbr / MONBREAK.AZM / MONBREAK.ASM
Assembly Source File  |  1988-06-19  |  16KB  |  1,013 lines

  1.     title    'Break/Trace/Display Module for Monitor'
  2. ;
  3. ;    Last Edited    85-04-27    Wagner
  4. ;
  5. ;    Copyright (c) 1984, 1985 by
  6. ;
  7. ;        Thomas Wagner
  8. ;        Patschkauer Weg 31
  9. ;        1000 Berlin 33
  10. ;        West Germany
  11. ;
  12. ;       Released to the public domain 1987
  13. ;
  14. ;
  15.     maclib    z80
  16.     maclib    monopt
  17. ;
  18.     public    break
  19. ;
  20.     public    display,disalt,disyvars
  21. ;
  22.     IF    hilo
  23.     public    dishighlow
  24.     ENDIF
  25. ;
  26.     public    initbreak,unbreak,dotrace
  27.     public    deletebk,definebk,addbk,resetbk,nresetbk
  28. ;
  29.     public    numbreaks,breaklist
  30.     public    regi,regiff,regbc,regpc,regsp,altbc,iffstr
  31. ;
  32.     extrn    initcio
  33.     extrn    resetrst
  34.     extrn    string
  35. ;
  36.     IF    extended
  37.     public    cbank
  38.     extrn    peek,poke,currbank,peekbuf,xltbank
  39.     ENDIF
  40. ;
  41.     extrn    goto
  42.     extrn    wrstr,wrchar,wrhex,wrword,space,space2,crlf,tkbint
  43.     extrn    mexpression
  44.     extrn    monitor,cmderr,stack
  45.     extrn    disasm,analop,jumpaddr,jumpmark
  46.     extrn    tracecount,trcallopt,tracejp,tracenl,traceexp,traceptr
  47.     extrn    bkexpbuf,protexpbuf
  48.     extrn    listaddr,restart,rstloc
  49.     extrn    variables
  50. ;
  51.     IF    hilo
  52.     extrn    lowval
  53.     ENDIF
  54. ;
  55.     cseg
  56. ;
  57. maxbreaks    equ    8
  58. ;
  59. ;
  60. ;    Display:
  61. ;
  62. ;123456789.123456789.123456789.123456789.
  63. ;F=76543210  A=xx BC=xxxx DE=xxxx HL=xxxx IX=xxxx PC=xxxx    instruction
  64. ;     IFF=x  I=xx IY=xxxx SP=xxxx (xxxx xxxx xxxx xxxx xxxx) LD    (IX+00),00
  65. ;F'=76543210 A'=xx BC'=xxxx DE'=xxxx HL'=xxxx M=xx
  66. ;
  67. ;F=76543210 A=xx BC=xxxx DE=xxxx PC=xxxx 12345678:   1234567890123456  .1234567
  68. ;IFF=x I=xx HL=xxxx IX=xxxx IY=xxxx SP=xxxx (xxxx xxxx)
  69. ;
  70. ;
  71. ;    disflags:    Display flag register
  72. ;
  73. disflags:
  74.     push    psw
  75.     call    disregnam
  76.     pop    psw
  77.     lxi    h,flagnames
  78.     mvi    b,8
  79. disfll:
  80.     rlc
  81.     push    psw
  82.     jrnc    disfloff
  83.     mov    a,m
  84.     jr    disflxx
  85. disfloff:
  86.     mvi    a,'.'
  87. disflxx:
  88.     call    wrchar
  89.     inx    h
  90.     pop    psw
  91.     djnz    disfll
  92.     jmp    space
  93. ;
  94. flagnames    db    'SZxHxPNC'
  95. ;
  96. ;
  97. ;
  98. ;    display:    display CPU state (primary regs only)
  99. ;
  100. display:
  101.     lxi    d,reg1nam
  102.     lda    regf
  103.     call    disflags        ; display flags
  104.     lxi    h,rega
  105.     call    dis8reg            ; display A
  106. ;
  107.     lxi    h,regbc
  108.     IF    symbolic
  109.     mvi    b,2
  110.     ELSE
  111.     mvi    b,3
  112.     ENDIF
  113. displ10:
  114.     call    dis16reg        ; display BC, DE, HL
  115.     djnz    displ10
  116.     IF    NOT symbolic
  117.     lxi    h,regix
  118.     call    dis16reg        ; IX
  119.     ENDIF
  120. ;
  121.     call    disregnam        ; 'PC='
  122.     IF    extended
  123.     lda    cbank
  124.     ENDIF
  125.     lhld    regpc
  126.     mvi    b,0
  127.     call    disasm            ; disassemble at PC
  128.     shld    newpc            ; save next PC
  129.     call    crlf
  130. ;
  131.     lxi    d,reg2nam
  132.     call    disregnam        ; 'IFF='
  133.     lda    regiff
  134.     ani    1
  135.     ori    30h
  136.     call    wrchar            ; display IFF
  137.     call    space
  138.     lxi    h,regi
  139.     call    dis8reg            ; display I
  140. ;
  141.     IF    symbolic
  142.     lxi    h,reghl
  143.     call    dis16reg
  144.     lxi    h,regix
  145.     call    dis16reg
  146.     call    dis16reg
  147. ;
  148.     ELSE
  149. ;
  150.     lxi    h,regiy
  151.     call    dis16reg        ; IY
  152.     ENDIF
  153. ;
  154.     call    disregnam        ; 'SP='
  155.     lhld    regsp
  156.     call    wrword            ; display SP
  157.     call    space
  158.     IF    extended
  159.     lda    cbank
  160.     call    peek
  161.     ENDIF
  162.     mvi    a,'('
  163.     call    wrchar
  164.     IF    symbolic
  165.     mvi    b,2
  166.     ELSE
  167.     mvi    b,5            ; display 5 words at bottom of stack
  168.     ENDIF
  169.     IF    extended
  170.     lxi    h,peekbuf
  171.     ENDIF
  172. displayl3:
  173.     mov    e,m
  174.     inx    h
  175.     mov    d,m
  176.     inx    h
  177.     xchg
  178.     call    wrword            ; display (SP)
  179.     xchg
  180.     dcr    b
  181.     jrz    displayend
  182.     call    space
  183.     jr    displayl3
  184. ;
  185. displayend:
  186.     mvi    a,')'
  187.     call    wrchar
  188.     jmp    crlf
  189. ;
  190.     IF    symbolic
  191. ;
  192. reg1nam    db    'F=A=BC=DE=PC='
  193. reg2nam:
  194. iffstr    db    'IFF=I=HL=IX=IY=SP='
  195. ;
  196.     ELSE
  197. ;
  198. reg1nam    db    'F= A=BC=DE=HL=IX=PC='
  199. reg2nam    db    '     '
  200. iffstr    db    'IFF= I=IY=SP='
  201. ;
  202.     ENDIF
  203. ;
  204. ;
  205. ;    disalt:        display alternate registers
  206. ;
  207. disalt:
  208.     lda    altaf
  209.     lxi    d,reganam
  210.     call    disflags
  211.     lxi    h,altaf+1
  212.     call    dis8reg            ; display A'
  213.     lxi    h,altbc
  214.     mvi    b,3
  215. disaltlp:
  216.     call    dis16reg        ; display BF', DE', HL'
  217.     djnz    disaltlp
  218.     IF    extended
  219.     lxi    h,cbank
  220.     call    dis8reg
  221.     ENDIF
  222.     jmp    crlf
  223. ;
  224. ;
  225. reganam    db    'F''=A''=BC''=DE''=HL''='
  226.     IF    extended
  227.     db    ' X='
  228.     ENDIF
  229. ;
  230. ;    disyvars:    display Y-variables
  231. ;
  232. disyvars:
  233.     lxi    h,variables
  234.     mvi    b,10
  235.     mvi    c,'0'
  236. disylp:
  237.     mvi    a,'Y'
  238.     call    wrchar
  239.     mov    a,c
  240.     call    wrchar
  241.     mvi    a,'='
  242.     call    wrchar
  243.     call    disword
  244.     call    space
  245.     inr    c
  246.     mov    a,c
  247.     cpi    '5'
  248.     cz    crlf
  249.     djnz    disylp
  250.     jmp    crlf
  251. ;
  252. ;
  253.     IF    hilo
  254. ;
  255. ;    dishighlow:    display High, Low and Max
  256. ;
  257. dishighlow:
  258.     lxi    d,hilostr
  259.     lxi    h,lowval
  260.     mvi    b,4
  261. dishilo10:
  262.     call    dis16reg
  263.     djnz    dishilo10
  264.     jmp    crlf
  265. ;
  266. hilostr    db    'Low=  High=  Max=  Top='
  267. ;
  268.     ENDIF
  269. ;
  270. dis8reg:
  271.     call    disregnam
  272.     mov    a,m
  273.     call    wrhex
  274.     jmp    space
  275. ;
  276. ;
  277. dis16reg:
  278.     call    disregnam
  279.     call    disword
  280.     jmp    space
  281. ;
  282. ;
  283. disword:
  284.     push    d
  285.     mov    e,m
  286.     inx    h
  287.     mov    d,m
  288.     inx    h
  289.     xchg
  290.     call    wrword
  291.     xchg
  292.     pop    d
  293.     ret
  294. ;
  295. ;
  296. disregnam:
  297.     ldax    d
  298.     inx    d
  299.     call    wrchar
  300.     cpi    '='
  301.     rz
  302.     jr    disregnam
  303. ;
  304. ;
  305. ;------------------------------------------------------------------------------
  306. ;
  307. ;
  308. ;    Breakpoint Entry
  309. ;
  310. ;
  311. break:
  312.     sspd    savsp            ; save stackpointer
  313.     lxi    sp,breakstack        ; register save area
  314.     push    psw            ; AF
  315.     ldai
  316.     push    psw            ; I & IFF
  317.     IF    disint
  318.     DI
  319.     ENDIF
  320.     pushiy
  321.     pushix
  322.     push    h            ; dummy (AF)
  323.     push    h            ; dummy (SP)
  324.     push    h            ; HL
  325.     push    d
  326.     push    b
  327. ;
  328.     exaf
  329.     push    psw            ; AF'
  330.     exx
  331.     push    h            ; dummy (no SP')
  332.     push    h            ; HL'
  333.     push    d            ; DE'
  334.     push    b            ; BC'
  335.     exx
  336.     exaf                ; back to old register set
  337.     lxi    sp,stack        ; local stack
  338. ;
  339.     xra    a
  340.     sta    regiff            ; so peek does not enable interrupts
  341.     IF    extended
  342.     call    currbank
  343.     sta    cbank
  344.     ENDIF
  345.     lhld    savsp            ; stackpointer on entry
  346.     IF    extended
  347.     call    peek
  348.     lxi    h,peekbuf
  349.     ENDIF
  350.     mov    e,m
  351.     inx    h
  352.     mov    d,m            ; location at stackpointer = retaddr
  353.     lhld    savsp
  354.     inx    h
  355.     inx    h            ; point before retaddr on stack
  356.     xchg                ; retaddr into HL
  357.     dcx    h            ; address at RST
  358.     IF    extended
  359.     lda    cbank
  360.     call    peek
  361.     lda    peekbuf
  362.     ELSE
  363.     mov    a,m
  364.     ENDIF
  365.     push    h
  366.     lxi    h,restart
  367.     cmp    m            ; is it RST ?
  368.     pop    h
  369.     jrnz    break15            ; leave pc as is if not
  370.     lda    breaklist
  371.     mov    b,a
  372.     push    d
  373.     IF    extended
  374.     lda    cbank
  375.     call    xltbank
  376.     ENDIF
  377.     call    searchbk        ; is it a breakpoint ?
  378.     pop    d
  379.     jrz    break20            ; then reset PC to RST
  380. break15:
  381.     inx    h            ; else leave PC as it is
  382. break20:
  383.     xchg
  384.     shld    regsp            ; store corrected SP
  385.     lhld    regpc            ; this contains I & IFF
  386.     sded    regpc            ; set corrected PC
  387.     sded    listaddr        ; new default list address
  388.     shld    regiff            ; store iff elsewhere
  389.     lhld    savaf
  390.     shld    regaf            ; store AF at correct place
  391. ;
  392.     lda    regiff
  393.     rrc
  394.     rrc
  395.     ani    1
  396.     push    psw
  397.     xra    a
  398.     sta    regiff
  399.     call    resetbk            ; reset breakpoints
  400.     pop    psw
  401.     sta    regiff            ; shift P/V-Flag for IFF
  402.     IF    disint
  403.     jrz    break80            ; exit if interrupts disabled
  404.     ei                ; else re-enable
  405.     ENDIF
  406. ;
  407. break80:
  408.     call    initcio
  409.     lhld    regpc            ; current PC
  410.     lda    numbreaks
  411.     mov    b,a
  412. ;
  413.     IF    zeroboot
  414.     mov    a,h
  415.     ora    l
  416.     jz    breakwarm        ; jump if warmboot
  417.     ENDIF
  418. ;
  419.     IF    extended
  420.     lda    cbank
  421.     call    xltbank
  422.     ENDIF
  423.     call    searchbk        ; is this a normal breakpoint ?
  424.     jrnz    breaktr            ; check trace if not
  425.     ldy    a,3            ; conditional break ?
  426.     ani    80h
  427.     jz    breakexit        ; exit if not conditional
  428.     lxix    bkexpbuf
  429.     call    mexpression        ; evaluate condition
  430.     jc    breakexit        ; exit if bad
  431.     mov    a,h
  432.     ora    l
  433.     jnz    breakexit        ; exit if condition met
  434.     lhld    tracecount
  435.     mov    a,h
  436.     ora    l
  437.     jrnz    breaktr            ; go trace if condition false
  438.     call    tkbint
  439.     jrnz    breakexit
  440.     jmp    gounbreak        ; continue if condition not met
  441. ;
  442. ;
  443. breaktr:
  444.     lhld    tracecount        ; are we tracing ?
  445.     mov    a,h
  446.     ora    l
  447.     jrnz    breaktr10        ; then check trace conditions
  448.     lda    temptrace
  449.     ora    a
  450.     jnz    gounbreak        ; go if temporary trace
  451.     jr    breakexit
  452. ;
  453. breaktr10:
  454.     lda    tracejp            ; jumps only ?
  455.     ora    a
  456.     jrz    breaktr20        ; next if not
  457.     lhld    regpc
  458.     IF    extended
  459.     lda    cbank
  460.     ENDIF
  461.     call    analop            ; analyse opcode
  462.     lda    jumpmark        ; jump ?
  463.     ora    a
  464.     jrz    brkdotr            ; no list if no jump
  465. ;
  466. breaktr20:
  467.     lda    traceexp        ; while/until ?
  468.     ora    a
  469.     jrz    break85            ; continue if not
  470. ;
  471. ;    trace while/until
  472. ;
  473.     lixd    traceptr        ; load expression pointer
  474.     call    mexpression
  475.     jrc    breakexit        ; exit on error
  476.     lda    traceexp
  477.     rlc
  478.     jrc    breakuntil
  479.     mov    a,h
  480.     ora    l
  481.     jrz    breakexit        ; trace while: exit if false
  482.     jr    break85
  483. breakuntil:
  484.     mov    a,h
  485.     ora    l
  486.     jrnz    breakexit        ; trace until: exit if true
  487. ;
  488. break85:
  489.     lda    traceexp
  490.     ora    a
  491.     jrnz    break91            ; no decrease if expression
  492.     lhld    tracecount
  493.     dcx    h            ; else decrease count
  494.     shld    tracecount
  495.     mov    a,h
  496.     ora    l
  497.     jrz    breakexit        ; and exit if zero
  498. break91:
  499.     lda    tracenl            ; no list ?
  500.     ora    a
  501.     jrz    breakdis        ; go if no list
  502. brkdotr:
  503.     call    tkbint            ; check for int from keyboard
  504.     jrnz    breakexit
  505.     jmp    dotrace
  506. ;
  507. breakdis:
  508.     call    display            ; display if list on
  509.     jmp    dotrace            ; and continue tracing
  510. ;
  511.     IF    zeroboot
  512. breakwarm:
  513.     lxi    h,wbootmsg
  514.     call    wrstr
  515.     ENDIF
  516. ;
  517. breakexit:
  518.     call    display            ; display next opcode
  519.     jmp    monitor
  520. ;
  521.     IF    zeroboot
  522. wbootmsg    db    0dh,0ah,'WARM BOOT',0dh,0ah,0
  523.     ENDIF
  524. ;
  525. ;------------------------------------------------------------------------------
  526. ;
  527. ;    unbreak:    return from break
  528. ;
  529. ;
  530. gounbreak:
  531.     lda    numbreaks
  532.     mov    b,a
  533. unbreak:
  534.     xra    a
  535.     sta    temptrace
  536.     ora    b
  537.     jrz    untrace        ; go if no breakpoints
  538.     push    b
  539.     lhld    regpc
  540.     IF    extended
  541.     mvi    a,0ffh
  542.     call    xltbank
  543.     ENDIF
  544.     call    searchbk    ; break set at PC ?
  545.     pop    b
  546.     jrnz    untrace        ; ok if not
  547.     mvi    a,0ffh
  548.     sta    temptrace    ; mark temporary trace
  549.     jmp    normtrace    ; trace one op if break at PC
  550. ;
  551. ;
  552. ;    untrace:    return from break, tracing on
  553. ;
  554. ;        entry:    B = number of breakpoints (including temporary)
  555. ;
  556. untrace:
  557.     IF    disint
  558.     DI
  559.     ENDIF
  560.     lda    regiff
  561.     push    psw
  562.     xra    a
  563.     sta    regiff
  564.     call    setbk
  565.     pop    psw
  566.     sta    regiff
  567. ;
  568.     lxi    sp,altbc    ; restore registers
  569.     exx
  570.     pop    b
  571.     pop    d
  572.     pop    h
  573.     exx
  574.     pop    psw        ; i & iff
  575.     stai
  576.     exaf
  577.     pop    psw
  578.     exaf
  579.     pop    b
  580.     pop    d
  581.     pop    h
  582.     pop    psw        ; dummy (SP)
  583.     pop    psw        ; AF
  584.     popix
  585.     popiy
  586.     lxi    sp,string+80
  587.     jmp    goto        ; go to program
  588. ;
  589. ;
  590. ;------------------------------------------------------------------------------
  591. ;
  592. ;
  593. ;    setbk:        set breakpoints
  594. ;
  595. ;        entry:    B = number of breakpoints
  596. ;
  597. setbk:
  598.     lxix    breaklist+1
  599.     stx    b,-1
  600.     mov    a,b
  601.     ora    a
  602.     rz            ; ret if no breakpoints
  603.     mvi    c,5
  604.     lded    regpc
  605. setbkloop:
  606.     ldx    l,0
  607.     ldx    h,1
  608.     IF    extended
  609.     ldx    a,2
  610.     call    peek
  611.     lda    peekbuf
  612.     ELSE
  613.     mov    a,m
  614.     ENDIF
  615.     stx    a,4        ; save previous memory contents
  616.     IF    extended
  617.     lda    cbank
  618.     cmpx    2
  619.     jrz    setbklp4    ; check pc if same bank
  620.     ldx    a,2
  621.     inr    a        ; default bank ?
  622.     jrnz    setbklp5    ; branch if different bank
  623.     ENDIF
  624. setbklp4:
  625.     ora    a
  626.     IF    NOT extended
  627.     push    h
  628.     dsbc    d
  629.     pop    h
  630.     ELSE
  631.     dsbc    d
  632.     ENDIF
  633.     jrz    setbklp10    ; dont set break at current PC
  634. setbklp5:
  635.     lda    restart
  636.     IF    extended
  637.     sta    peekbuf
  638.     call    poke
  639.     ELSE
  640.     mov    m,a
  641.     ENDIF
  642. setbklp10:
  643.     mov    a,b
  644.     mvi    b,0
  645.     dadx    b
  646.     mov    b,a
  647.     djnz    setbkloop
  648.     ret
  649. ;
  650. ;
  651. ;    resetbk:    reset breakpoints and restart location
  652. ;    nresetbk:    reset breakpoints only
  653. ;
  654. resetbk:
  655.     call    resetrst
  656. nresetbk:
  657.     lxix    breaklist+1
  658.     ldx    b,-1
  659.     mov    a,b
  660.     ora    a
  661.     rz                ; ret if no breakpoints
  662.     lda    numbreaks
  663.     stx    a,-1            ; reset number of breakpoints
  664.     lxi    d,5
  665. resbkloop:
  666.     ldx    l,0
  667.     ldx    h,1
  668.     IF    extended
  669.     ldx    a,2
  670.     call    peek
  671.     lda    peekbuf
  672.     lxi    h,restart
  673.     cmp    m
  674.     ELSE
  675.     lda    restart
  676.     cmp    m
  677.     ENDIF
  678.     jrnz    resbk1
  679.     ldx    a,4
  680.     IF    extended
  681.     sta    peekbuf
  682.     call    poke
  683.     ELSE
  684.     mov    m,a
  685.     ENDIF
  686. resbk1:
  687.     dadx    d
  688.     djnz    resbkloop
  689.     ret
  690. ;
  691. ;
  692. ;------------------------------------------------------------------------------
  693. ;
  694. ;    dotrace:    execute one opcode, then break
  695. ;
  696. dotrace:
  697.     xra    a
  698.     sta    temptrace
  699.     lxix    protexpbuf        ; protection
  700.     call    mexpression
  701.     jrc    normtrace        ; ok if no protection
  702.     mov    a,h
  703.     ora    l
  704.     jrz    normtrace        ; ok if expression false
  705. ;
  706. ;    protected region, set break to return address
  707. ;
  708.     call    tratsp
  709.     lda    numbreaks
  710.     mov    b,a
  711.     mvi    a,0ffh            ; default bank
  712.     call    addbk            ; set as temp breakpoint
  713.     jmp    untrace
  714. ;
  715. ;    normal trace
  716. ;
  717. normtrace:
  718.     lhld    regpc
  719.     IF    extended
  720.     lda    cbank
  721.     ENDIF
  722.     call    analop
  723.     shld    newpc
  724.     lda    numbreaks        ; number of breakpoints
  725.     mov    b,a
  726.     lda    jumpmark
  727.     ora    a            ; jump/call/ret instruction ?
  728.     jrnz    dotrjump        ; then we have to set a different break
  729. dotr10:
  730.     lhld    newpc            ; next location
  731.     mvi    a,0ffh
  732.     call    addbk            ; set as temporary breakpoint
  733.     jmp    untrace            ; execute
  734. ;
  735. dotrjump:
  736.     ani    070h
  737.     cpi    20h
  738.     jrc    dotrjimm        ; 10 is immediate
  739.     jrnz    dotrjreg        ; 30 is to register
  740.     call    tratsp            ; 20 is to stack
  741. dotrj10:
  742.     mvi    a,0ffh
  743.     call    addbk            ; set as temp breakpoint
  744.     lda    jumpmark
  745.     ani    80h            ; conditional ?
  746.     jz    untrace            ; go exec if not
  747.     jr    dotr10            ; enter normal
  748. ;
  749. dotrjimm:
  750.     lhld    jumpaddr        ; immediate
  751.     lded    regpc            ; same as current PC ?
  752.     ora    a
  753.     dsbc    d
  754.     jrnz    dotrjimmok        ; ok if not same
  755.     IF    extended
  756.     lda    peekbuf            ; peekbuf contains current opcode
  757.     ELSE
  758.     ldax    d
  759.     ENDIF
  760.     cpi    10h            ; DJNZ ?
  761.     jnz    cmderr            ; abort if not
  762.     jr    dotr10            ; enter normal addr instead of jumpaddr
  763. ;
  764. dotrjimmok:
  765.     lhld    jumpaddr
  766.     lda    jumpmark
  767.     ani    1            ; call ?
  768.     jrz    dotrj10            ; ok if not
  769.     lda    trcallopt        ; trace over calls ?
  770.     ora    a
  771.     jrnz    dotr10            ; set normal break if yes
  772.     jr    dotrj10            ; else continue
  773. ;
  774. dotrjreg:
  775.     lda    jumpmark
  776.     ani    7
  777.     add    a
  778.     mov    e,a
  779.     mvi    d,0
  780.     lxi    h,regbc
  781.     dad    d
  782.     mov    e,m
  783.     inx    h
  784.     mov    d,m
  785.     xchg
  786.     jr    dotrj10
  787. ;
  788. ;
  789. tratsp:
  790.     lhld    regsp            ; get return address
  791.     IF    extended
  792.     lda    cbank
  793.     call    peek
  794.     lxi    h,peekbuf
  795.     ENDIF
  796.     mov    e,m
  797.     inx    h
  798.     mov    d,m
  799.     xchg
  800.     ret
  801. ;
  802. ;------------------------------------------------------------------------------
  803. ;
  804. ;    addbk:        add a breakpoint to the list if not already present
  805. ;
  806. ;        entry:    HL = breakpoint address
  807. ;            B  = current number of breakpoints
  808. ;            A  = breakpoint bank
  809. ;
  810. ;        exit:    B = B + 1
  811. ;
  812. addbk:
  813.     IF    extended
  814.     cpi    0ffh
  815.     jrnz    addbk1
  816.     call    xltbank
  817.     ENDIF
  818. addbk1:
  819.     call    searchbk
  820.     rz                ; no change if already defined
  821.     sty    l,0
  822.     sty    h,1
  823.     sty    a,2
  824.     mviy    0,3            ; clear condition flag
  825.     inr    b
  826.     ret
  827. ;
  828. ;
  829. ;    searchbk:    search for breakpoint
  830. ;
  831. ;        entry:    A/HL = address
  832. ;            B = number of breakpoints
  833. ;
  834. ;        exit:    zero-flag set if found
  835. ;            C = index if found
  836. ;            IY = breaklist pointer (end of list if not found)
  837. ;
  838. searchbk:
  839.     mov    d,a
  840.     mov    e,b
  841.     lxiy    breaklist+1
  842.     mov    a,b
  843.     ora    a
  844.     jrnz    searchbk10
  845.     dcr    a
  846.     mov    a,d
  847.     ret
  848. searchbk10:
  849.     mvi    c,0
  850. searchbk20:
  851.     ldy    a,0
  852.     cmp    l
  853.     jrnz    searchbk25    ; no match if not same address
  854.     ldy    a,1
  855.     sub    h
  856.     jrnz    searchbk25
  857.     IF    extended
  858.     ldy    a,2
  859.     cmp    d
  860.     jrnz    searchbk25    ; no match if not same bank
  861.     ENDIF
  862.     mov    b,e        ; match, return
  863.     mov    a,d
  864.     ret
  865. ;
  866. searchbk25:
  867.     push    d
  868.     lxi    d,5
  869.     dady    d
  870.     pop    d
  871.     inr    c
  872.     djnz    searchbk20
  873.     ori    0ffh
  874.     mov    b,e
  875.     mov    a,d
  876.     ret
  877. ;
  878. ;
  879. ;    delbk:        delete breakpoint
  880. ;
  881. ;        entry:    IY = pointer to breakpoint list element
  882. ;            C = index
  883. ;
  884. delbk:
  885.     lxi    h,numbreaks
  886.     dcr    m
  887.     mov    a,m
  888.     sta    breaklist
  889.     sub    c        ; elements after this element
  890.     rz            ; ready if nothing to move
  891.     mov    c,a
  892. delbklp:
  893.     mvi    b,5
  894. delbk10:
  895.     ldy    a,5
  896.     sty    a,0
  897.     inxiy
  898.     djnz    delbk10
  899.     dcr    c
  900.     jrnz    delbklp
  901.     ret
  902. ;
  903. ;
  904. ;    deletebk:    delete breakpoint
  905. ;
  906. ;        entry:    A/HL = address
  907. ;
  908. deletebk:
  909.     pushiy
  910.     push    psw
  911.     lda    numbreaks
  912.     mov    b,a
  913.     pop    psw
  914.     IF    extended
  915.     cpi    0ffh
  916.     cz    xltbank
  917.     ENDIF
  918.     call    searchbk
  919.     jnz    cmderr
  920.     call    delbk
  921.     popiy
  922.     ret
  923. ;
  924. ;
  925. ;    definebk:    add breakpoint
  926. ;
  927. ;
  928. definebk:
  929.     push    b
  930.     lbcd    numbreaks-1        ; get numbreaks into B
  931.     call    addbk
  932.     mvi    a,maxbreaks
  933.     cmp    b
  934.     jc    cmderr
  935.     mov    a,b
  936.     pop    b
  937.     sty    c,3            ; set condition flag
  938.     sta    numbreaks
  939.     sta    breaklist
  940.     ret
  941. ;
  942. ;
  943. ;    initbreak:    init module variables
  944. ;
  945. initbreak:
  946.     lxi    h,vars
  947.     lxi    d,vars+1
  948.     lxi    b,varspace-1
  949.     mvi    m,0
  950.     ldir                ; clear registers & breakpoints
  951.     IF    extended
  952.     call    currbank
  953.     sta    cbank            ; init current bank
  954.     ENDIF
  955.     ldai
  956.     sta    regi            ; init I-reg
  957.     rpo                ; leave IFF = 0 if interrupts disabled
  958.     mvi    a,1
  959.     sta    regiff            ; init IFF
  960.     ret
  961. ;
  962. ;
  963.     dseg
  964. ;
  965. vars:
  966. ;
  967. altbc    ds    2
  968. altde    ds    2
  969. althl    ds    2
  970. regiff    ds    2        ; no alternate SP
  971. regi    equ    regiff+1
  972. altaf    ds    2
  973. ;
  974. regbc    ds    2
  975. regde    ds    2
  976. reghl    ds    2
  977. regsp    ds    2
  978. regaf    ds    2
  979. regf    equ    regaf
  980. rega    equ    regaf+1
  981. regix    ds    2
  982. regiy    ds    2
  983. regpc    ds    2
  984. ;
  985. savaf    ds    2
  986. breakstack    equ    $
  987. ;
  988. savsp    ds    2
  989. retloc    ds    2
  990. newpc    ds    2
  991. ;
  992.     IF    extended
  993. cbank        ds    1
  994.     ENDIF
  995. ;
  996. temptrace    ds    1
  997. numbreaks    ds    1
  998. breaklist    ds    (maxbreaks+2)*5+1
  999. ;
  1000. ; Break list format:
  1001. ;
  1002. ;    db    number of active entries
  1003. ; each entry:
  1004. ;    dw    address
  1005. ;    db    bank    (unused for non-extended version)
  1006. ;    db    condition-flag
  1007. ;    db    storage for original contents of location
  1008. ;
  1009. varspace    equ    $-vars
  1010. ;
  1011.     end
  1012. 
  1013.