home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / debug / wadesrc.lbr / MONIT.AZM / MONIT.ASM
Assembly Source File  |  1988-06-19  |  33KB  |  1,909 lines

  1.     title    'Monitor Main Module'
  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.     maclib    z80
  15.     maclib    monopt
  16. ;
  17.     public    monent,monmain,monitor,cmderr,eocmd
  18.     public    stack,listaddr,asmaddr,dumpaddr,variables
  19. ;
  20.     IF    hilo
  21.     public    highval,lowval,maxval,topval
  22.     ENDIF
  23.     IF    extended
  24.     public    listbnk,dumpbnk,asmbnk
  25.     ENDIF
  26. ;
  27.     public    tracecount,tracejp,tracenl,traceexp,traceptr,trcallopt
  28.     public    bkexpbuf,protexpbuf
  29.     public    prompt
  30. ;
  31.     extrn    initsystem
  32. ;
  33.     IF    symbolic
  34.     extrn    rdsymname,defsymbol,killsymbol,dissymbols,wrsymbol
  35.     extrn    symstart
  36.     IF    fileops
  37.     extrn    symtop,readsym,symwrite,rsvsym
  38.     extrn    sfile
  39.     ENDIF
  40.     ENDIF
  41. ;
  42.     extrn    wraddr,wrchar
  43. ;
  44.     IF    extended
  45.     extrn    xltbank,peek,peeks,poke,paddr,pbank,psaddr,psbank,peekbuf,cbank
  46.     ENDIF
  47. ;
  48.     extrn    wrhex,wrhexdig,wrword,space,space2,crlf,wrdec,wrbit,wrstr
  49.     extrn    readstring,expression,skipsep,bytestring,rdregister
  50.     extrn    mexpression,sexpression
  51.     extrn    getch,testch,isletter,isdigit,isspecial,iscontrol
  52.     extrn    string
  53. ;
  54.     extrn    userdef
  55.     extrn    disasm,assemble,analop
  56.     extrn    initbreak,display,disalt,disyvars,unbreak,dotrace
  57. ;
  58.     IF    hilo
  59.     extrn    dishighlow
  60.     ENDIF
  61. ;
  62.     IF    fileops
  63.     extrn    read,write,file,jmacro,killmac
  64.     ENDIF
  65. ;
  66.     extrn    deletebk,definebk,numbreaks,breaklist,addbk
  67. ;
  68.     extrn    regi,regiff,regbc,regpc,altbc
  69. ;
  70. ;
  71. ;    This is the main entry to the monitor.
  72. ;    Variables and registers are initialised, then INITSYSTEM is called
  73. ;    for system dependent initialisations.
  74. ;
  75. monent:
  76.     lxi    sp,stack
  77.     lxi    h,varstart
  78.     lxi    d,varstart+1
  79.     lxi    b,varspace-1
  80.     mvi    m,0
  81.     ldir            ; init all defaults and variables to 0
  82.     call    initbreak    ; init break-variables
  83.     call    initsystem    ; system dependent initialisation
  84.     call    crlf
  85. ;
  86. ;
  87. ;    MONITOR is the entry jumped to on a break.
  88. ;
  89. monitor:
  90.     IF    extended
  91.     mvi    a,0ffh
  92.     sta    listbnk
  93.     sta    dumpbnk
  94.     sta    asmbnk
  95.     ENDIF
  96. ;
  97. ;
  98. ;    MONMAIN is the main program loop.
  99. ;    It is also the entry jumped to by CMDERR
  100. ;
  101. monmain:
  102.     xra    a
  103.     sta    tracecount    ; in case trace was aborted in CRLF
  104.     lxi    sp,stack    ; re-init stack
  105. ;
  106.     call    resettmpbk
  107. ;
  108.     mvi    a,':'
  109. prompt    equ    $-1
  110.     call    wrchar        ; prompt
  111.     call    readstring    ; get command
  112.     call    getch
  113.     mvi    b,0ffh
  114.     jrnz    monmain1    ; ok if not empty
  115.     lda    dumpword
  116.     mov    b,a
  117.     lda    lastop        ; use last command as default
  118. monmain1:
  119.     sta    lastop        ; remember last command
  120.     lxi    h,dumpword
  121.     mov    m,b
  122. moncmd:
  123.     lxi    h,commands
  124.     call    tabsel        ; select routine
  125.     jr    monmain        ; loop
  126. ;
  127. ;
  128. tabsel:
  129.     call    isletter    ; letter ?
  130.     jrc    cmderr        ; no command if not
  131.     sui    'A'
  132.     add    a        ; *2
  133.     mov    e,a
  134.     mvi    d,0
  135.     lxi    h,commands
  136.     dad    d        ; point to command handler
  137.     mov    e,m
  138.     inx    h
  139.     mov    d,m        ; command handler address
  140.     xchg            ; into hl
  141.     call    skipsep        ; prepare access to next char
  142.     pchl            ; enter routine
  143. ;
  144. ;
  145. ;    eocmd:        check for end of command, abort if not at end
  146. ;
  147. eocmd:
  148.     push    psw
  149.     call    skipsep
  150.     jrnz    cmderr
  151.     pop    psw
  152.     ret
  153. ;
  154. ;
  155. ;    cmderr:        issue error message, go to main loop
  156. ;
  157. cmderr:
  158.     mvi    a,'?'        ; issue error message
  159.     call    wrchar
  160.     call    wrchar        ; write ??
  161.     call    crlf
  162.     IF    fileops
  163.     call    killmac
  164.     ENDIF
  165.     jr    monmain        ; loop
  166. ;
  167. ;
  168. ;    command handler table
  169. ;
  170. commands:
  171.     dw    asmop        ; A
  172.     dw    breakset    ; B
  173.     dw    calltrace    ; C
  174.     dw    dump        ; D
  175.     IF    fileops
  176.     dw    exec        ; E
  177.     dw    file        ; F
  178.     ELSE
  179.     dw    cmderr
  180.     dw    cmderr
  181.     ENDIF
  182.     dw    go        ; G
  183.     dw    hexcalc        ; H
  184.     dw    input        ; I
  185.     IF    fileops
  186.     dw    jmacro        ; J
  187.     dw    killmac        ; K
  188.     ELSE
  189.     dw    cmderr
  190.     dw    cmderr
  191.     ENDIF
  192.     dw    list        ; L
  193.     dw    move        ; M
  194.     IF    symbolic
  195.     dw    namedef        ; N
  196.     ELSE
  197.     dw    cmderr        ; N (undef)
  198.     ENDIF
  199.     dw    output        ; O
  200.     dw    protect        ; P
  201.     dw    query        ; Q
  202.     IF    fileops
  203.     dw    fread        ; R
  204.     ELSE
  205.     dw    cmderr
  206.     ENDIF
  207.     dw    substit        ; S
  208.     dw    trace        ; T
  209.     dw    userdef        ; U
  210.     dw    verify        ; V
  211.     IF    fileops
  212.     dw    fwrite        ; W
  213.     ELSE
  214.     dw    cmderr
  215.     ENDIF
  216.     dw    where        ; X
  217.     dw    yvar        ; Y
  218.     dw    zap        ; Z
  219. ;
  220. ;------------------------------------------------------------------------------
  221. ;
  222. ;    A:    Assemble
  223. ;
  224. asmop:
  225.     call    expression
  226.     jrnc    asmop10            ; ok if expression
  227.     call    eocmd
  228.     lhld    asmaddr            ; else use defaults
  229.     jr    asmloop
  230. ;
  231. asmop10:
  232.     IF    extended
  233.     sta    asmbnk
  234.     ENDIF
  235.     call    eocmd
  236. asmloop:
  237.     shld    asmaddr            ; save as default
  238.     push    h
  239.     IF    extended
  240.     lda    asmbnk
  241.     ENDIF
  242.     IF    symbolic
  243.     mvi    b,0
  244.     ELSE
  245.     mvi    b,0ffh
  246.     ENDIF
  247.     call    disasm            ; disassemble
  248.     call    readstring        ; get input
  249.     jrz    asm10            ; next if null input
  250.     pop    h
  251.     cpi    '.'
  252.     rz                ; exit if dot
  253.     push    h            ; current address
  254.     IF    extended
  255.     lda    asmbnk
  256.     ENDIF
  257.     call    assemble        ; assemble
  258.     IF    extended
  259.     call    poke            ; store back
  260.     ENDIF
  261. asm10:
  262.     pop    h
  263.     call    analop            ; analyse again to get length
  264.     jr    asmloop            ; and loop
  265. ;
  266. ;
  267. ;------------------------------------------------------------------------------
  268. ;
  269. ;    B:    set breakpoint
  270. ;
  271. breakset:
  272.     jrz    breaklst    ; no parameter means list
  273.     cpi    'X'
  274.     jz    breakdel    ; X means delete breakpoint
  275.     cpi    'I'
  276.     jrnz    breaks1        ; I means condition
  277.     call    getch        ; skip I
  278.     call    clrbkcond    ; clear old condition flags
  279.     call    copyexp        ; copy expression
  280.     mvi    c,0ffh        ; mark conditional
  281.     jr    breaks2
  282. ;
  283. breaks1:
  284.     mvi    c,0        ; mark unconditional
  285. breaks2:
  286.     push    b
  287.     call    sexpression    ; get breakpoint addr
  288.     pop    b
  289.     jc    cmderr        ; error if something else
  290. ;
  291. breakslp:
  292.     push    b
  293.     call    definebk    ; define breakpoint
  294.     call    sexpression    ; check for another
  295.     pop    b
  296.     jc    eocmd        ; ready if end
  297.     jr    breakslp
  298. ;
  299. ;
  300. breaklst:            ; list breakpoints
  301.     lda    numbreaks
  302.     ora    a
  303.     rz            ; ready if none
  304.     mov    b,a        ; B = number of entries
  305.     lxiy    breaklist+1    ; IY = break def pointer
  306.     lxi    d,5        ; DE = entry length
  307.     mvi    c,0        ; C = marker: list condition if nonzero
  308.     IF    symbolic
  309.     mvi    h,3        ; H = counter for entries per line
  310.     ELSE
  311.     mvi    h,4
  312.     ENDIF
  313.     mov    l,c        ; L = marker: at start of line if zero
  314. breakll:
  315.     push    h
  316.     ldy    l,0        ; HL = break addr
  317.     ldy    h,1
  318.     IF    extended
  319.     ldy    a,2        ; bank
  320.     ENDIF
  321.     call    wraddr        ; write breakpoint address
  322.     ldy    a,3        ; conditional flag
  323.     ora    a
  324.     jrz    breakll1
  325.     mov    c,a        ; mark condition occurred
  326.     push    h
  327.     lxi    h,bkcnstr
  328.     call    wrstr        ; mark as conditional
  329.     pop    h
  330. breakll1:
  331.     IF    symbolic
  332.     call    space
  333.     mvi    a,'.'
  334.     pushiy
  335.     push    d
  336.     push    b
  337.     call    wrsymbol
  338.     pop    b
  339.     pop    d
  340.     popiy
  341.     ENDIF
  342.     call    space2
  343.     dady    d        ; next entry
  344.     pop    h        ; restore entry counter
  345.     inr    l
  346.     dcr    h
  347.     jrnz    breakll2    ; jump if not end of line
  348.     call    crlf
  349.     IF    symbolic
  350.     mvi    h,3
  351.     ELSE
  352.     mvi    h,4
  353.     ENDIF
  354.     mvi    l,0
  355. breakll2:
  356.     djnz    breakll
  357. ;
  358. breaklsti:
  359.     mov    a,l
  360.     ora    a
  361.     cnz    crlf        ; CRLF if not at start of line
  362.     mov    a,c
  363.     ora    a        ; conditional breakpoint found ?
  364.     rz            ; ready if not
  365.     lxi    h,bkifstr
  366.     call    wrstr        ; else display condition
  367.     lxi    h,bkexpbuf
  368.     call    wrstr
  369.     jmp    crlf
  370. ;
  371. ;
  372. breakdel:
  373.     call    getch        ; skip 'X'
  374.     call    testch
  375.     sui    'I'        ; delete condition only ?
  376.     jrz    clrbkcond
  377.     call    sexpression    ; get breakpoint addr
  378.     jrc    breakdelall    ; delete all breakpoints if no address
  379. ;
  380. breakdellp:
  381.     call    deletebk
  382.     call    sexpression    ; check if another one to delete
  383.     jc    eocmd        ; ready if not
  384.     jr    breakdellp
  385. ;
  386. breakdelall:
  387.     call    eocmd
  388.     xra    a        ; delete all breakpoints
  389.     sta    numbreaks
  390.     sta    breaklist
  391.     ret
  392. ;
  393. ;
  394. clrbkcond:            ; clear conditional flag in all breakpoints
  395.     lda    numbreaks
  396.     ora    a
  397.     rz
  398.     mov    b,a
  399.     lxi    h,breaklist+4    ; first condition field
  400.     lxi    d,5
  401. clrbklp:
  402.     mvi    m,0
  403.     dad    d
  404.     djnz    clrbklp
  405.     ret
  406. ;
  407. ;
  408. ;    copy expression into save area
  409. ;
  410. copyexp:
  411.     call    skipsep
  412.     lxi    d,bkexpbuf        ; destination
  413.     pushix
  414.     pop    h            ; current line pointer
  415. copyexlp:
  416.     mov    a,m            ; copy up to ';'
  417.     ora    a
  418.     jz    cmderr            ; error if end of line
  419.     cpi    ';'
  420.     jrz    copyex10        ; ready if ;
  421.     stax    d            ; store char
  422.     inx    h
  423.     inx    d
  424.     jr    copyexlp
  425. ;
  426. copyex10:
  427.     xra    a
  428.     stax    d            ; terminate
  429.     call    mexpression        ; evaluate once to trap errors
  430.     jc    cmderr
  431.     call    getch
  432.     cpi    ';'
  433.     jnz    cmderr            ; error if something after expression
  434.     ret
  435. ;
  436. ;
  437. bkifstr    db    'If: ',0
  438. bkcnstr    db    '(If)',0
  439. ;
  440. ;------------------------------------------------------------------------------
  441. ;
  442. ;    D:    Dump
  443. ;
  444. dump:
  445.     cpi    'W'
  446.     jrnz    dump05
  447.     call    getch
  448.     call    skipsep
  449.     xra    a
  450.     jr    dump06
  451. dump05:
  452.     lda    dumpword
  453.     ora    a
  454. dump06:
  455.     sta    dumpword
  456.     push    psw
  457.     call    sexpression    ; from
  458.     jrnc    dump10
  459.     lded    dumpaddr    ; use default if no from address
  460.     jr    dump15
  461. ;
  462. dump10:
  463.     IF    extended
  464.     sta    dumpbnk
  465.     ENDIF
  466.     push    h
  467.     call    sexpression    ; end address
  468.     pop    d
  469.     jrnc    dump20        ; ok if specified
  470. ;
  471. dump15:
  472.     lxi    h,7fh        ; default end address = from + 7fh
  473.     dad    d
  474.     jrnc    dump20        ; ok if no wraparound to zero
  475.     lxi    h,0ffffh
  476.  
  477. ;
  478. dump20:
  479.     call    eocmd
  480.     xchg            ; HL = from, DE = end
  481. ;
  482. ;    write dump header line
  483. ;
  484.     mvi    b,7
  485.     IF    extended
  486.     lda    dumpbnk
  487.     cpi    0ffh        ; default bank ?
  488.     jrz    dumpspac    ; then 7 spaces
  489.     push    h
  490.     lxi    h,cbank
  491.     cmp    m        ; same as current bank ?
  492.     pop    h
  493.     jrz    dumpspac    ; then 7 spaces
  494.     mvi    b,10        ; else three spaces more for 'hh:'
  495.     ENDIF
  496. dumpspac:
  497.     call    space
  498.     djnz    dumpspac        ; write spaces
  499. ;
  500.     pop    psw        ; W-option ?
  501.     mov    a,l            ; low byte of addr
  502.     mvi    b,8
  503.     jrz    dumpwhdr
  504.     mvi    b,16
  505. ;
  506. dumphdr:
  507.     push    psw
  508.     call    wrhexdig        ; write lower nibble
  509.     call    space2
  510.     mov    a,b
  511.     cpi    9
  512.     cz    space            ; one space after 8 digits
  513.     pop    psw
  514.     inr    a
  515.     djnz    dumphdr
  516.     call    crlf
  517. ;
  518. ;    write dump
  519. ;
  520. dumploop:
  521.     IF    extended
  522.     lda    dumpbnk
  523.     ENDIF
  524.     call    dumpline        ; dump a line
  525.     shld    dumpaddr        ; store next addr as default
  526. ;
  527.     mov    a,d            ; end
  528.     inr    a
  529.     cmp    h            ; hi(curr) = hi(end) + 1 ?
  530.     rz                ; then wraparound, stop dump
  531.     ora    a
  532.     push    d            ; end
  533.     xchg
  534.     dsbc    d            ; end - current
  535.     xchg
  536.     pop    d            ; end
  537.     jrnc    dumploop        ; again if end >= current
  538.     ret
  539. ;
  540. ;
  541. dumpwhdr:
  542.     push    psw
  543.     inr    a
  544.     call    wrhexdig        ; write lower nibble
  545.     call    space
  546.     pop    psw
  547.     push    psw
  548.     call    wrhexdig
  549.     call    space2
  550.     call    space
  551.     pop    psw
  552.     inr    a
  553.     inr    a
  554.     djnz    dumpwhdr
  555.     call    crlf
  556. ;
  557. ;    write dump
  558. ;
  559. dumpwloop:
  560.     IF    extended
  561.     lda    dumpbnk
  562.     ENDIF
  563.     call    dumpwline        ; dump a line
  564.     shld    dumpaddr        ; store next addr as default
  565. ;
  566.     ora    a
  567.     push    d
  568.     xchg
  569.     dsbc    d            ; end - current
  570.     xchg
  571.     pop    d
  572.     jrnc    dumpwloop        ; again if end >= current
  573.     ret
  574. ;
  575. ;
  576. ;    dumpline:    dump one line
  577. ;
  578. ;        entry:    A/HL = address
  579. ;
  580. ;        exit:    HL = HL + 16
  581. ;
  582. dumpline:
  583.     push    b
  584.     IF    extended
  585.     push    h
  586.     call    peek
  587.     ENDIF
  588.     call    wraddr            ; show address
  589.     call    space2
  590. ;
  591.     mvi    b,16
  592.     IF    extended
  593.     lxi    h,peekbuf
  594.     ELSE
  595.     push    h
  596.     ENDIF
  597. dumplinlp:
  598.     mov    a,m
  599.     inx    h
  600.     call    wrhex            ; write byte at address
  601.     call    space
  602.     mov    a,b
  603.     cpi    9
  604.     cz    space            ; one space after 8 bytes
  605.     djnz    dumplinlp
  606. ;
  607. dumplinasc:
  608.     call    space
  609.     IF    extended
  610.     lxi    h,peekbuf
  611.     ELSE
  612.     pop    h
  613.     ENDIF
  614.     mvi    b,16
  615.     mvi    a,'>'
  616.     call    wrchar
  617. dumpch:
  618.     mov    a,m            ; write as character
  619.     inx    h
  620.     call    iscontrol
  621.     jrc    dumpch10
  622.     mvi    a,'.'            ; replace non-display char
  623. dumpch10:
  624.     call    wrchar
  625.     djnz    dumpch
  626. ;
  627.     mvi    a,'<'
  628.     call    wrchar
  629. ;
  630.     IF    extended
  631.     pop    h
  632.     lxi    b,16
  633.     dad    b            ; increase address
  634.     ENDIF
  635.     pop    b
  636.     jmp    crlf            ; exit via crlf
  637. ;
  638. ;
  639. dumpwline:
  640.     push    b
  641.     IF    extended
  642.     push    h
  643.     call    peek
  644.     ENDIF
  645.     call    wraddr            ; show address
  646.     call    space2
  647. ;
  648.     mvi    b,8
  649.     IF    extended
  650.     lxi    h,peekbuf
  651.     ELSE
  652.     push    h
  653.     ENDIF
  654.     push    d
  655. dumpwlinlp:
  656.     mov    e,m
  657.     inx    h
  658.     mov    d,m
  659.     inx    h
  660.     xchg
  661.     call    wrword            ; write word at address
  662.     call    space2
  663.     xchg
  664.     djnz    dumpwlinlp
  665. ;
  666.     pop    d
  667.     jr    dumplinasc
  668. ;
  669. ;
  670. ;------------------------------------------------------------------------------
  671. ;
  672. ;    E:    Execute command
  673. ;
  674.     IF    fileops
  675. ;
  676. exec:
  677.     call    mexpression        ; get condition
  678.     rc                ; default to FALSE if no expression
  679.     call    getch
  680.     cpi    ';'
  681.     rnz                ; do nothing if no command
  682.     mov    a,h
  683.     ora    l            ; true expression ?
  684.     rz                ; do nothing if false
  685.     call    skipsep
  686.     call    getch            ; get command character
  687.     jmp    moncmd            ; execute command
  688. ;
  689.     ENDIF
  690. ;
  691. ;------------------------------------------------------------------------------
  692. ;
  693. ;    G:    Go
  694. ;
  695. go:
  696.     xra    a
  697.     sta    lastop            ; this op may not be repeated
  698.     sta    tmpbkflag
  699.     call    expression        ; get address to jump to
  700.     jrnc    gogo            ; ok if specified
  701.     lhld    regpc            ; else load default
  702.     IF    extended
  703.     lda    cbank
  704.     ENDIF
  705. ;
  706. gogo:
  707.     shld    regpc
  708.     IF    extended
  709.     cpi    0ffh
  710.     jrz    gogo10
  711.     sta    cbank
  712.     ENDIF
  713. gogo10:
  714.     call    skipsep
  715.     lda    numbreaks        ; current number of breakpoints
  716.     mov    b,a
  717.     call    getch
  718.     jrz    gogoubk            ; go if no further parameter
  719.     cpi    ';'
  720.     jnz    cmderr            ; error if not ';'
  721.     call    expression        ; get temp breakpoint
  722.     jc    cmderr            ; error if nothing after ;
  723.     mov    c,a            ; save bank
  724.     lda    numbreaks        ; number of breaks again
  725.     mov    b,a
  726.     mov    a,c            ; bank number
  727.     call    addbk            ; add temp breakpoint
  728.     ldy    a,3            ; conditional ?
  729.     ani    07fh            ; mask off hi bit
  730.     sty    a,3            ; to mark unconditional
  731.     lxi    h,numbreaks
  732.     mov    a,m
  733.     sub    b            ; check if new break or old
  734.     dcr    a
  735.     sta    tmpbkflag        ; save (-2 if new, -1 if old)
  736.     mov    m,b
  737.     siyd    tmpbkiy
  738. ;
  739. gogoubk:
  740.     call    eocmd
  741.     jmp    unbreak            ; and go
  742. ;
  743. ;
  744. resettmpbk:
  745.     lxi    h,tmpbkflag
  746.     mov    a,m
  747.     ora    a
  748.     rz
  749.     mvi    m,0
  750.     liyd    tmpbkiy
  751.     inr    a
  752.     jrz    resetcond
  753.     ldy    l,0
  754.     ldy    h,1
  755.     ldy    a,2
  756.     jmp    deletebk
  757. ;
  758. resetcond:
  759.     ldy    a,3
  760.     ora    a
  761.     rz
  762.     mviy    0ffh,3
  763.     ret
  764. ;
  765. ;------------------------------------------------------------------------------
  766. ;
  767. ;    H:    Hex calculate
  768. ;
  769. hexcalc:
  770.     IF    hilo
  771.     jz    dishighlow        ; display high/low if no param
  772.     ENDIF
  773.     call    expression        ; get the expression
  774.     jc    cmderr            ; error if no expression
  775. hexcallp:
  776.     xchg
  777.     lxi    h,0
  778.     dsbc    d            ; negate
  779.     xchg
  780.     call    wrword            ; write hex
  781.     call    space2
  782.     xchg
  783.     mvi    a,'-'
  784.     call    wrchar
  785.     call    wrword            ; write complement as hex
  786.     call    space2
  787.     xchg
  788.     mvi    a,' '
  789.     call    wrdec            ; write decimal
  790.     call    space2
  791.     xchg
  792.     mvi    a,'-'
  793.     call    wrdec            ; write complement as decimal
  794.     call    space2
  795.     xchg
  796.     mov    a,h
  797.     call    wrbit            ; write as bit string
  798.     mov    a,l
  799.     call    wrbit
  800.     call    space2
  801.     mvi    a,''''
  802.     call    wrchar            ; write as character
  803.     mov    a,l
  804.     call    iscontrol
  805.     jrc    hexcdisc        ; ok if not a control character
  806. hexcch:
  807.     push    psw
  808.     mvi    a,'^'            ; mark control char
  809.     call    wrchar
  810.     pop    psw
  811.     adi    40h
  812. hexcdisc:
  813.     call    wrchar
  814.     mvi    a,''''
  815.     call    wrchar
  816. ;
  817.     IF    symbolic
  818.     call    space2
  819.     mvi    a,'.'
  820.     call    wrsymbol
  821.     ENDIF
  822. ;
  823.     call    crlf
  824. ;
  825.     call    sexpression
  826.     jrnc    hexcallp        ; display again if another expression
  827.     jmp    eocmd
  828. ;
  829. ;
  830. ;------------------------------------------------------------------------------
  831. ;
  832. ;    I:    input from port
  833. ;
  834. input:
  835.     call    expression        ; get port number
  836.     jrnc    inp1            ; ok if specified
  837.     lhld    lastinp            ; else use default
  838. inp1:
  839.     call    eocmd
  840.     shld    lastinp            ; store as default
  841.     mov    b,h
  842.     mov    c,l
  843.     inp    e            ; get byte
  844.     mvi    a,'I'
  845. ;
  846. portwr:
  847.     call    wrchar            ; write command identification
  848.     lxi    h,portstr
  849.     call    wrstr
  850.     mov    a,c
  851.     call    wrhex            ; display port number
  852.     lxi    h,sepstr
  853.     call    wrstr
  854.     mov    a,b
  855.     call    wrhex            ; display register B
  856.     lxi    h,pendstr
  857.     call    wrstr
  858.     mov    a,e
  859.     call    wrhex            ; display data as hex
  860.     call    space2
  861.     mov    a,e
  862.     call    wrbit            ; display data as bitstring
  863.     jmp    crlf
  864. ;
  865. ;
  866. ;    O:    Output to port
  867. ;
  868. output:
  869.     call    expression        ; get data
  870.     jrnc    outpa
  871.     lhld    outdata            ; use last data if not specified
  872.     mov    a,h
  873.     ora    a
  874.     jz    cmderr            ; error if no last data
  875. outpa:
  876.     mov    e,l
  877.     mvi    h,0ffh
  878.     shld    outdata            ; store as default data
  879. ;
  880.     push    d
  881.     call    sexpression        ; get port
  882.     pop    d
  883.     jrnc    outp1
  884.     lhld    lastout            ; use last port if no port number
  885. outp1:
  886.     call    eocmd
  887.     shld    lastout            ; store as default
  888.     push    h
  889.     mov    b,h
  890.     mov    c,l
  891.     mov    a,e
  892.     push    psw
  893.     mvi    a,'O'
  894.     call    portwr            ; display port & data
  895.     pop    psw
  896.     pop    b
  897.     outp    a            ; output data
  898.     ret
  899. ;
  900. ;
  901. portstr    db    '(Port=',0
  902. sepstr    db    ',B=',0
  903. pendstr    db    '): ',0
  904. ;
  905. ;------------------------------------------------------------------------------
  906. ;
  907. ;    L:    Disassemble
  908. ;
  909. list:
  910.     call    expression        ; from
  911.     jrnc    list1
  912.     lhld    listaddr        ; use default if no from-address
  913.     mvi    c,0ffh
  914.     mvi    b,8            ; mark 8 lines to list
  915.     jr    list2
  916. ;
  917. list1:
  918.     IF    extended
  919.     sta    listbnk
  920.     ENDIF
  921.     push    h
  922.     call    sexpression        ; to
  923.     pop    d
  924.     xchg                ; from into HL
  925.     mvi    c,0
  926.     jrnc    list2            ; ok if to given
  927. ;
  928.     mvi    c,0ffh
  929.     mvi    b,8            ; else mark 8 lines to list
  930. list2:
  931.     call    eocmd
  932.     push    d            ; save to-address
  933. ;
  934. listloop:
  935.     push    b
  936.     IF    extended
  937.     lda    listbnk
  938.     ENDIF
  939.     mvi    b,0ffh
  940.     call    disasm            ; disassemble line
  941.     shld    listaddr        ; store next addr as next default
  942.     call    crlf
  943.     pop    b
  944.     bit    0,c            ; 8 lines ?
  945.     jrz    listcmp            ; branch if to-address given
  946.     djnz    listloop        ; else use count
  947.     pop    d
  948.     ret
  949. ;
  950. listcmp:
  951.     pop    d            ; to-address
  952.     push    d
  953.     xchg
  954.     ora    a
  955.     dsbc    d            ; to - current
  956.     xchg
  957.     jrnc    listloop        ; list if current <= to
  958.     pop    d
  959.     ret
  960. ;
  961. ;------------------------------------------------------------------------------
  962. ;
  963. ;    M:    Move memory
  964. ;
  965. move:
  966.     call    expression        ; start
  967.     jc    cmderr            ; error if no start-addr
  968.     push    h
  969.     IF    extended
  970.     sta    mvsrcbnk
  971.     ENDIF
  972.     call    sexpression        ; end
  973.     jc    cmderr
  974.     push    h
  975.     call    sexpression        ; to
  976.     jc    cmderr
  977.     IF    extended
  978.     sta    mvdstbnk
  979.     sta    pbank            ; set bank for poke
  980.     ENDIF
  981.     call    eocmd
  982. ;
  983.     pop    d            ; end into DE
  984.     xthl                ; to-addr on stack, get start
  985.     xchg                ; end into HL
  986.     ora    a
  987.     dsbc    d            ; end - start
  988.     jc    cmderr            ; error if start > end
  989.     inx    h            ; length + 1
  990. ;
  991.     IF    extended
  992. ;
  993.     push    h            ; save length
  994.     mvi    b,4            ; divide by 16
  995. movlp1:
  996.     srlr    h
  997.     rarr    l
  998.     djnz    movlp1
  999.     mov    b,h
  1000.     mov    c,l        ; move number of 16-byte chunks into BC
  1001.     pop    h        ; length
  1002.     xthl            ; to-addr into HL, length on stack
  1003.     xchg            ; dest into DE, start into HL
  1004.     lda    mvsrcbnk    ; source bank
  1005.     call    peeks        ; peek into string
  1006. ;
  1007. movloop:
  1008.     mov    a,b
  1009.     ora    c
  1010.     jrz    movend        ; branch if no further 16-bit chunks
  1011.     push    b
  1012.     lxi    b,16
  1013.     dad    b        ; increase source addr
  1014.     xchg
  1015.     shld    paddr        ; set poke-address
  1016.     dad    b        ; increase dest addr
  1017.     push    d        ; save dest
  1018.     push    h        ; save source
  1019.     lxi    h,string
  1020.     lxi    d,peekbuf
  1021.     ldir            ; copy string -> peek/poke buffer
  1022.     pop    d        ; restore source
  1023.     pop    h        ; restore dest
  1024.     lda    mvsrcbnk
  1025.     call    peeks        ; get next chunk into string
  1026.     call    poke        ; write into destination
  1027.     pop    b        ; number of chunks
  1028.     dcx    b
  1029.     jr    movloop        ; loop
  1030. ;
  1031. movend:
  1032.     xchg            ; destination
  1033.     pop    b        ; original length
  1034.     mov    a,c        ; remainder
  1035.     ani    0fh        ; of division by 16
  1036.     rz            ; ready if no remaining bytes to move
  1037.     mov    c,a
  1038.     mvi    b,0
  1039.     lda    mvdstbnk
  1040.     call    peek        ; peek destination
  1041.     lxi    h,string
  1042.     lxi    d,peekbuf
  1043.     ldir            ; copy string into destination
  1044.     jmp    poke        ; write it
  1045. ;
  1046.     ELSE
  1047. ;
  1048.     mov    b,h
  1049.     mov    c,l        ; length into BC
  1050.     pop    h
  1051.     push    h        ; get & save to
  1052.     ora    a
  1053.     dsbc    d        ; to - start
  1054.     pop    h        ; to again
  1055.     xchg            ; HL = source, DE = dest
  1056.     jrnc    move80        ; jump if to >= start
  1057.     ldir
  1058.     ret
  1059. ;
  1060. move80:
  1061.     dcx    b
  1062.     dad    b
  1063.     xchg
  1064.     dad    b
  1065.     xchg
  1066.     inx    b
  1067.     lddr
  1068.     ret
  1069. ;
  1070.     ENDIF
  1071. ;
  1072. ;------------------------------------------------------------------------------
  1073. ;
  1074. ;    N:    Name definition
  1075. ;
  1076.     IF    symbolic
  1077. ;
  1078. namedef:
  1079.     jz    dissymbols
  1080.     IF    fileops
  1081.     cpi    'W'        ; write symbols
  1082.     jrnz    namedef10
  1083.     call    getch
  1084.     call    skipsep
  1085.     jmp    symwrite
  1086. ;
  1087. namedef10:
  1088.     cpi    'F'
  1089.     jrnz    namedef15
  1090.     call    getch
  1091.     call    skipsep
  1092.     jz    cmderr
  1093.     jmp    sfile        ; set filename
  1094. ;
  1095. namedef15:
  1096.     cpi    'S'        ; reserve space
  1097.     jrnz    namedef20
  1098.     call    getch
  1099.     call    sexpression
  1100.     jc    cmderr
  1101.     call    eocmd
  1102.     jmp    rsvsym
  1103. ;
  1104. namedef20:
  1105.     ENDIF
  1106.     cpi    'X'        ; kill symbol
  1107.     jrz    namekill
  1108.     IF    fileops
  1109.     cpi    'R'        ; symbol read ?
  1110.     jrnz    namdefloop
  1111.     call    getch
  1112.     call    sexpression
  1113.     jmp    readsym
  1114.     ENDIF
  1115. ;
  1116. namdefloop:            ; define symbol
  1117.     call    sexpression
  1118.     jc    cmderr
  1119.     push    h
  1120.     call    rdsymname
  1121.     jc    cmderr
  1122.     pop    d
  1123.     call    defsymbol
  1124.     call    skipsep
  1125.     jrnz    namdefloop
  1126.     ret
  1127. ;
  1128. namekill:
  1129.     call    getch
  1130.     call    skipsep
  1131.     jrz    namekall
  1132. ;
  1133. namekloop:
  1134.     call    rdsymname
  1135.     jc    cmderr
  1136.     jz    cmderr
  1137.     call    killsymbol
  1138.     call    skipsep
  1139.     jrnz    namekloop
  1140.     ret
  1141. ;
  1142. namekall:
  1143.     lhld    symstart
  1144.     IF    fileops
  1145.     shld    symtop
  1146.     ELSE
  1147.     shld    topval
  1148.     ENDIF
  1149.     ret
  1150. ;
  1151.     ENDIF
  1152. ;
  1153. ;------------------------------------------------------------------------------
  1154. ;
  1155. ;    P:    Protect
  1156. ;
  1157. protect:
  1158.     jrz    protlst        ; list if no param
  1159.     cpi    'X'
  1160.     jrz    protdel        ; delete if X
  1161.     pushix
  1162.     pop    h
  1163.     lxi    d,protexpbuf
  1164.     lxi    b,80
  1165.     ldir            ; copy buffer
  1166.     call    mexpression    ; evaluate once to trap errors
  1167.     jrc    proterr
  1168.     call    testch
  1169.     rz
  1170. proterr:
  1171.     call    protdel
  1172.     jmp    cmderr
  1173. ;
  1174. protdel:
  1175.     lxi    h,0
  1176.     shld    protexpbuf    ; mark buffer empty
  1177.     ret
  1178. ;
  1179. protlst:
  1180.     lxi    h,protexpbuf
  1181.     call    wrstr        ; write expression
  1182.     jmp    crlf
  1183. ;
  1184. ;
  1185. ;------------------------------------------------------------------------------
  1186. ;
  1187. ;    Q:    Query memory for a byte string
  1188. ;
  1189. query:
  1190.     cpi    'J'        ; justified ?
  1191.     mvi    a,0
  1192.     jrnz    query1
  1193.     call    getch        ; skip J
  1194. query1:
  1195.     sta    querjust    ; set justified flag
  1196.     call    sexpression    ; start
  1197.     jc    cmderr
  1198.     IF    extended
  1199.     sta    querbnk
  1200.     ENDIF
  1201.     push    h
  1202.     call    sexpression    ; end
  1203.     jc    cmderr
  1204.     push    h
  1205. ;
  1206.     call    skipsep
  1207.     call    bytestring    ; assemble string to look for
  1208.     jc    cmderr
  1209. ;
  1210.     pop    h        ; end
  1211.     pop    d        ; start
  1212.     dsbc    d        ; end - start
  1213.     jc    cmderr        ; error if end < start
  1214.     inx    h        ; length
  1215.     xchg            ; addr into HL, length into DE
  1216. ;
  1217. querloop:
  1218.     lxix    string
  1219.     ldx    c,-1        ; string length
  1220.     push    h        ; save start
  1221.     IF    extended
  1222. querloop1:
  1223.     lda    querbnk
  1224.     call    peek        ; get memory
  1225.     push    d
  1226.     lxi    d,16
  1227.     dad    d        ; increase memory addr
  1228.     pop    d
  1229.     mvi    b,16
  1230.     push    h
  1231.     lxi    h,peekbuf
  1232.     ENDIF
  1233. quercmp:
  1234.     ldx    a,0
  1235.     cmp    m
  1236.     jrnz    quernxt        ; branch if unequal
  1237.     inx    h
  1238.     inxix
  1239.     dcr    c
  1240.     IF    extended
  1241.     jrz    quermatch    ; match if string length expired
  1242.     djnz    quercmp        ; loop for 16 bytes in chunk
  1243.     pop    h
  1244.     jr    querloop1    ; get next 16-byte chunk
  1245.     ELSE
  1246.     jrnz    quercmp
  1247.     ENDIF
  1248. ;
  1249. ;
  1250. quermatch:
  1251.     IF    extended
  1252.     pop    h        ; discard current addr
  1253.     ENDIF
  1254.     pop    h        ; get start addr
  1255.     push    h        ; and save
  1256.     push    d
  1257.     lda    querjust    ; justified ?
  1258.     ora    a
  1259.     jrz    quermat1
  1260.     lxi    d,8
  1261.     dsbc    d        ; display 8 bytes before addr if justified
  1262. quermat1:
  1263.     IF    extended
  1264.     lda    querbnk
  1265.     ENDIF
  1266.     call    dumpline    ; dump the matching line
  1267.     pop    d
  1268.     IF    extended
  1269.     push    h        ; dummy push
  1270.     ENDIF
  1271. ;
  1272. quernxt:
  1273.     IF    extended
  1274.     pop    h        ; discard current addr
  1275.     ENDIF
  1276.     pop    h        ; start addr again
  1277.     inx    h        ; next addr to compare
  1278.     dcx    d        ; decrease count
  1279.     mov    a,d
  1280.     ora    e
  1281.     rz            ; ready if count exprired
  1282.     jr    querloop    ; else try again to find match
  1283. ;
  1284. ;
  1285. ;------------------------------------------------------------------------------
  1286. ;
  1287. ;    R:    Read
  1288. ;
  1289.     IF    fileops
  1290. ;
  1291. fread:
  1292. ;
  1293.     call    expression    ; offset
  1294.     jmp    read        ; continue in system dependent part
  1295. ;
  1296.     ENDIF
  1297. ;
  1298. ;------------------------------------------------------------------------------
  1299. ;
  1300. ;    S:    Substitute
  1301. ;
  1302. substit:
  1303.     call    expression    ; substitution address
  1304.     jrnc    substit10
  1305.     call    eocmd
  1306.     lhld    asmaddr        ; use default if no start addr
  1307.     jr    subsmain
  1308. ;
  1309. substit10:
  1310.     IF    extended
  1311.     sta    asmbnk
  1312.     ENDIF
  1313.     push    h
  1314.     call    skipsep
  1315.     call    bytestring    ; specified in command ?
  1316.     pop    h
  1317.     jrc    subsmain    ; normal substit if not
  1318.     call    subslinp    ; substitute
  1319.     shld    asmaddr        ; set new default
  1320.     ret            ; and exit
  1321. ;
  1322. subsmain:
  1323.     shld    asmaddr        ; set new default
  1324.     IF    extended
  1325.     lda    asmbnk
  1326.     call    peek        ; get memory
  1327.     ENDIF
  1328.     call    wraddr        ; show address
  1329.     call    space2
  1330.     IF    extended
  1331.     lda    peekbuf
  1332.     ELSE
  1333.     mov    a,m
  1334.     ENDIF
  1335.     call    wrhex        ; show byte at address
  1336.     call    space2
  1337.     push    h
  1338.     call    readstring    ; get input line
  1339.     pop    h
  1340.     jrz    subs10        ; next if empty
  1341.     cpi    '.'
  1342.     rz            ; exit if dot
  1343.     push    h
  1344.     call    bytestring    ; get byte string
  1345.     jc    cmderr        ; error if something else
  1346.     pop    h        ; restore address
  1347.     call    subsline    ; substitute
  1348.     jr    subsmain
  1349. ;
  1350. subs10:
  1351.     inx    h        ; next address
  1352.     jr    subsmain
  1353. ;
  1354. ;
  1355. subslinp:
  1356.     IF    extended
  1357.     lda    asmbnk
  1358.     call    peek        ; get memory
  1359.     ENDIF
  1360. subsline:
  1361.     IF    extended
  1362.     xchg            ; addr into DE
  1363.     ENDIF
  1364.     mov    c,b        ; string length into C
  1365. subslinlp:
  1366.     IF    extended
  1367.     mvi    b,16        ; length of a chunk
  1368.     lxi    h,peekbuf
  1369.     ENDIF
  1370. subsloop:
  1371.     ldx    a,0        ; get byte
  1372.     mov    m,a        ; store at address
  1373.     inx    h
  1374.     inxix
  1375.     IF    extended
  1376.     inx    d        ; increase addr, too
  1377.     ENDIF
  1378.     dcr    c
  1379.     IF    extended
  1380.     jrz    subslex        ; ready if string count reached
  1381.     djnz    subsloop    ; loop for all 16 bytes    in chunk
  1382.     call    poke        ; store the 16 bytes
  1383.     xchg            ; addr again
  1384.     mov    b,c
  1385.     jr    subslinp    ; get next 16-byte chunk
  1386.     ELSE
  1387.     jrnz    subsloop
  1388.     ENDIF
  1389. ;
  1390. subslex:
  1391.     IF    extended
  1392.     call    poke        ; store back
  1393.     xchg            ; restore HL (addr)
  1394.     ENDIF
  1395.     ret
  1396. ;
  1397. ;
  1398. ;------------------------------------------------------------------------------
  1399. ;
  1400. ;    C:    Trace over Calls
  1401. ;    T:    Trace
  1402. ;
  1403. calltrace:
  1404.     mvi    a,0ffh
  1405.     jr    trace1
  1406. trace:
  1407.     xra    a
  1408. trace1:
  1409.     sta    trcallopt        ; trace over calls option
  1410.     xra    a
  1411.     sta    traceexp        ; init options
  1412.     sta    tracenl
  1413.     sta    tracejp
  1414. trace2:
  1415.     call    testch
  1416.     cpi    'N'            ; no list ?
  1417.     jrz    trace21
  1418.     cpi    'J'            ; jumps only ?
  1419.     jrz    trace22
  1420.     cpi    'W'            ; while ?
  1421.     jrz    trace23
  1422.     cpi    'U'            ; until ?
  1423.     jrnz    trace3
  1424.     mvi    a,80h            ; mark until
  1425.     jr    tracewu
  1426. ;
  1427. trace21:
  1428.     sta    tracenl            ; mark no list
  1429. trace29:
  1430.     call    getch            ; skip char
  1431.     jr    trace2            ; check for other options
  1432. ;
  1433. trace22:
  1434.     sta    tracejp            ; mark jumps only
  1435.     jr    trace29
  1436. ;
  1437. ;    trace with count
  1438. ;
  1439. trace3:
  1440.     call    sexpression        ; get number of ops to trace
  1441.     jrnc    trace10
  1442.     lxi    h,1            ; default is 1
  1443. trace10:
  1444.     call    eocmd
  1445.     mov    a,h
  1446.     ora    l
  1447.     jz    cmderr            ; error if zero count
  1448.     shld    tracecount        ; save
  1449.     jmp    dotrace            ; doit
  1450. ;
  1451. ;    trace while/until
  1452. ;
  1453. trace23:
  1454.     mvi    a,07fh            ; mark while
  1455. tracewu:
  1456.     sta    traceexp        ; mark expression kind
  1457.     call    getch            ; skip W/U
  1458.     call    skipsep
  1459.     sixd    traceptr        ; remember position in line
  1460.     call    mexpression        ; evaluate once to trap errors
  1461.     jc    cmderr
  1462.     call    testch
  1463.     jnz    cmderr            ; error if something left on line
  1464.     lxi    h,0ffffh
  1465.     shld    tracecount        ; set dummy trace count
  1466.     jmp    dotrace            ; go trace
  1467. ;
  1468. ;
  1469. ;------------------------------------------------------------------------------
  1470. ;
  1471. ;    V:    Verify memory
  1472. ;
  1473. verify:
  1474.     call    expression        ; start
  1475.     jc    cmderr            ; error if no start-addr
  1476.     push    h
  1477.     IF    extended
  1478.     sta    mvsrcbnk
  1479.     ENDIF
  1480.     call    sexpression        ; end
  1481.     jc    cmderr
  1482.     push    h
  1483.     call    sexpression        ; to
  1484.     jc    cmderr
  1485.     call    eocmd
  1486. ;
  1487.     IF    extended
  1488.     sta    mvdstbnk
  1489.     ENDIF
  1490.     pop    d            ; end into DE
  1491.     xthl                ; to-addr on stack, get start
  1492.     xchg                ; end into HL
  1493.     ora    a
  1494.     dsbc    d            ; end - start
  1495.     jc    cmderr            ; error if start > end
  1496.     inx    h            ; length + 1
  1497.     mov    b,h
  1498.     mov    c,l            ; length into BC
  1499.     pop    h
  1500.     xchg                ; dest into DE, start into HL
  1501. ;
  1502. verifyloop:
  1503.     IF    extended
  1504.     push    b
  1505.     lxi    b,16
  1506.     lda    mvsrcbnk        ; source bank
  1507.     call    peek            ; source into peekbuf
  1508.     dad    b            ; inc source addr
  1509.     xchg
  1510.     lda    mvdstbnk
  1511.     call    peeks            ; dest into string
  1512.     dad    b            ; inc dest addr
  1513.     pop    b
  1514. ;
  1515.     push    h            ; save dest
  1516.     push    d            ; save source
  1517.     lxi    d,string
  1518.     lxi    h,peekbuf
  1519.     mvi    a,16
  1520. verify10:
  1521.     push    psw
  1522.     ENDIF
  1523.     ldax    d
  1524.     cmp    m
  1525.     cnz    verifyerr    ; display if mismatch
  1526.     inx    h
  1527.     inx    d
  1528.     dcx    b
  1529.     mov    a,b
  1530.     ora    c
  1531.     IF    extended
  1532.     jrnz    verify20
  1533.     pop    psw
  1534.     pop    d
  1535.     pop    h
  1536.     ret
  1537. ;
  1538. verify20:
  1539.     pop    psw
  1540.     dcr    a
  1541.     jrnz    verify10
  1542.     pop    h        ; source
  1543.     pop    d        ; dest
  1544.     jr    verifyloop
  1545.     ELSE
  1546.     jrnz    verifyloop
  1547.     ret
  1548.     ENDIF
  1549. ;
  1550. verifyerr:
  1551.     IF    extended
  1552.     push    h
  1553.     push    d
  1554.     push    b
  1555.     mov    c,a
  1556.     mov    b,m
  1557.     lxi    d,peekbuf
  1558.     ora    a
  1559.     dsbc    d
  1560.     push    h        ; offset
  1561.     lded    paddr
  1562.     dad    d        ; source addr + offset
  1563.     lda    mvsrcbnk
  1564.     call    wraddr        ; write source addr
  1565.     call    space
  1566.     mov    a,b
  1567.     call    wrhex        ; write source byte
  1568.     call    space2
  1569.     lhld    psaddr
  1570.     pop    d
  1571.     dad    d        ; dest addr + count
  1572.     lda    mvdstbnk
  1573.     call    wraddr        ; write dest addr
  1574.     call    space
  1575.     mov    a,c
  1576.     call    wrhex        ; write dest byte
  1577.     call    crlf
  1578.     pop    b
  1579.     pop    d
  1580.     pop    h
  1581.     ret
  1582. ;
  1583.     ELSE
  1584. ;
  1585.     call    wraddr
  1586.     call    space
  1587.     mov    a,m
  1588.     call    wrhex
  1589.     call    space2
  1590.     xchg
  1591.     call    wraddr
  1592.     call    space
  1593.     mov    a,m
  1594.     call    wrhex
  1595.     call    crlf
  1596.     xchg
  1597.     ret
  1598. ;
  1599.     ENDIF
  1600. ;
  1601. ;
  1602. ;------------------------------------------------------------------------------
  1603. ;
  1604. ;    W:    Write
  1605. ;
  1606.     IF    fileops
  1607. ;
  1608. fwrite:
  1609.     call    expression        ; from
  1610.     jc    cmderr
  1611.     push    h
  1612.     push    psw
  1613.     call    sexpression        ; to
  1614.     jc    cmderr
  1615.     xchg                ; to into DE
  1616.     pop    psw            ; bank
  1617.     pop    h            ; from
  1618.     jmp    write            ; continue in system dependent part
  1619. ;
  1620.     ENDIF
  1621. ;
  1622. ;------------------------------------------------------------------------------
  1623. ;
  1624. ;    X:    where are we & register display/mod
  1625. ;
  1626. where:
  1627.     jz    display            ; display regs if no param
  1628.     cpi    ''''
  1629.     jz    disalt            ; display alternate regs
  1630. ;
  1631. whereloop:
  1632.     call    rdregister        ; read register name
  1633.     jc    cmderr            ; error if none
  1634.     mov    b,a
  1635.     push    b
  1636.     push    h
  1637.     call    sexpression
  1638.     jrc    wheredis        ; display if no expression
  1639.     pop    d
  1640.     pop    b
  1641.     push    psw
  1642.     mov    a,b
  1643.     ani    30h
  1644.     cpi    10h
  1645.     jrz    set8reg            ; branch if 8-bit reg
  1646.     pop    psw
  1647.     call    putval
  1648. wherenxt:
  1649.     call    skipsep
  1650.     rz
  1651.     jr    whereloop
  1652. ;
  1653. set8reg:
  1654.     xchg
  1655.     pop    psw
  1656.     mov    a,b
  1657.     cpi    17h
  1658.     jrz    setrr
  1659.     mov    m,e
  1660.     jr    wherenxt
  1661. ;
  1662. setrr:
  1663.     mov    a,e
  1664.     star
  1665.     jr    wherenxt
  1666. ;
  1667. ;
  1668. wheredis:
  1669.     pop    h
  1670.     pop    b
  1671.     mov    a,b
  1672.     ani    30h
  1673.     cpi    10h
  1674.     jrz    mod8reg            ; branch if 8-bit reg
  1675. ;
  1676. wheremod:
  1677.     push    h            ; save reg addr
  1678.     mov    e,m
  1679.     inx    h
  1680.     mov    d,m            ; get contents
  1681.     xchg
  1682.     call    wrword            ; write contents
  1683.     call    whereget        ; get replacement
  1684.     pop    d            ; restore reg addr
  1685.     rc                ; ret if no change
  1686. putval:
  1687.     xchg
  1688.     mov    m,e            ; store new value
  1689.     inx    h
  1690.     mov    m,d
  1691.     lxi    b,regpc+1        ; was it PC ?
  1692.     ora    a
  1693.     dsbc    b
  1694.     rnz                ; ready if not
  1695.     IF    extended
  1696.     call    xltbank            ; adjust bank
  1697.     sta    cbank            ; set new bank
  1698.     ENDIF
  1699.     sded    listaddr        ; set new default list addr
  1700.     ret
  1701. ;
  1702. ;
  1703. mod8reg:
  1704.     mov    a,b
  1705.     cpi    17h            ; R ?
  1706.     jrz    modrr            ; R is special
  1707.     push    h            ; save address
  1708.     mov    a,m
  1709.     call    wrhex            ; show value
  1710.     call    whereget        ; get replacement
  1711.     pop    d
  1712.     rc                ; ready if no change
  1713.     xchg
  1714.     mov    m,e            ; store value
  1715.     ret
  1716. ;
  1717. modrr:
  1718.     ldar                ; get current value of R
  1719.     call    wrhex            ; display
  1720.     call    whereget
  1721.     rc
  1722.     star                ; set new value
  1723.     ret
  1724. ;
  1725. ;
  1726. whereget:
  1727.     call    space2
  1728.     call    readstring        ; get input line
  1729.     stc
  1730.     rz                ; ready if no replacement
  1731.     call    sexpression        ; get value
  1732.     jc    cmderr
  1733.     jmp    eocmd
  1734. ;
  1735. ;------------------------------------------------------------------------------
  1736. ;
  1737. ;    Y:    Display/change Y-variables
  1738. ;
  1739. yvar:
  1740.     jz    disyvars        ; display if no parameter
  1741.     call    expression
  1742.     jc    cmderr            ; error if no number
  1743. setyloop:
  1744.     mov    a,h
  1745.     ora    a
  1746.     jnz    cmderr
  1747.     mov    a,l
  1748.     cpi    10
  1749.     jnc    cmderr
  1750.     add    a            ; digit * 2
  1751.     mov    e,a
  1752.     mvi    d,0
  1753.     lxi    h,variables
  1754.     dad    d            ; address variable
  1755.     push    h
  1756.     call    sexpression
  1757.     xchg
  1758.     pop    h
  1759.     jrc    wheremod        ; continue like for register
  1760.     mov    m,e
  1761.     inx    h
  1762.     mov    m,d
  1763.     call    sexpression
  1764.     rc
  1765.     jr    setyloop
  1766. ;
  1767. ;
  1768. ;------------------------------------------------------------------------------
  1769. ;
  1770. ;    Z:    Zap memory with constant
  1771. ;
  1772. zap:
  1773.     call    expression        ; from
  1774.     jc    cmderr
  1775.     IF    extended
  1776.     sta    zapbnk
  1777.     ENDIF
  1778.     push    h
  1779.     call    sexpression        ; to
  1780.     jc    cmderr
  1781.     push    h
  1782.     call    skipsep
  1783.     call    bytestring        ; value
  1784.     jc    cmderr
  1785. ;
  1786.     pop    h            ; to
  1787.     pop    d            ; from
  1788.     dsbc    d            ; to - from
  1789.     jc    cmderr            ; error if to < from
  1790.     inx    h
  1791.     xchg                ; length in DE, addr in HL
  1792.     lxix    string
  1793.     ldx    c,-1            ; string length
  1794. ;
  1795. zaploop:
  1796.     IF    extended
  1797.     lda    zapbnk
  1798.     call    peek            ; get memory
  1799.     push    d
  1800.     lxi    d,16
  1801.     dad    d            ; increase addr
  1802.     pop    d
  1803.     push    h
  1804.     mvi    b,16
  1805.     lxi    h,peekbuf
  1806. zaploop2:
  1807.     ENDIF
  1808.     ldx    a,0            ; copy bytes into destination
  1809.     mov    m,a
  1810.     inx    h
  1811.     inxix
  1812.     dcx    d
  1813.     mov    a,d
  1814.     ora    e
  1815.     IF    extended
  1816.     jrz    zapend            ; ready if all bytes zapped
  1817.     ELSE
  1818.     rz
  1819.     ENDIF
  1820.     dcr    c
  1821.     IF    extended
  1822.     jrnz    zaploop10        ; loop if more bytes in string
  1823.     ELSE
  1824.     jrnz    zaploop
  1825.     ENDIF
  1826.     lxix    string
  1827.     ldx    c,-1            ; go back to start of string
  1828. zaploop10:
  1829.     IF    extended
  1830.     djnz    zaploop2        ; loop for all 16 bytes in chunk
  1831.     call    poke            ; store back
  1832.     pop    h
  1833.     ENDIF
  1834.     jr    zaploop            ; get next chunk
  1835. ;
  1836.     IF    extended
  1837. zapend:
  1838.     pop    h
  1839.     jmp    poke            ; return via poke
  1840. ;
  1841.     ENDIF
  1842. ;
  1843. ;------------------------------------------------------------------------------
  1844. ;------------------------------------------------------------------------------
  1845. ;
  1846.     dseg
  1847. ;
  1848. varstart:
  1849. ;
  1850. tmpbkflag    ds    1
  1851. tmpbkiy        ds    2
  1852. ;
  1853. listaddr    ds    2        ; default list
  1854.         IF    extended
  1855. listbnk        ds    1
  1856.         ENDIF
  1857. dumpaddr    ds    2        ; default dump
  1858.         IF    extended
  1859. dumpbnk        ds    1
  1860.         ENDIF
  1861. asmaddr        ds    2        ; default assemble/substitute
  1862.         IF    extended
  1863. asmbnk        ds    1
  1864.         ENDIF
  1865. lastinp        ds    2        ; default input port
  1866. lastout        ds    2        ; default output port
  1867. outdata        ds    2        ; default output data
  1868. lastop        ds    1        ; last command
  1869. dumpword    ds    1        ; dump word if lastop is dump command
  1870. tracecount    ds    2        ; number of lines to trace
  1871. trcallopt    ds    1        ; trace over calls if <> 0
  1872. tracenl        ds    1        ; trace without list if <> 0
  1873. tracejp        ds    1        ; trace jumps only if <> 0
  1874. traceexp    ds    1        ; trace while if 7f, until if 80
  1875. traceptr    ds    2        ; expression pointer for trace U/W
  1876. variables    ds    20        ; variables Y0..Y9
  1877.         IF    hilo
  1878. lowval        ds    2        ; special variable L
  1879. highval        ds    2        ; special variable H
  1880. maxval        ds    2        ; special variable M
  1881. topval        ds    2        ; special variable T
  1882.         ENDIF
  1883. protexpbuf    ds    80        ; expression for trace protection
  1884. bkexpbuf    ds    80        ; expression for BREAK IF
  1885. ;
  1886.         IF    extended
  1887. bnktmp1        ds    1
  1888. bnktmp2        ds    1
  1889.         ENDIF
  1890. movdest        ds    2
  1891. ;
  1892.         IF    extended
  1893. zapbnk        equ    bnktmp1
  1894. mvsrcbnk    equ    bnktmp1
  1895. mvdstbnk    equ    bnktmp2
  1896. querbnk        equ    bnktmp1
  1897. querjust    equ    bnktmp2
  1898.         ELSE
  1899. querjust    ds    1
  1900.         ENDIF
  1901. ;
  1902. ;
  1903. varspace    equ    $-varstart
  1904. ;
  1905.     ds    256            ; stack space
  1906. stack:
  1907.     end
  1908. 
  1909.