home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / debug / ddtz27.ark / DDTZ.MAC < prev    next >
Encoding:
Text File  |  1988-05-29  |  37.9 KB  |  2,063 lines

  1. title    DDTZ main section, Ver. 2.7
  2. subttl    History, entries, externals
  3. ;
  4. ;    CPM/DOS+ 8080/Z80/64180 debugger, by C.B. Falconer.
  5. ;    CAUTION - Code is extremely tight - study before changing.
  6. ;
  7. ; 2.7    88/5/25.   Handling 64180 opcodes.   Now issued only with the
  8. ;    DDTZM command set (MSDOS debug compatible). Added support for
  9. ;    undocumented z80 opcodes. Dis/assm changes.        cbf.
  10. ; 2.6m  87/7/11. Dissassembler section, so MOV disassembles correctly
  11. ;    under 8080 (or V20-80 under MSDOS).            cbf.
  12. ; 2.5m    86/3/16.  Command structure altered to match MSDOS DEBUG,  to
  13. ;    avoid silly errors when switching between systems.   Ver. no.
  14. ;    shows "M" for this variant. MATCHDEBUG equate controls.  Adds
  15. ;    Quit command, removes Untrace.   Others shifted, see tbl/doc.
  16. ;
  17. ; 2.5   86/2/17. Correct exit from load of HEX files.  4 bytes moved,
  18. ;    but affects the relocation vector.  cbf
  19. ;
  20. ; 2.4   86/2/12.   Correct assembler section for inx/dcx/push/pop xy.
  21. ;    No changest to this segment,  except version no.   No changes
  22. ;    to 8080 only assembler/disassembler (DDTY).    cbf
  23. ;
  24. ; 2.3    86/1/10. Reworked from DDTY 2.2.5 to handle Z80 ops.  Z80
  25. ;    registers are displayed, cannot be set.  Tracing works on Z80
  26. ;    opcodes. Added based dump/substitute commands, @ to set base,
  27. ;    char value parameters, made h command default for anything
  28. ;    not recognizable.  Standard relocater system. k command added
  29. ;    Assy time switch cuts assemble/disassemble to 8080 code set.
  30. ;
  31. ; v5 - 2 Apr. 84. Upshift & strip hi order bit, hex file reads.
  32. ;      "h" shows decimal for difference. 
  33. ;      "#" prefix causes decimal parameter input.
  34. ;
  35. ; Used for assembly/disassembly only
  36.     extrn    assemble, disassem, keep
  37.     extrn    .bdos;        initialize use only
  38.     extrn    begin;        for overwrite checks only
  39. ;
  40. ; Routines useable by assembler/disassembler
  41.     entry    dblblk, blank, couta, csta
  42.     entry    crlf, qbrk, nextch, skipblks
  43.     entry    t4hx, t2hx, tstr;    a,f
  44.     entry    getline;    a,f,b,c,d,e
  45.     entry    pcnt, pcnta;    a,f,d,e,h,l. a=count, de^list
  46.     entry    nextparm;    d,e,h,l; hl := de^; de:=de+2
  47.     entry    rdhex, rdhexc;    a:=exitch, de := value
  48.     entry    qdelim;        flags
  49.     entry    chkop;        all. hl^ past op. de to op at entry
  50.     entry    based;        a,f,h,l.  hl := hl+base
  51.     entry    ldbased,tbased; a,f. getvalue/type_adr using hl+base
  52.     entry    index,indexwd;    a,f,h,l
  53.     entry    casexfr;    a,f,h,l + routine
  54.     entry    sdem, ldem;    hl^ =:= de; hl:=hl+2
  55.     entry    delesshl;    a,f. comparator, unsigned
  56.     entry    t4hxbc,t4hxblk;    a,f (with trailing blank)
  57.     entry    err;        abort return to command level
  58.     entry    dos, foperate;    save regs. operate on tfcb
  59. ;
  60. ; Data area for assembler/disassembler
  61.     entry    dendptr;    disassembly end for lcmd only
  62.     entry    disasmp;    where to dis/assemble from
  63.     entry    aflag;        -1, 0, or deflines.
  64. ;
  65. ; scratch space available for assembler/disassembler
  66.     entry    storeptr;    wd
  67.     entry    exitstk;    wd
  68.     entry    buff;        16 bytes
  69.     entry    tfcb, defdma;    cpm standard
  70. ;
  71. ; Read/only data areas, set by chkop
  72.     entry    opkind, zopkind
  73.     entry    z80flg;        set if running on Z80
  74.     entry    unloaded;    memory not used
  75. ;
  76. ; Values for relocater system
  77.     entry    codesize, pages
  78. ;
  79. subttl    equates, configuration
  80.     cseg
  81. ;
  82. true        equ    -1
  83. false        equ    not true
  84. matchdebug    equ    true;    false matches DDT command structure
  85. ;                true matches DEBUG command structure
  86. ;
  87. ver        equ    27
  88. if matchdebug
  89.  debugver    equ    'M';    Signify MSDOS match
  90. else; matchddt
  91.  debugver    equ    ' ';    lower case for debuggery/patches
  92. endif; matchddt
  93. ;
  94. ; Customization parameters
  95. traplvl        equ    7;    rst level for steps etc
  96. deflines    equ    12;    default for l command
  97. deflgh        equ    192;    default bytes for dcommand
  98. ;
  99. cbufsiz        equ    40;    characters in cons in buffer
  100. stksize        equ    44;    DDTs own stack. Even number only
  101. ;
  102. ; CPM parameters
  103. reboot        equ    0
  104. bdos        equ    reboot + 5
  105. tfcb        equ    reboot + 05ch
  106. defdma        equ    reboot + 080h
  107. tpa        equ    reboot + 0100h
  108. ;
  109. ; Ascii chars
  110. tab        equ    9
  111. lf        equ    0ah
  112. cr        equ    0dh
  113. rub        equ    07fh
  114. ;
  115. ; z80 opcodes used if Z80 cpu only. Always guarded.
  116. exaf    macro
  117.     db    08h
  118.     endm
  119. exx    macro
  120.     db    0d9h
  121.     endm
  122. pushix    macro
  123.     db    0ddh,0e5h
  124.     endm
  125. popix    macro
  126.     db    0ddh,0e1h
  127.     endm
  128. pushiy    macro
  129.     db    0fdh,0e5h
  130.     endm
  131. popiy    macro
  132.     db    0fdh,0e1h
  133.     endm
  134. ldai    macro
  135.     db    0edh,057h
  136.     endm
  137. ldia    macro
  138.     db    0edh,047h
  139.     endm
  140. ldar    macro
  141.     db    0edh,05fh
  142.     endm
  143. ;
  144. subttl    Main loop
  145. ;
  146. ; If the act of loading a program overwrites any of the above area
  147. ; then DDT is cut back to begin here and dis/assem commands removed
  148. ddtbgn:
  149. .bdosexu:    jmp    init;    altered, alt ^bdos when cut-back
  150. ;
  151. ; setup for return from executed program
  152. ; h,l
  153. setrtn:    lxi    h,return
  154.     shld    spsave
  155.     lxi    h,progrtn
  156.     shld    return
  157.     ret
  158. ;
  159. ; program exit via return
  160. progrtn:
  161.     lxi    sp,stack
  162.     call    setrtn
  163. ;    "    "
  164. cmdloop:
  165.     lxi    sp,stack
  166.     call    zerotctr
  167.     call    chkused
  168.     jc    cmdloop1
  169.     lxi    h,.bdosexu;    In case lower portion overwritten
  170.     shld    bdos+1
  171. cmdloop1:
  172.     call    qbrk;        flush any input
  173.     call    crlf
  174.     mvi    a,'-'
  175.     call    couta
  176.     call    newln
  177.     jz    cmdloop
  178.     lxi    h,cmdloop;    set return on stack
  179.     push    h
  180.     cpi    ' '
  181.     jc    err
  182.     sui    '@'
  183.     jc    cmdloop2
  184.     cpi    maxcmd
  185.     lxi    h,cmdtable
  186.     jc    casexfr
  187. cmdloop2:
  188.     adi    '@';        restore input char
  189.     call    pcnta;        try for a number conversion
  190.     jmp    hcmda
  191. ;
  192. subttl    command table
  193. ;
  194. cmdtable:
  195.     dw    setbase;    @)set up offset
  196.     dw    acmd;        a)ssemble first
  197.     dw    progrtn;    b)egin (* i.e. initialize stack & return *)
  198.     dw    ccmnd;        c)ompare first,last,against
  199.     dw    dcmd;        d)ump first,last,base
  200. if matchdebug; not DDT commands
  201.     dw    scmd;    *    e)nter_mem 1st_address        err
  202.     dw    fcmd;        f)ill first,last,value
  203.     dw    gcmd;        g)oto address, trap1, trap2
  204.     dw    hcmd;        h)exarith valu1, valu2
  205.     dw    err;    *
  206.     dw    err    
  207.     dw    err;    *
  208.     dw    rcmd;    *    l)oad_from_file [offset]
  209.     dw    mcmd;        m)ove first,last,destination
  210.     dw    icmd;    *    n)ame init tfcbs_cmdline
  211.     dw    err
  212.     dw    err
  213.     dw    reboot;    *    q)uit to DOS
  214.     dw    xcmd;    *    r)egister examine/change
  215.     dw    wcmnd;    *    s)earch first,last,value
  216.     dw    tcmd;        t)race_execution [count]
  217.     dw    lcmd;    *    u)nassemble first,last
  218.     dw    err
  219.     dw    kcmd;    *    w)rite [1st,last]
  220.     dw    rdexit;    *    x)amine memory usage
  221. else;    match DDT commands, not DEBUG
  222.     dw    err;    *
  223.     dw    fcmd;        f)ill first,last,value
  224.     dw    gcmd;        g)oto address, trap1, trap2
  225.     dw    hcmd;        h)exarith valu1, valu2
  226.     dw    icmd;    *    i)nit tfcb_cmdln
  227.     dw    err    
  228.     dw    kcmd;    *    k)eep_in_file [1st,last}
  229.     dw    lcmd;    *    l)istcode first,last
  230.     dw    mcmd;        m)ove first,last,destination
  231.     dw    err;    *
  232.     dw    err
  233.     dw    err
  234.     dw    rdexit;    *    q)uery (* memory used for application *)
  235.     dw    rcmd;    *    r)ead_from_file [offset]
  236.     dw    scmd;    *    s)ubstitute_in_mem 1st adr.
  237.     dw    tcmd;        t)race_execution [count]
  238.     dw    ucmd;    *    u)ntrace_execution [count] (* quiet *)
  239.     dw    err
  240.     dw    wcmnd;    *    w)here first,last,value
  241.     dw    xcmd;    *    x)amine_change [register]
  242. endif;    DDT, not DEBUG structure
  243.     dw    ycmd;        bc := p1; de := p2; execute (p3)
  244.     dw    zcmd;        Show Z80 registers
  245. maxcmd    equ    ($-cmdtable)/2
  246. ;
  247. subttl    Command executors etc.
  248. ;
  249. ; set base on @ command
  250. setbase:
  251.     call    pcnt
  252.     lhld    baseval
  253.     cnz    nextparm;    does not disturb flags
  254.     shld    baseval
  255.     rnz
  256. ;    "    "
  257. ; crlf and t4hx
  258. t4hxc:    call    crlf
  259.     jmp    t4hx
  260. ;
  261. ; execute arbitrary user routine as command
  262. ; y bcvalue, devalue, routineaddress
  263. ycmd:    call    get3p
  264.     pchl;            call user routine
  265. ;
  266. ; open file, using tfcb
  267. ; a,f
  268. fopen:    xra    a
  269.     sta    charcntr
  270.     sta    tfcb+32;    set back to first record
  271.     sta    tfcb+12
  272.     mvi    a,0fh
  273. ;    "    "
  274. ; operate on file tfcb, function (a)
  275. ; a,f
  276. foperate:
  277.     push    d
  278.     lxi    d,tfcb
  279.     call    dos
  280.     pop    d
  281.     ret
  282. ;
  283. acmd:    call    ckpcnt;        aborts if not available
  284.     jmp    assemble
  285. ;
  286. ; c(ompare) start_addr, end_addr, against_addr
  287. ccmnd:    call    get3p;        bc:=start, de := end; hl := against
  288. ccmnd1:    ldax    b
  289.     cmp    m
  290.     jz    ccmnd5;        no difference
  291.     call    crlfbk
  292.     call    t4hxbc;        compare address
  293.     ldax    b
  294.     call    t2hx;        compare contents
  295.     call    blank
  296.     call    t4hxblk;    against address
  297.     mov    a,m
  298.     call    t2hx;        against contents
  299. ccmnd5:    inx    b
  300.     inx    h
  301.     call    delessbc
  302.     jnc    ccmnd1
  303.     ret
  304. ;
  305. kcmd:    call    ckpcnt;        aborts if not available
  306.     jmp    keep
  307. ;
  308. lcmd:    call    ckpcnt;        aborts if not available
  309.     call    nextparm;    does not disturb flags
  310.     jz    dadef
  311.     dcr    a
  312.     jc    lcmd0;        1st parm skipped, continue
  313.     shld    disasmp
  314.     jz    dadef;        1 parm only
  315. lcmd0:    call    nextparm
  316.     shld    dendptr
  317.     ani    07fh
  318.     dcr    a
  319.     jz    disassm
  320. ;    "    "    
  321. ; command error exit
  322. err:    call    crlf
  323.     mvi    a,'?'
  324.     call    couta
  325.     jmp    cmdloop
  326. ;
  327. ; dissassemble for default line count
  328. dadef:    mvi    a,deflines
  329. ;    "    "
  330. ; connector to dissassem. (a) is kind coding
  331. disassm:
  332.     jmp    disassem
  333. ;
  334. ; Dump parm1 thru parm2, relative to base
  335. ; (parm1 defaults to prev dump end, parm2 to parm1+0c0h)
  336. ; (optional) parm3 sets base
  337. dcmd:    lhld    baseval
  338.     shld    base
  339.     call    pcnt
  340.     jz    dcmd2
  341.     call    nextparm
  342.     jc    dcmd1
  343.     shld    dumptr
  344. dcmd1:    ani    7fh
  345.     dcr    a
  346.     jz    dcmd2
  347.     call    nextparm
  348.     shld    dumplast
  349.     dcr    a
  350.     jz    dcmd3
  351.     call    nextparm
  352.     shld    base
  353.     jmp    dcmd4
  354. dcmd2:    lhld    dumptr
  355.     mov    a,l
  356.     ani    0f0h
  357.     mov    l,a
  358.     lxi    d,deflgh-1
  359.     dad    d
  360.     jnc    dcmd3
  361.     lxi    h,65535;    prevent wrap-around
  362. dcmd3:    shld    dumplast
  363. dcmd4:    call    crlfbk
  364.     lhld    dumptr
  365.     push    h
  366.     call    tbased;        show with possible offset
  367. dcmd5:    mov    a,l
  368.     ani    0fh
  369.     jz    dcmd6
  370.     call    blks43
  371.     dcr    l
  372.     jmp    dcmd5
  373. dcmd6:    pop    h
  374.     push    h
  375. dcmd7:    call    blank
  376.     call    ldbased
  377.     call    t2hx
  378.     inx    h
  379.     mov    a,l
  380.     ani    7
  381.     cz    blank
  382.     call    dumpdone
  383.     jc    dcmd8
  384.     mov    a,l
  385.     ani    0fh
  386.     jnz    dcmd7
  387. dcmd8:    shld    dumptr
  388.     mov    a,l
  389.     ani    0fh
  390.     jz    dcmda
  391. dcmd9:    call    blks43
  392.     inr    l
  393.     mov    a,l
  394.     ani    0fh
  395.     jnz    dcmd9
  396.     call    blank
  397. dcmda:    pop    h
  398. dcmdb:    call    ldbased
  399.     call    ascii
  400.     inx    h
  401.     xchg
  402.     lhld    dumptr
  403.     call    delesshl
  404.     xchg
  405.     jnz    dcmdb
  406.     call    dumpdone
  407.     jnc    dcmd4
  408.     ret
  409. ;
  410. ; crlf and check for break
  411. ; a,f
  412. crlfbk:    call    crlf
  413. ;    "    "
  414. ; get console status. If ready, abort command, else z flag
  415. ; a,f (if not broken, else never returns)
  416. qbrk:    call    csta
  417.     rz
  418.     mvi    c,1
  419.     call    .bdosexu;    flush the char
  420.     jmp    cmdloop
  421. ;
  422. ; load a := (hl + base)^.  Z flag if base zero
  423. ; a,f
  424. ldbased:
  425.     push    h
  426.     call    based
  427.     mov    a,m
  428.     pop    h
  429.     ret
  430. ;
  431. ; Show hl as possible offset from base.
  432. ; a,f
  433. tbased:    call    t4hx
  434.     push    h
  435.     call    based
  436.     jz    tbx
  437.     mvi    a,':'
  438.     call    couta
  439.     call    t4hx
  440. tbx:    pop    h
  441.     ret    
  442. ;
  443. ; hl := hl + base.  Z flag if base is zero
  444. ; a,f,h,l
  445. based:    push    d
  446.     xchg
  447.     lhld    base
  448.     mov    a,l
  449.     ora    h
  450.     dad    d
  451.     pop    d
  452.     ret
  453. ;
  454. ; get 3 paramaters from command line to bc,de,hl resp.
  455. ; a,f,b,c,d,e,h,l
  456. get3p:    call    pcnt
  457.     cpi    3
  458.     jnz    err
  459. ;    "    "
  460. ; load regs with 3 parms, no count check
  461. ld3p:    call    nextparm
  462.     push    h
  463.     call    nextparm
  464.     push    h
  465.     call    nextparm
  466.     pop    d
  467.     pop    b
  468.     ret
  469. ;
  470. ; set carry for (de) less than (bc), z flag if equal
  471. ; a,f
  472. delessbc:
  473.     mov a,d    ! sub b
  474.     rnz
  475.     mov a,e    ! sub c
  476.     ret
  477. ;
  478. ; fill parm1 thru parm2 with parm3
  479. fcmd:    call    get3p
  480.     mov a,h    ! ora a
  481.     jnz    err
  482. fcmd1:    call    delessbc
  483.     jc    cmdloop
  484.     mov    a,l
  485.     stax b    ! inx b
  486.     jmp    fcmd1
  487. ;
  488. ; goto [parm1],[trap1[,trap2]]
  489. gcmd:    call    crlf
  490.     call    pcnt
  491.     call    ld3p
  492.     push h ! push b ! pop h ! pop b;    xchg bc,hl
  493. ;    "    "
  494. ; execute, z flag no setups, carry no pc change
  495. ; hl = pc, de = trap1, bc = trap2 on entry
  496. ; (a) = trapcount + 1
  497. run:    di
  498.     jz    run2
  499.     jc    run1
  500.     shld    pcsave
  501. run1:    ani    7fh
  502.     dcr a    ! jz run2
  503.     push    b
  504.     call    setatrp
  505.     pop    d
  506.     dcr    a
  507.     cnz    setatrp
  508. run2:    lxi    sp,stack
  509.     pop d ! pop b ! pop psw ! pop h
  510.     sphl
  511.     lhld    pcsave
  512.     push    h
  513.     lhld    hlsave
  514.     ei
  515.     ret
  516. ;
  517. ; set a     trap at (de)
  518. ; b,h,l
  519. setatrp:
  520.     push    psw
  521.     lxi    h,trp1set
  522.     mov a,m ! inr m ! ora a
  523.     jz    setatrp2
  524.     inx h    ! mov a,m
  525.     inx h    ! mov b,m
  526.     inx    h
  527.     cmp e    ! jnz setatrp2
  528.     mov    a,b
  529.     cmp d    ! jnz setatrp2
  530.     mov a,m    ! stax d
  531. setatrp2:
  532.     inx h    ! mov m,e
  533.     inx h    ! mov m,d
  534.     inx h    ! ldax d ! mov m,a
  535.     mvi    a,0c7h + 8*traplvl;    (rst traplvl)
  536.     stax    d
  537.     pop    psw
  538.     ret
  539. ;
  540. ; H parm1 parm2   hex sub/difference
  541. hcmd:    call    pcnt
  542. ;    "    "
  543. ; Entry after other command line items used 
  544. hcmda:    call    nextparm
  545.     dcr a    ! jz thxdecr
  546.     dcr a    ! jnz err
  547.     push    h
  548.     call    nextparm
  549.     pop    d
  550.     push    h
  551.     call    crlf
  552.     dad    d
  553.     call    t4hxblk
  554.     pop    h
  555.     mov a,e    ! sub l ! mov l,a
  556.     mov a,d    ! sbb h ! mov h,a
  557.     jmp    thexdec;    show in hex and decimal
  558. ;
  559. ; output (hl) in hex and decimal after cr/lf
  560. ; a,f,b,c,d,e,h,l
  561. thxdecr:
  562.     call    crlf
  563. ;    "    "
  564. ; output (hl) in hex and decimal to console
  565. ; a,f,b,c,d,e,h,l
  566. thexdec:
  567.     call    t4hxblk
  568.     push    h
  569.     call    tdzs
  570.     pop    h
  571.     call    blank
  572.     mov    a,l
  573.     jmp    ascii
  574. ;
  575. ; istring - setup tfcb
  576. ; move char string into defdma, set length, etc.
  577. ; parse initial file name into tfcb
  578. icmd:    lda    consbuf+1;    line length
  579.     lxi    d,consbuf+3;    ignoring "i" character
  580.     lxi    h,defdma
  581.     mov    b,a
  582.     inr    b
  583. icmd1:    mov    m,a
  584.     inx    h
  585.     mvi    m,0;        set a terminator
  586.     dcr    b
  587.     ldax    d
  588.     inx    d
  589.     jnz    icmd1
  590.     xra    a
  591.     sta    tfcb+32
  592.     lxi    h,tfcb
  593.     call    pfnm
  594.     mvi    m,0;        set first extent
  595.     lxi    h,tfcb+16
  596.     call    pfnm
  597.     mvi    m,0
  598.     ret
  599. ;
  600. ; parse filename into fcb hl^.  Only drive/name/ext fields
  601. ; Return a = terminator character, hl points to fcb+12
  602. ; a,f,c,h,l
  603. pfnm:    call    skipblks
  604.     mvi    m,0
  605.     inx    h
  606.     mvi    c,8;        hl+c=fcb+9
  607.     jz    pfnm1;        eol, blank fill
  608.     mov    m,a
  609.     inx h    ! dcr c
  610.     call    nextch;
  611.     jz    pfnm1;        eol, blank files. hl+c=fcb+9
  612.     cpi    ':'
  613.     jz    pfnm2
  614. pfnm1:    call    ldflda;        not a drive spec
  615.     jmp    pfnm3
  616. pfnm2:    dcx h    ! inr c
  617.     mov    a,m
  618.     sui    '@'
  619.     dcx h ! mov m,a ! inx h;    hl=fcb+1, c=8
  620.     call    ldfld;        exit hl=fcb+9
  621. pfnm3:    cpi    '.'
  622.     mvi    c,3
  623.     jnz    ldflda;        blank fill extent
  624. ;    "    "
  625. ; load field hl^ for c chars.
  626. ; Return a = terminator char, hl points past field
  627. ; a,f,c,h,l
  628. ldfld:    call    nextch;        jams at eol
  629. ;    "    "
  630. ; Entry with initial char. in a
  631. ; a,f,c,h,l
  632. ldflda:    mvi    m,' ';        default
  633.     call    qfndelim
  634.     jc    ldfld2;        control char
  635.     jz    ldfld2;        other delimiter
  636.     cpi    '*'
  637.     mov    m,a
  638.     jz    ldfld4
  639.     inx h    ! dcr c
  640.     jnz    ldfld
  641. ldfld1:    call    nextch;        skip to delimiter
  642.     call    qfndelim
  643.     jnz    ldfld1
  644.     ret
  645. ldfld2:    inx h    ! dcr c;    early delimiter found
  646.     jnz    ldflda;        with the ".", blank or control
  647.     ret
  648. ldfld4:    mvi    m,'?'
  649.     inx h    ! dcr c
  650.     jnz    ldfld4
  651.     jmp    ldfld1
  652. ;
  653. ; move memory parm1 thru parm2 to parm3 (up)]
  654. mcmd:    call    get3p
  655. mcmd1:    call    delessbc
  656.     rc
  657.     ldax b ! inx b ! mov m,a ! inx h
  658.     jmp    mcmd1
  659. ;
  660. ; Check for hex file, tfcb
  661. ; a,f,h,l
  662. qhexfile:
  663.     lxi    h,tfcb+9
  664.     mov    a,m
  665.     ani 7fh    ! cpi 'H'
  666.     rnz
  667.     inx h    ! mov a,m
  668.     ani 7fh    ! cpi 'E'
  669.     rnz
  670.     inx h    ! mov a,m
  671.     ani 7fh    ! cpi 'X'
  672.     ret
  673. ;
  674. ; check for program loaded above (hl)^.  carry if so
  675. ; a,f,d,e
  676. cmpload:
  677.     xchg
  678.     lhld    unloaded
  679.     mov a,l    ! sub e ! mov a,h ! sbb    d
  680.     xchg
  681.     ret
  682. ;
  683. chkldmax:
  684.     call    cmpload
  685.     rnc
  686.     shld    unloaded
  687.     ret
  688. ;
  689. ; check for program loaded above disassembler section
  690. ; a,f,d,e
  691. chkused:
  692.     push    h
  693.     lxi    h,begin
  694.     call    cmpload
  695.     pop    h
  696.     ret
  697. ;
  698. ; read from file tfcb into defdma
  699. ; a,f
  700. fread:    mvi    a,20
  701.     call    foperate;    fread
  702.     ora    a
  703.     ret
  704. ;
  705. ; r(ead) from file tfcb with bias parm1
  706. rcmd:    call    pcnt
  707.     jz    rcmd1
  708.     dcr a    ! jnz err
  709.     call    nextparm
  710. rcmd1:    push    h
  711. ;    "    "
  712. loadit:    lxi    d,defdma
  713.     mvi    a,26
  714.     call    dos;        set to std dma
  715.     call    fopen
  716.     inr a    ! jz err
  717.     call    qhexfile
  718.     jz    loadit5;    read from hex file
  719.     pop    h
  720.     lxi    d,tpa
  721.     dad    d
  722. loadit1:
  723.     push    h
  724.     call    fread;        read from file tfcb
  725.     pop    h
  726.     jnz    rdexit
  727.     lxi    d,.bdosexu-128
  728.     call    delesshl
  729.     jc    err;        too big
  730.     lxi    d,defdma
  731.     mvi    c,128
  732. loadit2:
  733.     ldax d    ! inx d
  734.     mov m,a    ! inx h
  735.     dcr    c
  736.     jnz    loadit2
  737.     call    chkldmax
  738.     jmp    loadit1
  739. loadit3:
  740.     call    rdhexbyt;    record type
  741. loadit4:
  742.     call    rdhexbyt;    data
  743.     mov m,a    ! inx h ! dcr e
  744.     jnz    loadit4
  745.     call    rdhexbyt
  746.     push    psw
  747.     call    chkldmax
  748.     pop    psw
  749.     jnz    err
  750. loadit5:
  751.     call    charead;    load from hex file
  752.     jc    err
  753.     sui    ':'
  754.     jnz    loadit5
  755.     mov    d,a
  756.     pop h    ! push h;    get bias value
  757.     call    rdhexbyt;    record length
  758.     mov    e,a
  759.     call    rdhexbyt
  760.     push    psw
  761.     call    rdhexbyt
  762. ; no load check to allow load above cp/m
  763.     pop    b
  764.     mov    c,a;        form address
  765.     dad    b;        plus bias
  766.     mov    a,e
  767.     ora    a
  768.     jnz    loadit3
  769.     mov a,b    ! ora c
  770.     pop    b
  771.     jz    rdexit;        dont update pc on zero exu point
  772.     mov a,b    ! ora c
  773.     jnz    rdexit;        or on non-zero bias
  774.     shld    pcsave
  775. ;    "    "
  776. rdexit:    lxi    h,rdxmsg
  777.     mov    a,m
  778. rdexit1:
  779.     call    couta
  780.     inx h    ! mov a,m
  781.     ora    a
  782.     jnz    rdexit1
  783. rdexit2:
  784.     call    crlf
  785.     lhld    unloaded
  786.     push    h
  787.     call    t4hxblk
  788.     lhld    pcsave
  789.     call    t4hxblk
  790.     pop    h
  791.     dcx    h
  792.     mov    l,h
  793.     mvi    h,0
  794. ;    "    "
  795. ; output (hl) in decimal to console.
  796. ;  suppress leading zeros.
  797. ; a,f,b,c,d,e,h,l
  798. tdzs:    lxi    b,0f00ah;    c=divisor=10, b=iter cnt=-16
  799.     xra    a;        clear
  800. tdzs1:    dad    h;        (hl) := (hl)/10; rdr to (a)
  801.     ral;            shift off into (a)
  802.     cmp    c;        test
  803.     jc    tdzs2;        no bit
  804.     sub    c;        bit = 1
  805.     inx    h
  806. tdzs2:    inr    b
  807.     jm    tdzs1;        not done
  808.     push    psw;        save output digit
  809.     mov a,h    ! ora l
  810.     cnz    tdzs;        not left digit, recursive
  811.     pop    psw;        last unlisted digit
  812.     adi    '0'
  813.     jmp    couta
  814. ;
  815. rdxmsg:    db    cr,lf,'Next  PC  Save',0
  816. ;
  817. ; read hex byte to (a), update cksum (d)
  818. ; a,f,d
  819. rdhexbyt:
  820.     push    b
  821.     push    d
  822.     call    getch
  823.     rlc ! rlc ! rlc ! rlc
  824.     ani    0f0h
  825.     push    psw
  826.     call    getch
  827.     pop    b
  828.     ora    b
  829.     mov    b,a
  830.     pop    d
  831.     add    d
  832.     mov    d,a
  833.     mov    a,b
  834.     pop    b
  835.     ret
  836. ;
  837. ; substitute memory at parm up
  838. scmd:    lhld    baseval
  839.     shld    base
  840.     call    pcnt
  841.     jz    err
  842.     call    nextparm
  843.     dcr a    ! jz scmd1
  844.     dcr a    ! jnz err
  845.     push    h
  846.     call    nextparm
  847.     shld    base
  848.     pop    h
  849. scmd1:    call    crlf
  850.     push    h
  851.     call    tbased
  852.     call    blank
  853.     pop    h
  854.     call    ldbased
  855.     call    t2hx
  856.     call    blank
  857.     call    newln
  858.     jz    scmd2
  859.     cpi    '.'
  860.     rz
  861.     push    h
  862.     call    pcnta
  863.     dcr a    ! jnz err
  864.     call    nextparm
  865.     mov a,h ! ora a
  866.     jnz    err
  867.     mov    a,l
  868.     pop h    ! push h
  869.     push    psw
  870.     call    based
  871.     pop    psw
  872.     mov    m,a
  873.     pop    h
  874. scmd2:    inx    h
  875.     jmp    scmd1
  876. ;
  877. ucmd:    xra    a
  878.     jmp    track
  879. ;
  880. tcmd:    mvi    a,-1
  881. ;    "    "
  882. ; track machine execution. show on (a)
  883. track:    sta    showtrc
  884.     call    pcnt
  885.     jz    track1
  886.     dcr a    ! jnz err
  887.     call    nextparm
  888.     mov a,l    ! ora h
  889.     jz    err
  890.     dcx    h
  891. track1:    shld    tracectr
  892. ;    "    "
  893. showrun:
  894.     call    showcpu
  895.     jmp    run
  896. ;
  897. ; w(here) first_address, last_address, search_value
  898. wcmnd:    call    get3p;        (bc):=first, (de):=last, (hl):=value
  899. wcmnd1:    call    delessbc
  900.     rc;            done, exit
  901.     ldax b    ! cmp l ! inx b
  902.     jnz    wcmnd1;        not here
  903.     ldax b    ! cmp h
  904.     jnz    wcmnd1;        2nd byte does not match
  905.     call    crlf
  906.     dcx    b
  907.     call    t4hxbc;        list address
  908.     inx    b
  909.     call    qbrk
  910.     jmp    wcmnd1;        and continue
  911. ;
  912. subttl    Register display
  913. ;
  914. ; display register, all or 1 only and modify
  915. xcmd:    call    skipblks
  916.     jnz    xcmd1
  917.     call    showcpu
  918.     call    qz80
  919.     jnz    zshow
  920.     ret
  921. xcmd1:    lxi    b,11;        selected registers - modify
  922.     lxi    h,regnames
  923. xcmd2:    cmp    m
  924.     jz    xcmd3;        valid reg, index in (c)
  925.     inx h    ! inr b ! dcr c
  926.     jnz    xcmd2
  927.     jmp    err
  928. xcmd3:    call    skipblks
  929.     jnz    err
  930.     push    b
  931.     call    crlf
  932.     call    dumpreg
  933.     call    blank
  934.     call    getline
  935.     call    pcnt
  936.     pop    b
  937.     rz
  938.     dcr a    ! jnz err
  939.     call    nextparm
  940.     mov    a,b
  941.     cpi 05    ! jnc xcmd4
  942.     mov    a,h;        flag revisions
  943.     ora a    ! jnz err
  944.     mov    a,l
  945.     cpi    02
  946.     jnc    err
  947.     call    getflgs
  948.     mov    h,a
  949.     mov    b,c
  950.     mvi    a,0feh
  951.     call    lrotate
  952.     ana    h
  953.     mov    b,c
  954.     mov    h,a
  955.     mov    a,l
  956.     call    lrotate
  957.     ora    h
  958.     stax    d
  959.     ret
  960. xcmd4:    jnz    xcmd5
  961.     mov    a,h;        (a) revisions
  962.     ora a    ! jnz err
  963.     mov    a,l
  964.     lxi    h,asave
  965.     mov    m,a
  966.     ret
  967. xcmd5:    push    h;        bc, de, hl, sp, pc revisions
  968.     call    regkept
  969.     pop    d
  970.     mov m,e    ! inx h ! mov m,d
  971.     ret
  972. ;
  973. ; Show z80 registers command
  974. zcmd:    call    qz80
  975.     jz    err
  976. ;    "    "
  977. ; show all z80 only registers.  No alteration allowed
  978. zshow:    call    crlf
  979.     mvi    c,9
  980.     lxi    h,rreg
  981.     lxi    d,zregnm
  982. zshow1:    ldax    d
  983.     call    couta
  984.     mvi    a,'='
  985.     call    couta
  986.     mov    a,m
  987.     call    t2hx
  988.     mov    a,c
  989.     cpi    6
  990.     jnc    zshow2
  991.     dcx    h
  992.     mov    a,m
  993.     call    t2hx
  994. zshow2:    call    blank
  995.     dcx h    ! inx d    ! dcr c
  996.     jnz    zshow1
  997.     ret
  998. ;
  999. zregnm:    db    'riafbdhxy'
  1000. ;         987654321
  1001. ;
  1002. ; a,f,c,d,e
  1003. getflgs:
  1004.     push    h
  1005.     lxi    h,flgbits
  1006.     mov e,b    ! mvi d,0 ! dad    d
  1007.     mov    c,m
  1008.     lxi    h,flgsave
  1009.     mov    a,m
  1010.     xchg
  1011.     pop    h
  1012.     ret
  1013. ;
  1014. ; a,f,c,d,e
  1015. showflg:
  1016.     call    getflgs
  1017. showflg1:
  1018.     rar
  1019.     dcr    c
  1020.     jnz    showflg1
  1021.     ral
  1022.     ani    1
  1023.     jmp    hexdig
  1024. ;
  1025. ; hl := pointer to register storage for id (a)
  1026. ; a,f,d,e,h,l
  1027. regkept:
  1028.     lxi    h,reglocns-6
  1029.     call    index
  1030.     mov    e,m
  1031.     mvi    d,-1
  1032.     lxi    h,pcsave+2
  1033.     dad    d
  1034.     ret
  1035. ;
  1036. ; get stored value to hl for reg id (a)
  1037. ; a,f,d,e,h,l
  1038. regvalue:
  1039.     call    regkept
  1040.     mov e,m    ! inx h ! mov d,m
  1041.     xchg
  1042.     ret
  1043. ;
  1044. ; dump reg content, (a) is id name char, b is id
  1045. ; a,f,d,e,h,l
  1046. dumpreg:
  1047.     mov    a,m
  1048.     call    couta
  1049.     mov    a,b
  1050.     cpi    05
  1051.     jc    showflg
  1052. ;    "    "
  1053. ; show reg value 8 bit or 16bit, on z flag set/reset. a=b is regid
  1054. ; a,f,d,e,h,l
  1055. showreg:
  1056.     push    psw
  1057.     mvi    a,'='
  1058.     call    couta
  1059.     pop    psw
  1060.     jnz    showreg1
  1061.     lxi    h,asave
  1062.     mov    a,m
  1063.     jmp    t2hx
  1064. showreg1:
  1065.     push    psw
  1066.     call    regvalue
  1067.     call    t4hx
  1068.     pop    psw
  1069.     sui    8
  1070.     rc;            bc or de > 0..1
  1071.     sui    2
  1072.     rnc;            pc
  1073.     mvi    a,'>';        show mem for hl^ and sp^
  1074.     call    couta
  1075.     mov e,m    ! inx h ! mov d,m
  1076.     xchg
  1077. ;    "    "
  1078. ; output (hl) as 4 hex chars to console
  1079. ; a,f
  1080. t4hx:    mov    a,h
  1081.     call    t2hx
  1082.     mov    a,l
  1083. ;    "    "
  1084. ; output (a) as 2 hex chars to console
  1085. ; a,f
  1086. t2hx:    push    psw
  1087.     rar ! rar ! rar ! rar
  1088.     call    hexdig
  1089.     pop    psw
  1090. ;    "    "
  1091. ; output (a) lsbits as hex char to console
  1092. ; a,f
  1093. hexdig:    ani    0fh
  1094.     adi 090h ! daa
  1095.     aci 040h ! daa
  1096. ;    "    "
  1097. ; display (a) as ascii char, use '.' for all controls
  1098. ; a,f
  1099. ascii:    cpi    rub
  1100.     jnc    ascii1
  1101.     cpi    ' '
  1102.     jnc    couta
  1103. ascii1:    mvi    a,'.'
  1104.     jmp    couta
  1105. ;
  1106. showcpu:
  1107.     lxi    h,regnames
  1108.     mvi    b,00
  1109.     call    crlf
  1110. showcpu1:
  1111.     push b    ! push h
  1112.     call    dumpreg;    id b, name hl^
  1113.     pop h    ! pop b
  1114.     inr    b
  1115.     inx    h
  1116.     mov    a,b
  1117.     cpi    05
  1118.     cnc    blank
  1119.     mov    a,b
  1120.     cpi    11
  1121.     jc    showcpu1
  1122. ;    "    "
  1123. showcd:    call    setraps;    to get length, etc
  1124.     push    psw
  1125.     push d    ! push b;    save for possible run
  1126.     call    chkused
  1127.     jnc    showcd1
  1128.     lhld    pcsave
  1129.     shld    disasmp
  1130.     mvi    a,-1
  1131.     call    disassm
  1132.     jmp    showcd3
  1133. showcd1:
  1134.     dcx    h
  1135.     shld    dumplast
  1136.     lhld    pcsave
  1137. showcd2:
  1138.     mov    a,m
  1139.     call    t2hx
  1140.     call    blank
  1141.     inx    h
  1142.     call    dumpdone
  1143.     jnc    showcd2
  1144. showcd3:
  1145.     pop b    ! pop d
  1146.     pop    psw
  1147.     ret
  1148. ;
  1149. ; left rotate (a) (b)-1 places
  1150. lrotate:
  1151.     dcr    b
  1152.     rz
  1153.     rlc
  1154.     jmp    lrotate
  1155. ;
  1156. ; read next char from file.  carry for eof or error
  1157. ; a,f
  1158. charead:
  1159.     push h    ! push d ! push b
  1160.     lda    charcntr
  1161.     ani    7fh
  1162.     jnz    charead1
  1163.     call    fread
  1164.     stc
  1165.     jnz    charead2
  1166.     sta    charcntr
  1167. charead1:
  1168.     mvi    d,0
  1169.     mov    e,a
  1170.     lxi    h,defdma
  1171.     dad    d
  1172.     mov    a,m
  1173.     ani    07fh;        strip any high order bit
  1174.     call    upshift
  1175.     cpi    1ah
  1176.     stc
  1177.     jz    charead2
  1178.     lxi    h,charcntr
  1179.     inr    m
  1180.     ora    a
  1181. charead2:
  1182.     pop b    ! pop d ! pop h
  1183.     ret
  1184. ;
  1185. subttl    console i/o stuff
  1186. ;
  1187. ; line in to buffer. lnptr := first char
  1188. ; a,f
  1189. getline:
  1190.     push    h
  1191.     mvi    a,10
  1192.     lxi    d,consbuf
  1193.     call    dos;        get console line
  1194.     lxi    h,consbuf+2
  1195.     shld    lnptr
  1196.     pop    h
  1197.     ret
  1198. ;
  1199. ; output 3 blanks, 4th if a = 8 n entry
  1200. ; a,f
  1201. blks43:    cpi    8
  1202.     cz    blank
  1203. ;    "    "
  1204. ; output 3 blanks
  1205. ; a,f
  1206. trplbk:    call    blank
  1207. ;    "    "
  1208. ; output 2 blanks
  1209. ; a,f
  1210. dblblk:    call    blank
  1211.     jmp    blank
  1212. ;
  1213. ; t4hx with trailing blank
  1214. t4hxblk:
  1215.     call    t4hx
  1216. ;    "    "
  1217. ; output blank to console
  1218. ; a,f
  1219. blank:    mvi    a,' ';        blank
  1220. ;    "    "
  1221. ; output (a) to console
  1222. ; a,f
  1223. couta:    push    d
  1224.     mov    e,a
  1225.     mvi    a,02
  1226.     call    dos;        put console char
  1227.     pop    d
  1228.     ret
  1229. ;
  1230. ; upshift (a) if lower case
  1231. ; a,f
  1232. upshift:
  1233.     cpi    'z'+1
  1234.     rnc
  1235.     cpi    'a'
  1236.     rc
  1237.     ani    5fh
  1238.     ret
  1239. ;
  1240. ; getline and first char
  1241. newln:    call    getline
  1242. ;    "    "
  1243. ; (a) := next char from console buffer, upshifted
  1244. ; At line end a stream of <cr>s will be returned.
  1245. ; compared to cr on exit.
  1246. ; a,f
  1247. nextch:    call    nxtch
  1248.     call    upshift
  1249.     cpi    cr
  1250.     ret
  1251. ;
  1252. ; (a) := next char from console buffer, NOT upshifted
  1253. ; At line end a stream of <cr>s will be returned.
  1254. ; Compared to cr on exit
  1255. ; a,f
  1256. nxtch:    push    h
  1257.     lxi    h,consbuf+1
  1258.     mov    a,m
  1259.     ora    a
  1260.     mvi    a,cr
  1261.     jz    nxtch1
  1262.     dcr    m
  1263.     lhld    lnptr
  1264.     mov    a,m
  1265.     inx    h
  1266.     shld    lnptr
  1267. nxtch1:    pop    h
  1268.     cpi    cr
  1269.     ret
  1270. ;
  1271. ; Skip input blanks.  z flag for eol.  Return non-blk char.
  1272. ; a,f
  1273. skipblks:
  1274.     call    nextch
  1275.     rz
  1276.     cpi    ' '
  1277.     jz    skipblks
  1278.     ret
  1279. ;
  1280. ; cr & lf to console
  1281. ; a,f
  1282. crlf:    mvi    a,cr
  1283.     call    couta
  1284.     mvi    a,lf
  1285.     jmp    couta
  1286. ;
  1287. ; get console status.  nz if char ready
  1288. ; a,f
  1289. csta:    mvi    a,11
  1290.     call    dos
  1291.     ani    1
  1292.     ret
  1293. ;
  1294. ; output $ terminated string de^
  1295. ; a,f
  1296. tstr:    mvi    a,9
  1297. ;    "    "
  1298. ; call dos function a, preserve registers
  1299. dos:    push b    ! push d ! push h
  1300.     mov    c,a
  1301.     call    .bdosexu
  1302.     pop h    ! pop d ! pop b
  1303.     ret
  1304. ;
  1305. ; output (bc) as 4 hex characters with trailing blank
  1306. ; a,f
  1307. t4hxbc:    push    h
  1308.     mov h,b    ! mov l,c
  1309.     call    t4hxblk
  1310.     pop    h
  1311.     ret
  1312. ;
  1313. dumpdone:
  1314.     mov    a,h
  1315.     ora    l
  1316.     stc
  1317.     rz;            prevent wrap arounds
  1318.     xchg;            dumpdone
  1319.     lhld    dumplast
  1320.     xchg
  1321. ;    "    "
  1322. ; zero flag if (hl) = (de), carry if (hl) > (de)
  1323. ; a,f
  1324. delesshl:
  1325.     mov a,d    ! sub h
  1326.     rnz
  1327.     mov a,e    ! sub l
  1328.     ret
  1329. ;
  1330. ; next char and check for delimiter
  1331. nxtchq:    call    nextch
  1332. ;    "    "
  1333. qdelim:    cpi ','    ! rz
  1334.     cpi ']' ! rz
  1335. ;    "    "
  1336. ; filename delimiters, z if so, carry for control
  1337. qfndelim:
  1338.     cpi cr    ! rz
  1339.     cpi tab    ! rz
  1340.     cpi '.'    ! rz
  1341.     cpi ' '    ! ret
  1342. ;
  1343. ; get character, and check for hex
  1344. getch:    call    charead
  1345. ;    "    "
  1346. ; check (a) is hex char, convert to binary.
  1347. ; divert to "err" if not.  carry for decimal digit range
  1348. ; a,f
  1349. chkhex:    sui    '0'
  1350.     cpi    10
  1351.     rc
  1352.     adi    0f9h
  1353.     cpi    16
  1354.     jnc    err
  1355.     cpi    10
  1356.     rnc
  1357.     jmp    err
  1358. ;
  1359. ; get next parameter from (de)^ to (hl)
  1360. ; de := de+2, hl
  1361. nextparm:
  1362.     xchg
  1363.     call    ldem
  1364.     xchg
  1365.     ret
  1366. ;
  1367. ; read next hex value, get next char
  1368. ; a,f,d,e
  1369. rdhex:    call    nextch
  1370. ;    "    "
  1371. ; read next hex value from command line to (de);
  1372. ; initial character in (a)
  1373. ; a,f,d,e
  1374. rdhexc:    cpi    ' '
  1375.     jz    rdhex;        deblank
  1376.     xchg
  1377.     lxi    h,0000
  1378.     cpi    '#'
  1379.     jz    rdec;        get a decimal parameter
  1380.     cpi    ''''
  1381.     jz    rdchar
  1382.     cpi    '"'
  1383.     jz    rdchar
  1384. rdhex1:    call    chkhex
  1385.     dad h    ! dad h ! dad h ! dad h
  1386.     ora l    ! mov l,a
  1387.     call    nxtchq
  1388.     jnz    rdhex1
  1389. rdhex2:    xchg
  1390.     ret
  1391. ;
  1392. ; read a char parameter to hl, terminated by (a) on input.
  1393. ; 2 chars max. Exchange with de
  1394. ; a,f,d,e (net via rdhex entry)
  1395. rdchar:    push    d
  1396.     mov    d,a
  1397.     call    nxtch
  1398.     jz    err
  1399.     mov    l,a
  1400.     call    nxtch
  1401.     jz    err
  1402.     cmp    d
  1403.     jz    rdc1
  1404.     mov    h,a
  1405.     call    nxtch
  1406.     cmp    d
  1407.     jnz    err
  1408. rdc1:    call    nxtch;        get delimiter
  1409.     call    qdelim
  1410.     jnz    err
  1411.     pop    d
  1412.     xchg
  1413.     ret
  1414. ;
  1415. ; read a decimal parameter to (hl), xchange with (de)
  1416. ; a,f,d,e (net via rdhex entry)
  1417. rdec:    call    nxtchq
  1418.     jz    rdhex2
  1419.     call    chkhex
  1420.     jnc    err;        non numeric character
  1421.     push    d
  1422.     mov d,h    ! mov e,l
  1423.     dad h    ! dad h;    4*
  1424.     dad    d;        5*
  1425.     pop    d
  1426.     dad    h;        10*
  1427.     call    index;        + (a)
  1428.     jmp    rdec
  1429. ;
  1430. ; store (de) in (hl)^, increment params
  1431. ; f, hl := hl+2
  1432. storede:
  1433.     push    h
  1434.     lxi    h,params
  1435.     inr    m
  1436.     pop    h
  1437. ;    "    "
  1438. ; store de in hl^, advance hl
  1439. ; h,l
  1440. sdem:    mov m,e    ! inx h
  1441.     mov m,d    ! inx h
  1442.     ret
  1443. ;
  1444. subttl    parameter input
  1445. ;
  1446. ckpcnt:    call    chkused
  1447.     jnc    err;        command not available now
  1448. ;    "    "        else go do pcnt and return
  1449. ; count parameters available and parse them
  1450. ; (a) returns count of parameters. z flag set on it
  1451. ; de points to first parameter storage point
  1452. ; If the first parameter is skipped return cy and 8 bit in (a)
  1453. ; Set hl to 0
  1454. ; a,f,d,e,h,l
  1455. pcnt:    call    skipblks
  1456. ;    "    "
  1457. ; pcnt with first character in (a)
  1458. ; a,f,d,e,h,l
  1459. pcnta:    lxi    h,params
  1460.     mvi    m,0
  1461.     inx    h
  1462.     cpi    cr
  1463.     jz    pcnt3
  1464.     cpi    ','
  1465.     jnz    pcnt1
  1466.     mvi    a,80h
  1467.     sta    params
  1468.     lxi    d,0
  1469. pcnt1:    cnz    rdhexc
  1470.     call    storede
  1471.     cpi    cr
  1472.     jz    pcnt3
  1473.     call    rdhex
  1474.     call    storede
  1475.     cpi    cr
  1476.     jz    pcnt3
  1477.     call    rdhex
  1478.     call    storede
  1479.     cpi    cr
  1480.     jnz    err
  1481. pcnt3:    lxi    d,params
  1482.     ldax    d
  1483.     cpi    81h
  1484.     jz    err
  1485.     lxi    h,0
  1486.     inx    d
  1487.     ora a    ! rlc ! rrc;    sign to carry
  1488.     ret
  1489. ;
  1490. subttl    Trapping
  1491. ;
  1492. ; clear any traps
  1493. ; If (bc) a trap point then pcsave := (bc)
  1494. ; a,f,d,e,h,l
  1495. clrtrps:
  1496.     lxi    h,trp1set
  1497.     mov    a,m;        count of traps set
  1498.     mvi    m,00
  1499.     inr    a
  1500. clrtrps1:
  1501.     dcr    a
  1502.     rz;            all cleared
  1503.     push    psw
  1504.     inx h    ! mov e,m;    clear traps
  1505.     inx h    ! mov d,m;    trap location
  1506.     call    delessbc
  1507.     jnz    clrtrps2;    not trapped on this one
  1508.     push    h
  1509.     mov h,b    ! mov l,c
  1510.     shld    pcsave
  1511.     pop    h
  1512. clrtrps2:
  1513.     inx    h
  1514.     mov    a,m;        original code (saved)
  1515.     stax    d
  1516.     pop    psw
  1517.     jmp    clrtrps1
  1518. ;
  1519. regnames:
  1520.     db    'CZMEIABDHSP'
  1521. ;
  1522. reglocns:
  1523.     db    boffset, doffset, hoffset, soffset, poffset
  1524. ;
  1525. flgbits:
  1526.     db    1,7,8,3,5
  1527. ;
  1528. zerotctr:
  1529.     lxi    h,0
  1530.     shld    tracectr
  1531.     ret
  1532. ;
  1533. ; trap entry via RST
  1534. trapit:    di
  1535.     shld    hlsave;        Save all 8080 regs.
  1536.     pop    h
  1537.     shld    pcsave
  1538.     push    psw
  1539.     lxi    h,0002
  1540.     dad    sp
  1541.     pop    psw
  1542.     lxi    sp,spsave+2
  1543.     push h    ! push psw ! push b !push d;    8080 regs saved.
  1544.     call    savz80;        save auxiliary registers
  1545.     lhld    pcsave
  1546.     mov b,h    ! mov c,l;    save trap point
  1547.     dcx    b;        point before trapping instruction
  1548.     call    clrtrps
  1549.     ei
  1550.     lhld    tracectr
  1551.     mov a,h    ! ora l
  1552.     jz    trapit5
  1553.     dcx    h
  1554.     shld    tracectr
  1555.     call    csta
  1556.     jnz    trapit5;    interrupted
  1557.     lda    showtrc
  1558.     ora    a
  1559.     jnz    showrun
  1560.     call    setraps
  1561.     jmp    run
  1562. trapit5:
  1563.     call    zerotctr
  1564.     mvi    a,'*'
  1565.     call    couta
  1566.     lhld    pcsave
  1567.     call    t4hx
  1568.     call    showcpu
  1569.     jmp    cmdloop
  1570. ;
  1571. ; save auxiliary z80 registers.  Main set is free
  1572. ; interrupts are disabled
  1573. savz80:    call    qz80
  1574.     rz;            cant execute instructions
  1575.     exaf
  1576.     push    psw
  1577.     exaf
  1578.     pop    h
  1579.     shld    afprime
  1580.     lxi    h,0
  1581.     dad    sp;        save stack, use sp as index
  1582.     lxi    sp,afprime
  1583.     exx
  1584.     push b    ! push d ! push h
  1585.     pushix
  1586.     pushiy
  1587.     exx
  1588.     sphl;            restore stack
  1589.     ldai
  1590.     mov l,a
  1591.     ldar
  1592.     mov h,a
  1593.     shld    ireg
  1594.     ret
  1595. ;
  1596. ; index word (hl) := (hl) + 2 * (a)  [max a =127]
  1597. ; a,f,h,l
  1598. indexwd:
  1599.     add    a
  1600. ;    "    "
  1601. ; index (hl) := (hl) + (a)
  1602. ; a,f,h,l
  1603. index:    add    l
  1604.     mov    l,a
  1605.     rnc
  1606.     inr    h
  1607.     ret
  1608. ;
  1609. ; transfer to case (a) on table (hl)^
  1610. ; a,f,h,l (and routine)
  1611. casexfr:
  1612.     call    indexwd
  1613.     mov a,m    ! inx h ! mov h,m ! mov    l,a
  1614.     pchl
  1615. ;
  1616. subttl    Trap setting, code analysis
  1617. ;
  1618. ; at entry hl points to op to decode
  1619. ; at exit, de = primary trap, bc = secondary trap
  1620. ; and hl points past the instruction, for tracing etc.
  1621. ; z flag set to release control (xfr to system),
  1622. ; else (a) = 2 for 1 trap, 3 for 2 traps, carry set
  1623. ; a,f,b,c,d,e,h,l
  1624. setraps:
  1625.     lhld    pcsave
  1626.     lxi    d, progrtn
  1627.     call    delesshl
  1628.     rz;            release control on outer block ret
  1629.     mov    b,m
  1630.     xchg
  1631.     lxi    h,reboot
  1632.     call    delesshl
  1633.     rz;            release control on reboot
  1634.     mvi    a,0c7h+8*traplvl;    (rst traplvl)
  1635.     cmp    b
  1636.     rz;            release control on trap instr.
  1637. ;    "    "
  1638. ; Entry here, with op pointer in de, avoids release control exits
  1639. ; a,f,b,c,d,e,h,l
  1640. chkop:    ldax    d
  1641.     mov    b,a
  1642.     inx    d
  1643.     push    d;        stack a possible word operand ptr
  1644.     call    optype;        (or next adr=trap pt for 1 byte ops)
  1645.     sta    opkind;        preserve for disassembler use
  1646.     push    d
  1647.     ret;            to xfr address from table.
  1648. ;
  1649. ; Return a := opcode classification for opcode (b)
  1650. ; de = action address, h=xtended length, l=prefixed length (added)
  1651. ; a,f,d,e,h,l
  1652. optype:    mvi    d,-1
  1653.     lxi    h,opmsktbl-4
  1654. optype1:
  1655.     inr    d
  1656.     inx h    ! inx h ! inx h ! inx h
  1657.     mov a,m    ! ana b ! inx h
  1658.     cmp m    ! inx h
  1659.     mov    a,d
  1660.     jnz    optype1
  1661.     mov e,m    ! inx h ! mov d,m;    de := action point
  1662.     inx    h
  1663.     push    psw
  1664.     mov a,m ! inx h ! mov l,m ! mov h,a
  1665.     pop    psw
  1666.     ret
  1667. ;
  1668. op    macro    mask, val, action, lghxtnd, lghidx
  1669.     db    mask, val
  1670.     dw    action
  1671.     db    lghxtnd,lghidx
  1672.     endm
  1673. ;
  1674. ; Table allows recognition of Z80 opcode lengths.
  1675. ; * marks items whose order in table is important.
  1676. ; Early entries found first.
  1677. opmsktbl:
  1678. ;  mask  val  exec. xtnd index  (SEE op macro ABOVE)
  1679.  op 0ffh,076h,opmovetc,1,0;    0 *mov m,m hlt    76 (eliminate in all)
  1680.  op 0cfh,009h,opmovetc,2,1;    1  dad        9 19 29 39    
  1681.  op 0f7h,022h,oplxietc,1,3;    2  lhld shld    22 2a
  1682.  op 0f7h,023h,opmovetc,1,1;    3  inc/dec hl    23 2b
  1683.  op 0feh,034h,opmovetc,1,2;     4  inr/dcr m    34 35
  1684.  op 0ffh,036h,opmvietc,1,3;    5 *mvi m    36
  1685.  op 0c7h,046h,opmovetc,1,2;    6 *mov rr,m   46 4e 56 5e 66 6e (76) 7e
  1686.  op 0ffh,073h,opmovetc,3,2;     7 *mov m,e      73
  1687.  op 0efh,064h,opmovetc,2,2;    8 *mov h,h, mov m,h   64 74 (for 64180)
  1688.  op 0f8h,070h,opmovetc,1,2;     9 *mov m,r  70 71 72 (73 74) 75 (76) 77
  1689.  op 0c7h,086h,opmovetc,1,2;     10 arith m    86 8e 96 9e a6 ae b6 be
  1690.  op 0ffh,021h,oplxietc,2,3;    11*lxi h    21
  1691.  op 0ffh,0cbh,opbitpic,1,3;    12 set/res/bit/shifts    0cb
  1692.  op 0ffh,0e3h,opmovetc,1,1;    13 xthl        e3
  1693.  op 0fbh,0e1h,opmovetc,1,1;    14 pop/push hl    e1 e5
  1694. xyjmp    equ    ($-opmsktbl)/6
  1695.  op 0ffh,0e9h,oppchl,  1,1;    15 pchl        0e9
  1696.  op 0ffh,0f9h,opmovetc,1,1;    16 sphl        0f9
  1697. ; The above portion order is wired into the disassembler section
  1698.  
  1699.  op 0ffh,0edh,opextend,1,0;    17 extension    ed
  1700.  op 0c7h,043h,opmovetc,3,1;    18 mov rr,e    43 4b 53 5b 63 6b 73 7b
  1701. reti    equ    ($-opmsktbl)/6
  1702.  op 0f7h,045h,opmovetc,1,1;    19 mov (retn, reti)    45,4d
  1703.  op 0dfh,0ddh,opxyregs,1,0;    20 x/y prefixes        dd fd
  1704.  
  1705.  op 0f7h,000h,opmovetc,2,0;    21*exaf,nop    0 8
  1706.  op 0c7h,000h,opjr,    2,0;    22*jr/djnz  (0 8) 10 18 20 28 30 38
  1707.  op 0ffh,0c3h,opcaljmp,1,0;    23 jmp        0c3 
  1708.  op 0ffh,0cdh,opcaljmp,1,0;    24 call        0cd
  1709.  op 0f7h,032h,oplxietc,1,0;    25 lda sta    32 3a
  1710.  op 0ffh,0c9h,opreturn,1,0;    26 ret        0c9
  1711.  op 0c7h,0c7h,oprstnn, 1,0;    27 rst        c7 cf d7 df e7 ef f7 ff
  1712.  op 0c7h,006h,opmvietc,1,2;    28*mvi        6 e 16 1e 26 2e (36) 3e
  1713.  op 0c7h,0c6h,opmvietc,1,0;    29 aritopi    c6 ce d6 de e6 ee f6 fe
  1714.  op 0c7h,0c2h,opcjccd, 1,0;    30 j(ccd)    c2 ca d2 da e2 ea f2 fa
  1715.  op 0c7h,0c4h,opcjccd, 1,0;    31 c(ccd)    c4 cc d4 dc e4 ec f4 fc
  1716.  op 0c7h,0c0h,oprccode,1,0;    32 r(ccd)    c0 c8 d0 d8 e0 e8 f0 f8
  1717.  op 0cfh,001h,oplxietc,2,0;    33*lxi         1 11 (21) 31
  1718.  op 0f7h,0d3h,opmvietc,1,0;    34 in/out    d3 db
  1719.  op 000h,000h,opmovetc,1,1;    35 the rest, all 1 byte
  1720. ;
  1721. ; ---- Cases for SETRAPS execution -----
  1722. ;
  1723. ; Check for z80 operating, and set opflg for this op if so
  1724. ; z flag if not z80 in operation
  1725. ; a,f
  1726. qz80:    lda    z80flg
  1727.     ora    a
  1728.     ret
  1729. ;
  1730. ; 0cbh - bit pickers
  1731. opbitpic:
  1732.     call    qz80
  1733.     jz    opmovetc
  1734.     pop    h
  1735.     inx    h
  1736.     jmp    opxtnd2
  1737. ;
  1738. ; 0ddh & 0fdh - x/y index reg ops
  1739. opxyregs:
  1740.     call    qz80
  1741.     jz    opmovetc
  1742.     pop h    ! push h ! mov b,m
  1743.     call    optype
  1744.     sta    zopkind;    save for disassembler
  1745.     cpi    xyjmp
  1746.     mov    a,l;        opcode length
  1747.     jnz    opxtnd1
  1748.     pop    h
  1749.     dcx    h
  1750.     mov    a,m;        which index
  1751.     inx    h
  1752.     inx    h
  1753.     push    h;        advance, length 2
  1754.     cpi    0ddh
  1755.     lhld    ixreg
  1756.     jz    oppchl1
  1757.     lhld    iyreg
  1758.     jmp    oppchl1
  1759. ;
  1760. ; 0edh - extension
  1761. opextend:
  1762.     call    qz80
  1763.     jz    opmovetc;    1 byte nop on 8080
  1764.     pop h    ! push h ! mov b,m
  1765.     call    optype
  1766.     sta    zopkind;    save for disassembler
  1767.     cpi    reti
  1768.     jz    opreti
  1769.     mov    a,h;        size
  1770. opxtnd1:
  1771.     pop    h
  1772.     call    index;        point past instruction
  1773. opxtnd2:
  1774.     push    h
  1775.     jmp    opmovetc
  1776. ;
  1777. opreti:    pop h    ! inx h    ! push h
  1778.     jmp    opreturn
  1779. ;
  1780. opjr:    call    qz80
  1781.     jz    opmovetc
  1782.     pop    h
  1783.     mov    a,m
  1784.     inx    h
  1785.     push    h
  1786.     mov    e,a
  1787.     ral;            sign to carry
  1788.     sbb    a;        extend sign
  1789.     mov    d,a
  1790.     dad    d
  1791.     xchg
  1792.     jmp    setrapx2
  1793. ;
  1794. ; jmp/call
  1795. opcaljmp:
  1796.     call    operand
  1797.     jnz    setrapx1
  1798. ;    "    "
  1799. ; ret
  1800. opreturn:
  1801.     call    stacktop
  1802.     jmp    setrapx1
  1803. ;
  1804. ; rst n
  1805. oprstnn:
  1806.     mov    a,b
  1807.     ani    38h
  1808.     mov    e,a
  1809.     mvi    d,0
  1810.     jmp    setrapx1
  1811. ;
  1812. ; pchl
  1813. oppchl:    lhld    hlsave
  1814. oppchl1:
  1815.     xchg
  1816.     call    qsyscall
  1817.     jnz    setrapx1
  1818.     jmp    opreturn
  1819. ;
  1820. ; j(ccd)/c(ccd)
  1821. opcjccd:
  1822.     call    operand
  1823.     jnz    setrapx2
  1824. ;    "    "
  1825. ; mov etc (one byte, no xfrs)
  1826. opmovetc:
  1827.     pop d    ! push d
  1828.     jmp    setrapx1
  1829. ;
  1830. ; r(ccd)
  1831. oprccode:
  1832.     call    stacktop
  1833. ;    "    "
  1834. ; set two traps.  bc is following op, de is destination
  1835. setrapx2:
  1836.     pop b    ! push b
  1837.     mvi    a,02
  1838.     jmp    setrapx
  1839. ;
  1840. ; lxi, lhld, shld, lda, sta
  1841. oplxietc:
  1842.     pop d    ! inx d ! push d
  1843. ;    "    "
  1844. ; mvi, in, out, aritopi (ex cpi)
  1845. opmvietc:
  1846.     pop d    ! inx d ! push d
  1847. ;    "    "
  1848. ; To set one trap only
  1849. setrapx1:
  1850.     mvi    a,01
  1851. ;    "    "
  1852. ; To set (a) traps
  1853. setrapx:
  1854.     inr    a
  1855.     stc
  1856.     pop    h;        set hl to next op code (for lgh)
  1857.     ret
  1858. ;
  1859. ;    ----    Subroutines for SETRAPS    ----
  1860. ;
  1861. ; load de := wd operand pointed at by TOS of caller. 
  1862. ; z flag if system entry point
  1863. ; a,f,b,c,d,e,h,l
  1864. operand:
  1865.     pop b    ! pop h
  1866.     call    ldem
  1867.     push h    ! push b
  1868. ;    "    "
  1869. ; z flag if (de)=system transfer point
  1870. ; a,f,h,l
  1871. qsyscall:
  1872.     lhld    bdos+1
  1873.     call    delesshl
  1874.     rz
  1875.     lda    reboot+2
  1876.     cmp    d
  1877.     rz;            a direct bios call
  1878.     lhld    .bdosexu+1;    catches lxi h,bdos; push h; ret
  1879.     jmp    delesshl
  1880. ;
  1881. ; Set de to value on top of run-time stack
  1882. ; d,e,h,l
  1883. stacktop:
  1884.     lhld    spsave
  1885. ;    "    "
  1886. ; load de from hl^, advance hl
  1887. ; d,e,h,l
  1888. ldem:    mov e,m    ! inx h ! mov d,m ! inx h
  1889.     ret
  1890. ;
  1891. subttl    -----    Initialization - used once only    -----
  1892. ;
  1893. ; Initialization
  1894. init:    lhld    bdos+1
  1895.     shld    .bdosexu+1
  1896.     mvi    c,6
  1897.     lxi    d,.bdos
  1898. init1:    dcx h    ! dcx d
  1899.     mov a,m    ! stax    d
  1900.     dcr    c
  1901.     jnz    init1;        copy serial etc - look like bdos
  1902.     lxi    h,.bdosexu
  1903.     shld    .bdos+1
  1904.     lxi    h,.bdos
  1905.     shld    bdos+1
  1906.     lxi    d,signon
  1907.     call    tstr
  1908.     mvi    a,0c3h;        (jmp)
  1909.     sta    8*traplvl
  1910.     lxi    h,trapit
  1911.     shld    8*traplvl+1
  1912.     lxi    h,firstoclear
  1913.     mvi    c,lastoclear-firstoclear
  1914. init2:    mvi    m,0;        We are using the CCP stack
  1915.     inx    h
  1916.     dcr    c
  1917.     jnz    init2;        clear it all out
  1918.     mvi    a,cbufsiz
  1919.     sta    consbuf
  1920.     lxi    h,tpa
  1921.     shld    disasmp
  1922.     shld    dumptr
  1923.     shld    unloaded
  1924.     shld    pcsave;        must be at or before operand locn
  1925. xmk    equ    $-ddtbgn;    for overlay error checking
  1926.     lxi    sp,pcsave
  1927.     lxi    h,0
  1928.     mvi    c,(pcsave - stack)/2
  1929. init3:    push    h
  1930.     dcr    c
  1931.     jnz    init3;        clear 8080 reg. images
  1932.     lxi    d,progrtn
  1933.     push    d;        default return for loading
  1934.     push    h;        default bias for loading
  1935.     lxi    d,c8080
  1936.     stc
  1937.     sbb    a
  1938.     jpe    init6;        z80 clears overflow
  1939.     sta    z80flg
  1940.     lxi    d,cz80
  1941. init6:    call    tstr
  1942.     lda    tfcb+1
  1943.     cpi    ' '
  1944.     jnz    loadit
  1945.     jmp    progrtn;    MUST be last instruction
  1946. ;
  1947. ; This definition re-uses the init area as execute time stack
  1948. return    equ    $-2;        rejammed to "progrtn"
  1949. ;
  1950. ;
  1951. subttl    ----    Initialized storage    -----
  1952. ;
  1953. consbuf:    db    cbufsiz
  1954. ; signon is stored in console buffer area, overwritten
  1955. signon:        db    'DDTZ v'
  1956.         db    ver/10 + '0', '.', ver MOD 10 +'0',debugver
  1957.         db    ' by CB Falconer. CPU=$'
  1958. c8080:        db    '8080$'
  1959. cz80:        db    'Z80$'
  1960. cbufused    equ    $-consbuf
  1961. firstoclear:
  1962. ;
  1963. ; Macro for storage allocation errors only, SLRMAC specific
  1964. px    macro    v, xmsg
  1965.     .printx    v&xmsg
  1966.     endm
  1967. ;
  1968. ; Code storage space for this segment
  1969. codesize    equ    $-ddtbgn;    for loader/relocater
  1970. ;
  1971. subttl    ----    Uninitialized storage    -----
  1972. ;
  1973.         org    signon;        Re-use signon space
  1974.         ds    1;        returned length
  1975.         ds    cbufsiz;    actual storage
  1976. ;
  1977.     if    ($-consbuf) LT cbufused
  1978. xtra     set    cbufused - ($-consbuf)
  1979.      +++ ERROR signon too long for overlay +++
  1980.     px     %xtra, < excess bytes>
  1981.     endif
  1982. ;
  1983. ; Following are uninitialized variables (also last of above buffer)
  1984. z80flg:        ds    1;    Is a Z80 running?
  1985. ;
  1986. ; Storage for auxiliary Z80 registers
  1987. iyreg:        ds    2
  1988. ixreg:        ds    2
  1989. hlprime:    ds    2
  1990. deprime:    ds    2
  1991. bcprime:    ds    2
  1992. afprime:    ds    2
  1993. ireg:        ds    1
  1994. rreg:        ds    1;    saved, but never restored.
  1995. ;
  1996. base        ds    2;    base for offset displays
  1997. baseval        ds    2;    recorded base, set by @
  1998. ;
  1999. unloaded:    ds    2;    Marks memory not loaded
  2000. tracectr:    ds    2;    Counter for steps to execute
  2001. showtrc:    ds    1;    Flag to trace each step
  2002. trp1set:    ds    1;    count of traps set
  2003.         ds    2;    location of first trap
  2004.         ds    1;    saved opcode at 1st trap
  2005.         ds    3;    second trap, as 1st trap
  2006. lastoclear:
  2007. ;
  2008. ; Storage and code for this segment
  2009. pages        equ    (($-ddtbgn)+255) / 256;    for loader
  2010. ;
  2011. ; Following storage overlays the initialization code.
  2012.         org    init;        reuse this space
  2013. ;
  2014. ; dis/assembler communication variables
  2015. disasmp:    ds    2
  2016. dendptr:    ds    2
  2017. aflag:        ds    1;    reserve for decoupling dis/assem
  2018. opkind:        ds    1;    set by chkop
  2019. zopkind:    ds    1;    set on z80 only code
  2020. ;
  2021. ; Dump control
  2022. dumptr:        ds    2;    Next to dump for D command
  2023. dumplast:    ds    2;    last to dump
  2024. ;
  2025. ; input processing
  2026. lnptr:        ds    2;    pointer to unused char in consbuf
  2027. params:        ds    7;    1st is count, then input params
  2028. charcntr:    ds    1;    for hex input
  2029. ;
  2030.         ds    stksize;    DDT run time stack
  2031. stack:
  2032. desave:        ds    2;        on TOS when control xfr
  2033. bcsave:        ds    2
  2034. flgsave:    ds    1
  2035. asave:        ds    1
  2036. spsave:        ds    2
  2037. hlsave:        ds    2
  2038. pcsave:        ds    2
  2039. ;
  2040.     if    ($-ddtbgn) GT xmk
  2041. xtra     set    ($-ddtbgn) - xmk
  2042.      +++ ERROR too much stack space for overlay +++
  2043.      px    %xtra, < excess bytes>
  2044.     endif
  2045. ;
  2046. poffset        equ    pcsave-$;    offsets for display/modify
  2047. soffset        equ    spsave-$
  2048. hoffset        equ    hlsave-$
  2049. doffset        equ    desave-$
  2050. boffset        equ    bcsave-$
  2051. ;
  2052. ; Working variables for dis/assembler section.
  2053. storeptr:    ds    2
  2054. exitstk:    ds    2
  2055. buff:        ds    16
  2056. ;
  2057. usrstack    equ    return-$
  2058.     px    %usrstack, < bytes in user stack>
  2059. ;
  2060.     org    lastoclear;    for slrmac bug
  2061. ;
  2062.     end
  2063. »°