home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol165 / nddt.asm < prev    next >
Assembly Source File  |  1984-07-08  |  55KB  |  3,268 lines

  1.  
  2. ;    --------------------------------------------------------
  3. ;    DDT.COM is a part of the collection of programs which
  4. ;    one receives when buying CP/M from Digital Research. Of
  5. ;    all the programs in the CP/M package, it is one of the
  6. ;    weakest, and seems to have been mainly intended to use
  7. ;    to insert the custom part of BIOS into CP/M when it is
  8. ;    desired to generate a new system. Its strongest point is
  9. ;    its single step facility and its suppression during the
  10. ;    execution of BDOS. Its most frustrating point may be its
  11. ;    lack of transparency to the command line of programs to
  12. ;    which it is to be applied.
  13. ;
  14. ;    The present program was based on a disassembly of the
  15. ;    Digital Research version, which has now been very
  16. ;    extensively rearranged, even though vestiges of that
  17. ;    original program still remain. Several minor errors
  18. ;    have been corrected, but the important changes consist
  19. ;    in the greatly expanded capabilities of most of the
  20. ;    options, besides a complete replacement of both the
  21. ;    assembler and the disassembler. Many commands now admit
  22. ;    a repeat factor, examination of registers and memory is
  23. ;    much more extensive, and a bitmap can generated to mark
  24. ;    significant memory locations. Other modifications or
  25. ;    extensions may be deduced from the change log below.
  26. ;
  27. ;    Since DDT will be coresident with the program it will
  28. ;    examine, it is convenient to relocate it to high memory
  29. ;    and adjust the BDOS call to reflect less free space. If
  30. ;    an origin for the relocated DDT can be assigned, a small
  31. ;    translation program is included to move it once loaded.
  32. ;    It has been disabled by commenting it out. It would have
  33. ;    to be assembled by Microsoft's M80 or a similar assembler
  34. ;    allowing phasing and dephasing. It is much more general
  35. ;    to generate a bitmap for a page relocator, for which the
  36. ;    following script will serve as a guide. It assumes that
  37. ;    the utilities LOHD.COM, GENBIM.COM, and PAGREL.COM are
  38. ;    available; also that two separate copies of DDT were
  39. ;    prepared: NDDT at origin 100H, and ZDDT at origin 000H,
  40. ;    but otherwise identical.
  41. ;
  42. ;        A>ASM NDDT.AAZ
  43. ;        A>ASM ZDDT.AAZ
  44. ;        A>LOHD NDDT
  45. ;        A>LOHD ZDDT
  46. ;        A>GENBIM ZDDT NDDT
  47. ;        A>NDDT PAGREL        [NEXT = 180]
  48. ;        -IZDDT.COM
  49. ;        -R100            [NEXT = 1600]
  50. ;        -IZDDT.BIM
  51. ;        -R1500            [NEXT = 1900]
  52. ;        -S103
  53. ;        . 0103 BB 00
  54. ;        . 0104 BB 02
  55. ;        . 0105 EE 00
  56. ;        . 0106 EE 16
  57. ;        h 0107 68 .
  58. ;        -^C
  59. ;        A>SAVE 24 NDDT.COM
  60. ;
  61. ;            NDDT.ASM -- Copyright (C) 1983
  62. ;            Universidad Autonoma de Puebla
  63. ;               20 November 1983
  64. ;
  65. ;    ---------------: B generates a bitmap, L shows X's.
  66. ;    ---------------: V is a T which ignores CALLs.
  67. ;    24 October 1982: R sets 007C to zero before starting.
  68. ;    24 October 1982: I will read an entire command line.
  69. ;    06 November 1982 - preliminary circulation copies.
  70. ;    12 December 1982 - XA shows both HEX, ASCII values.
  71. ;    12 December 1982 - X confirms register changes.
  72. ;    13 December 1982 - 007C zeroed while opening file.
  73. ;    13 December 1982 - I <pop h> when leaving HEX option.
  74. ;    13 December 1982 - <no extension> taken as .COM
  75. ;    13 December 1982 - P "Peek" added.
  76. ;    16 December 1982 - E "Execute" added.
  77. ;    18 December 1982 - S accepts quoted character.
  78. ;    20 December 1982 - edition for Assembler II.
  79. ;    7 August 1983 - correct overwrite of b in G.
  80. ;    7 August 1983 - zero 7C after initial program load.
  81. ;    20 August 1983 - clear memory before loading.
  82. ;    20 August 1983 - decimal prefix to all commands.
  83. ;    22 August 1983 - new format for display line.
  84. ;    22 August 1983 - En,xxxx superseded by nG,xxxx.
  85. ;    23 August 1983 - nV/, nT/, nU/ suppress display lines.
  86. ;    23 August 1983 - X=xxxx displays a window around xxxx.
  87. ;    23 August 1983 - nU superseded by nT/.
  88. ;    23 August 1983 - P incorporated into X.
  89. ;    26 August 1983 - M moves overlapping interval backwards.
  90. ;    26 August 1983 - A does not leave 3 0D's on exit.
  91. ;    28 August 1983 - General rearrangement and revision.
  92. ;    30 August 1983 - Edition for Languages II.
  93. ;    20 November 1983 - X - jz for jnz refused flag changes.
  94. ;    20 November 1983 - ASM - assembly of RST N was wrong.
  95. ;    20 November 1983 - stor - xra a to avoid false signals.
  96. ;    [Harold V. McIntosh, 20 December 1982]
  97. ;    [Harold V. McIntosh, 30 August 1983]
  98. ;    --------------------------------------------------------
  99.  
  100. HT    equ    09H    ;tab
  101. LF    equ    0AH    ;line feed
  102. CR    equ    0DH    ;carriage return
  103. KZ    equ    1AH    ;^Z
  104. RO    equ    7FH    ;rubout
  105.  
  106. ;ddtorg    equ    09000H    ;absolute DDT origin
  107. ;
  108. ;
  109. ;;    Move DDT up to higher memory.
  110. ;
  111. ;X0100:    lxi    b,enddt-begn
  112. ;X013D:    lxi    sp,begn
  113. ;    lxi    d,ddtorg
  114. ;    lxi    h,X0165
  115. ;X0158:    mov    a,b
  116. ;    ora    c
  117. ;    jz    ddtorg
  118. ;    dcx    b
  119. ;    mov    a,m
  120. ;    stax    d
  121. ;    inx    d
  122. ;    inx    h
  123. ;    jmp    X0158
  124. ;X0165:    ds    0
  125. ;
  126. ;;    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  127. ;
  128. ;    .phase    ddtorg
  129.  
  130.     org    0100H
  131.  
  132. begn:    jmp    init    ;initialize DDT
  133.  
  134. ;    ========================================================
  135. ;    Assembler for the INTEL 8080.  As a "small" assembler,
  136. ;    it is subject to the following restraints:
  137. ;        1) only hexadecimal numbers are accepted
  138. ;        2) opcode identification is merely sufficient
  139. ;        3) source code is not confined to a single line
  140. ;        4) error detection only for an unintelligible
  141. ;           opcode or field; then three zero bytes are
  142. ;           deposited to allow patches, assembler line
  143. ;           is abandoned
  144. ;        5) implausible combinations are not rejected
  145. ;
  146. ;    Register pair HL points to the byte in which the
  147. ;    assembled opcode will be stored.  If necessary, hex
  148. ;    data or address fields will be read and HL will be
  149. ;    incremented by 1, 2, or 3 as required.  Flags are valid
  150. ;    on return; zero means no error.
  151. ;
  152. ;    No RAM memory is used directly by the program, so that
  153. ;    it may be inscribed in its entirity in a PROM.  All its
  154. ;    requirements for temporary storage are met from the
  155. ;    internal registers of the 8080 or the stack.
  156. ;    ========================================================
  157.  
  158. assm:    push    h
  159.     lxi    h,stor
  160.     push    h
  161.     call    alfa
  162.     jmp    aopco
  163.  
  164. ;    Read an alpha field by ignoring leading separators,
  165. ;    storing letters in registers C,D,E, and terminating
  166. ;    reading when a separator is again encountered.  All
  167. ;    fields are held to three letters, so that the only
  168. ;    letters in a chain that are stored are the first,
  169. ;    second, and last.
  170.  
  171. alfa:    lxi    d,'  '
  172. ala:    call    relc
  173.     call    sepa
  174.     jz    ala
  175.     mov    c,a
  176.     call    relc
  177.     call    sepa
  178.     rz
  179.     call    term
  180.     rz
  181.     mov    d,a
  182. alb:    call    relc
  183.     call    sepa
  184.     rz
  185.     call    term
  186.     rz
  187.     mov    e,a
  188.     jmp    alb
  189.  
  190. ;    Read an alpha field with the intention of keeping only
  191. ;    the last letter in the field.  Otherwise the same rules
  192. ;    apply as in the subroutine alfa: leading separators are
  193. ;    ignored, trailing separators terminate.
  194.  
  195. beta:    call    relc
  196.     call    sepa
  197.     jz    beta
  198. bet:    mov    b,a
  199.     call    relc
  200.     call    sepa
  201.     jz    bta
  202.     call    term
  203.     jnz    bet
  204. bta:    mov    a,b
  205.     ret
  206.  
  207. ;    Locate the operation codes.  A simple linear search is
  208. ;    made of some sixty mnemonics, grouping them mostly in
  209. ;    sets of eight because their position within an octet
  210. ;    translates directly into a source or destination field
  211. ;    in the 2-3-3 decomposition of INTEL 8080 opcodes.
  212.  
  213. aopco:    mvi    b,0CH
  214.     lxi    H,AT4    ;Quadrant 0 with minor modifications
  215.     call    mnem
  216.     jp    AQ0
  217.     mvi    b,01H
  218.     lxi    h,AT0    ;Quadrant 1: interregister movements
  219.     call    mnem
  220.     jp    AQ1
  221.     mvi    b,08H
  222.     lxi    h,AT1    ;Quadrant 3: arithmetic-logical
  223.     call    mnem
  224.     jp    AQ2
  225.     mvi    b,08H
  226.     lxi    h,AT2    ;Quadrant 2, column 6: immediate
  227.     call    mnem
  228.     jp    AB6
  229.     mvi    b,11H
  230.     lxi    h,AT5    ;All the sporadic opcodes
  231.     call    mnem
  232.     jp    qq
  233.     mvi    b,08H
  234.     lxi    h,AT3    ;Quadrant 0, column 7: accumulator
  235.     call    mnem
  236.     jp    AA7
  237.     mov    a,c
  238.     cpi    'r'
  239.     jz    AB0    ;Quadrant 3, column 0: returns
  240.     cpi    'j'
  241.     jz    AB2    ;Quadrant 3, column 2: jumps
  242.     cpi    'c'
  243.     jz    AB4    ;Quadrant 3, column 4: calls
  244.     mvi    b,05H
  245.     lxi    h,AT7    ;Assembler directives
  246.     call    mnem
  247.     jp    QD
  248.     jmp    hexb
  249.  
  250. ;    Quadrant zero - memory to register - and some others.
  251.  
  252. AQ0:    mov    c,a
  253.     call    juta
  254.     dw    X0    ;pop  pair
  255.     dw    AA1    ;lxi  pair,addr
  256.     dw    AA0    ;stax pair  - beware - only b, d legal
  257.     dw    AA0    ;inx  pair
  258.     dw    AA4    ;inr  register
  259.     dw    AA4    ;dcr  register
  260.     dw    AA6    ;mvi  register,data
  261.     dw    AB7    ;rst  digit in opcode
  262.     dw    Y0    ;push pair
  263.     dw    AA0    ;dad  pair
  264.     dw    AA0    ;ldax pair  - beware - only b, d legal
  265.     dw    AA0    ;dcx  pair
  266.  
  267. X0:    mvi    c,0C1H
  268.     jmp    AA0
  269. Y0:    mvi    c,0C5H
  270. AA0:    call    beta
  271.     call    apair
  272.     ora    c
  273.     ret
  274.  
  275. AA1:    call    AA0
  276.     jmp    addq
  277.  
  278. AA4:    call    rdst
  279.     ora    c
  280.     ret
  281.  
  282. AA6:    call    AA4
  283.     jmp    datq
  284.  
  285. AA7:    add    a
  286.     add    a
  287.     add    a
  288.     ori    07H
  289.     ret
  290.  
  291. AQ1:    call    rdst
  292.     mov    c,a
  293.     call    rsrc
  294.     ora    c
  295.     ori    040H
  296.     ret
  297.  
  298. AQ2:    add    a
  299.     add    a
  300.     add    a
  301.     mov    c,a
  302.     call    rsrc
  303.     ora    c
  304.     ori    080H
  305.     ret
  306.  
  307. qq:    cpi    09H
  308.     jc    ss
  309.     lxi    h,adata
  310.     cpi    0BH
  311.     jc    rr
  312.     lxi    h,aaddr
  313. rr:    xthl
  314. ss:    lxi    h,AT8
  315.     jmp    reta
  316.  
  317. ;    Quadrant 3 - mostly program counter modification
  318.  
  319. AB0:    mvi    a,0C0H
  320.     jmp    abb
  321. AB2:    mvi    a,0C2H
  322.     call    abb
  323.     jmp    addq
  324. AB4:    mvi    a,0C4H
  325.     call    abb
  326.     jmp    addq
  327. abb:    push    psw
  328.     mvi    c,' '
  329.     mvi    b,08H
  330.     lxi    h,AT6
  331.     call    mnem
  332.     pop    b
  333.     jm    error
  334.     add    a
  335.     add    a
  336.     add    a
  337.     ora    b
  338.     ret
  339.  
  340. ;    Immediates.
  341.  
  342. AB6:    add    a
  343.     add    a
  344.     add    a
  345.     ori    0C6H
  346.     jmp    datq
  347.  
  348. ;    Restarts.
  349.  
  350. AB7:    call    beta
  351.     rlc
  352.     rlc
  353.     rlc
  354.     ani    038H
  355.     ori    0C7H
  356.     ret
  357.  
  358. ;    Assembler directives.
  359.  
  360. QD:    call    juta
  361.     dw    D0    ;data byte
  362.     dw    D1    ;data word
  363.     dw    D2    ;data space
  364.     dw    D3    ;origin
  365.     dw    D4    ;end
  366.  
  367. D0:    inx    sp    ;data byte
  368.     inx    sp
  369.     pop    d
  370.     call    hxar
  371.     mov    l,a
  372.     mvi    a,0FDH    ;error
  373.     rnz
  374.     inr    a    ;(org)
  375.     xchg
  376.     mov    m,e
  377.     inx    h
  378.     ret
  379.  
  380. D1:    inx    sp    ;data word
  381.     inx    sp
  382.     pop    d
  383.     call    hexf
  384.     mvi    a,0FDH    ;error
  385.     rnc
  386.     inr    a    ;(org)
  387.     xchg
  388.     mov    m,e
  389.     inx    h
  390.     mov    m,d
  391.     inx    h
  392.     ret
  393.  
  394. D2:    inx    sp    ;data space
  395.     inx    sp
  396.     pop    d
  397.     call    hexf
  398.     mvi    a,0FDH    ;error
  399.     rnc
  400.     inr    a    ;org
  401.     dad    d
  402.     ret
  403.  
  404. D3:    inx    sp    ;origin
  405.     inx    sp
  406.     inx    sp
  407.     inx    sp
  408.     call    hexf
  409.     mvi    a,0FEH    ;org
  410.     rc
  411.     dcr    a
  412.     ret
  413.  
  414. D4:    inx    sp    ;end
  415.     inx    sp
  416.     inx    sp
  417.     inx    sp
  418.     mvi    a,0FFH    ;done
  419.     ret
  420.  
  421. ;    If the operation field did not hold a valid opcode or
  422. ;    assembler directive, try it out for a one-byte, two
  423. ;    nibble hexadecimal byte.
  424.  
  425. hexb:    lxi    h,error
  426.     push    h
  427.     mov    a,e
  428.     cpi    ' '
  429.     rz
  430.     mov    a,c
  431.     call    cnh
  432.     rc
  433.     add    a
  434.     add    a
  435.     add    a
  436.     add    a
  437.     mov    b,a
  438.     mov    a,d
  439.     call    cnh
  440.     rc
  441.     add    b
  442.     inx    sp
  443.     inx    sp
  444.     ret
  445.  
  446. ;    Read and deposit a hexadecimal address field.
  447.  
  448. addq:    inx    sp
  449.     inx    sp
  450. aaddr:    mov    b,a
  451.     call    onar
  452.     xchg
  453.     pop    h
  454.     mov    m,b
  455.     inx    h
  456.     mov    m,e
  457.     inx    h
  458.     mov    m,d
  459.     inx    h
  460.     ret
  461.  
  462. ;    Read and deposit a one-byte hexadecimal data field.
  463.  
  464. datq:    inx    sp
  465.     inx    sp
  466. adata:    mov    b,a
  467.     call    hxar
  468.     jnz    error    ;<missing field>
  469.     xchg
  470.     pop    h
  471.     mov    m,b
  472.     inx    h
  473.     mov    m,e
  474.     inx    h
  475.     ret
  476.  
  477. ;    Deposit the assembled operation code
  478.  
  479. stor:    pop    h
  480.     mov    m,a
  481.     inx    h
  482.     xra    a    ;don't return the wrong signal
  483.     ret
  484.  
  485. ;    Load accumulator with nth item in the list whose
  486. ;    origin is contained in register pair HL, when n
  487. ;    lies in the accumulator.
  488.  
  489. reta:    add    l
  490.     mov    l,a
  491.     mov    a,h
  492.     aci    00H
  493.     mov    h,a
  494.     mov    a,m
  495.     ret
  496.  
  497. ;    Find numerical equivalents for register designations.
  498. ;    Source registers are reported at their true value, but
  499. ;    destination registers are multiplied by eight to have
  500. ;    their value positioned correctly for its field.
  501.  
  502. rsrc:    call    beta
  503. srce:    mvi    b,08H
  504.     lxi    h,atr
  505.     call    regi
  506.     jm    error
  507.     ret
  508.  
  509. rdst:    call    beta
  510. dest:    call    srce
  511.     add    a
  512.     add    a
  513.     add    a
  514.     ret
  515.  
  516. ;    Find numerical equivalents for register pair symbols.
  517. ;    They always left-pack their destination field.
  518.  
  519. apair:    mvi    b,05H
  520.     lxi    h,atp
  521.     call    regi
  522.     jm    error
  523.     cpi    04H
  524.     cmc
  525.     sbi    00H
  526.     mov    b,a
  527.     add    a
  528.     add    a
  529.     add    a
  530.     add    a
  531.     ret
  532.  
  533. ;    Search a list of bytes whose origin is contained in
  534. ;    in HL to find the one, if any, which matches the
  535. ;    accumulator.  The length of the list in is B on entry;
  536. ;    on exit A contains either the position or FF if no
  537. ;    match was found.
  538.  
  539. regi:    dcx    h
  540.     cmp    m
  541.     jz    reg
  542.     dcr    b
  543.     jnz    regi
  544. reg:    xra    a
  545.     dcr    b
  546.     ora    b
  547.     ret
  548.  
  549. ;    Search a table of three-letter mnemonics to find the
  550. ;    code contained in registers C,D,E.  Enter with the
  551. ;    table origin in pair HL, the table size N in the
  552. ;    accumulator.  On exit the accumulator will contain
  553. ;    either the position, ranging between 0 and N-1, of
  554. ;    the item in the table, or else FF(hex) if it was not
  555. ;    found.
  556.  
  557. mnem:    dcx    h
  558.     mov    a,m
  559.     cmp    e
  560.     jnz    mnb
  561.     dcx    h
  562.     mov    a,m
  563.     cmp    d
  564.     jnz    mnc
  565.     dcx    h
  566.     mov    a,m
  567.     sub    c
  568.     jnz    mnd
  569. mna:    dcr    b
  570.     ora    b
  571.     ret
  572. mnb:    dcx    h
  573. mnc:    dcx    h
  574. mnd:    dcr    b
  575.     jnz    mnem
  576.     jmp    mna
  577.  
  578. ;    Table of mnemonics grouped by octets and dodecuplets.
  579.  
  580. dtr:    db    'bcdehlma'
  581. atr:    db    'bdhpw'
  582. atp:    db    'mov'
  583. AT0:    db    'add','adc','sub','sbb'
  584.     db    'ana','xra','ora','cmp'
  585. AT1:    db    'adi','aci','sui','sbi'
  586.     db    'ani','xri','ori','cpi'
  587. AT2:    db    'rlc','rrc','ral','rar'
  588.     db    'daa','cma','stc','cmc'
  589. AT3:    db    'pop','lxi','stx','inx'
  590.     db    'inr','dcr','mvi','rst'
  591.     db    'puh','dad','ldx','dcx'
  592. AT4:    db    'nop','ret','pcl','spl'
  593.     db    'xtl','xcg','di ','ei '
  594.     db    'hlt','out','in ','jmp'
  595.     db    'cal','shd','lhd','sta','lda'
  596. AT5:    db    ' nz',' z ',' nc',' c '
  597.     db    ' po',' pe',' p ',' m '
  598. AT6:    db    'db ','dw ','ds ','org','end'
  599. AT7:    db    nop
  600.     db    ret
  601.     db    pchl
  602.     db    sphl
  603.     db    xthl
  604.     db    xchg
  605.     db    di
  606.     db    ei
  607.     db    hlt
  608.     db    0D3H    ;(out)
  609.     db    0DBH    ;(in)
  610.     db    0C3H    ;(jmp)
  611.     db    0CDH    ;(call)
  612.     db    022H    ;(shld)
  613.     db    02AH    ;(lhld)
  614.     db    032H    ;(sta)
  615.     db    03AH    ;(lda)
  616.  
  617. ;    T7 is the end of one table, T8 is the beginning of another.
  618.  
  619. AT8    equ    AT7
  620.  
  621.  
  622. ;    =====================================================
  623. ;    Disassembler for the INTEL 8080.  Register pair HL
  624. ;    points to the byte to be disassembled.  HL will be
  625. ;    incremented by 1, 2, or 3 according to the type of
  626. ;    instruction encountered.  No RAM storage is used
  627. ;    within the program, which may therefore be entirely
  628. ;    resident in ROM.
  629. ;    =====================================================
  630.  
  631. dism:    mov    a,m
  632.     push    h
  633.     lxi    h,done
  634.     push    h
  635.     cpi    76H
  636.     jnz    split
  637. halt:    lxi    h,td
  638.     jmp    three
  639.  
  640. ;    separate the instruction field into groups of 2,3,3
  641. ;    bits and then continue according to quadrants.
  642.  
  643. split:    push    psw
  644.     push    psw
  645.     ani    07H
  646.     mov    c,a
  647.     pop    psw
  648.     rrc
  649.     rrc
  650.     rrc
  651.     ani    07H
  652.     mov    b,a
  653.     pop    psw
  654.     rlc
  655.     rlc
  656.     ani    03H
  657.     lxi    h,jq
  658. jump:    call    bndx
  659.     mov    e,m
  660.     inx    h
  661.     mov    d,m
  662.     xchg
  663.     pchl
  664.  
  665. ;    Indexing subroutines which add corresponding multiples
  666. ;    [3,4,2,1] of A to the register pair HL.
  667.  
  668. tndx:    mov    e,a
  669.     add    a
  670.     add    e
  671.     jmp    indx
  672. qndx:    add    a
  673. bndx:    add    a
  674. indx:    add    l
  675.     mov    l,a
  676.     mov    a,h
  677.     aci    00H
  678.     mov    h,a
  679.     ret
  680.  
  681. ;    -------------------------------------------------------
  682. ;    Quadrant 0 contains accumulator operations, increments,
  683. ;    decrements, loads, stores and immediate moves, all of
  684. ;    which must be detailled further.
  685. ;    -------------------------------------------------------
  686.  
  687. DQ0:    mov    a,c
  688.     lxi    h,ja
  689.     jmp    jump
  690.  
  691. ;    Column 0 contains NOP together with seven unused codes
  692.  
  693. DA0:    mov    a,b
  694.     ora    a
  695.     jnz    node
  696. noop:    lxi    h,tc
  697.     jmp    trey
  698.  
  699. ;    Column 1 alternates lxi to a register pair with dad
  700. ;    from a register pair.  The lxi's require data words,
  701. ;    but not the dad's.
  702.  
  703. DA1:    mov    a,b
  704.     ani    01H
  705.     call    aa
  706.     mov    a,b
  707.     ani    01H
  708.     rnz
  709.     call    sngl
  710.     jmp    daddr
  711.  
  712. ;    Column 2 alternates storing and loading instructions.
  713. ;    The first six refer to register pairs, the last two to
  714. ;    the accumulator; the last four require addresses.
  715.  
  716. DA2:    mov    a,b
  717.     lxi    h,DT5
  718.     call    vier
  719.     mov    a,b
  720.     ani    04H
  721.     jz    putp
  722.     jmp    daddr
  723.  
  724. ;    Column 3 alternates inx of a register pair with dcx of
  725. ;    the same pair.
  726.  
  727. DA3:    mov    a,b
  728.     ani    01H
  729.     adi    02H
  730. aa:    lxi    h,DT4
  731.     call    drei
  732.     jmp    putp
  733.  
  734. ;    Column 4 contains inr, 5 containd dcr, both modified
  735. ;    by the register list.
  736.  
  737. DA4:    mov    a,c
  738.     lxi    h,DT4
  739.     call    drei
  740.     mov    a,b
  741.     lxi    h,dtr
  742.     jmp    ein
  743.  
  744. ;    Column 6 contains the mvi's, which require a data byte.
  745.  
  746. DA6:    call    DA4
  747.     call    sngl
  748.     jmp    ddata
  749.  
  750. ;    Column 7 contains the accumulator operations.
  751.  
  752. DA7:    mov    a,b
  753.     lxi    h,AT2
  754.     call    tndx
  755.     jmp    trey
  756.  
  757. ;    ----------------------------------------------------------
  758. ;    Quadrant 1 consists of interregister movements.
  759. ;    ----------------------------------------------------------
  760.  
  761. DQ1:    lxi    h,tb
  762.     call    three
  763.     mov    a,b
  764.     lxi    h,dtr
  765.     call    ein
  766.     call    sngl
  767.     mov    a,c
  768.     lxi    h,dtr
  769.     jmp    ein
  770.  
  771. ;    ----------------------------------------------------------
  772. ;    Quadrant 2 consists of arithmetic operations
  773. ;    ----------------------------------------------------------
  774.  
  775. DQ2:    mov    a,b
  776.     lxi    h,AT0
  777.     call    drei
  778.     mov    a,c
  779.     lxi    h,dtr
  780.     jmp    ein
  781.  
  782. ;    ---------------------------------------------------------
  783. ;    Quadrant 3 has returns, calls, jumps, pushes, pops,
  784. ;    and a variety of miscellania needing a detailed study.
  785. ;    ---------------------------------------------------------
  786.  
  787. DQ3:    mov    a,c
  788.     lxi    h,jb
  789.     jmp    jump
  790.  
  791. ;    Column 0 contains all the conditional returns
  792.  
  793. DB0:    mvi    a,'r'
  794. bb:    call    aout    ;A to console
  795.     mov    a,b
  796.     lxi    h,AT5
  797.     call    tndx
  798.     inx    h
  799.     jmp    two
  800.  
  801. ;    Column 1 contains the pops, together with the unconditional
  802. ;    return, pchl, sphl, and an undefined code.
  803.  
  804. DB1:    mov    a,b
  805.     lxi    h,DT7
  806.     call    vier
  807.     mov    a,b
  808.     cpi    03H
  809.     jz    dopco
  810.     ani    01H
  811.     rnz
  812.     jmp    putq
  813.  
  814. ;    Column 2 contains all the conditional jumps.
  815.  
  816. DB2:    mvi    a,'j'
  817.     call    bb
  818.     jmp    daddr
  819.  
  820. ;    Columnn 3 is an assortment, requiring many distinctions.
  821.  
  822. DB3:    mov    a,b
  823.     lxi    h,DT8
  824.     call    vier
  825.     mov    a,b
  826.     cpi    04H
  827.     rnc
  828.     cpi    01H
  829.     jz    dopco
  830.     jc    daddr
  831.     jmp    ddata
  832.  
  833. ;    Column 4 contains all the conditional calls.
  834.  
  835. DB4:    mvi    a,'c'
  836.     call    bb
  837.     jmp    daddr
  838.  
  839. ;    Column 5 contains the pushes, simple call, 3 undefined.
  840.  
  841. DB5:    mov    a,b
  842.     ani    01H
  843.     jnz    xx
  844.     lxi    h,tf
  845.     call    four
  846.     jmp    putq
  847. xx:    mov    a,b
  848.     cpi    01H
  849.     jnz    node
  850.     lxi    h,te
  851.     call    four
  852.     jmp    daddr
  853.  
  854. ;    Column 6 holds all the arithmetic immediates.
  855.  
  856. DB6:    mov    a,b
  857.     lxi    h,AT1
  858.     call    drei
  859.     jmp    ddata
  860.  
  861. ;    Column 7 contains all the restarts.
  862.  
  863. DB7:    lxi    h,DT4+21
  864.     call    three
  865.     mov    a,b
  866.     adi    '0'
  867.     jmp    aout    ;A to console
  868.  
  869. ;    ------------------------------------------------------
  870. ;    a collection of copying and spacing routines.
  871. ;    ------------------------------------------------------
  872.  
  873. vier:    call    qndx
  874.     jmp    four
  875. drei:    call    tndx
  876.     jmp    three
  877. ein:    call    indx
  878.     jmp    one
  879.  
  880. four:    call    quad
  881.     jmp    sngl
  882. three:    call    trey
  883.     jmp    dubl
  884. two:    call    dpair
  885.     jmp    dubl
  886.  
  887. quad:    mov    a,m
  888.     call    aout    ;A to console
  889.     inx    h
  890. trey:    mov    a,m
  891.     call    aout    ;A to console
  892.     inx    h
  893. dpair:    mov    a,m
  894.     call    aout    ;A to console
  895.     inx    h
  896. one:    mov    a,m
  897.     jmp    aout    ;A to console
  898.  
  899. ;    -------------------------------------------------------
  900. ;    Commonly used transferrence and conversion routines.
  901. ;    -------------------------------------------------------
  902.  
  903. putp:    mov    a,b
  904.     ani    06H
  905.     lxi    h,dtp
  906.     call    indx
  907.     jmp    dpair
  908.  
  909. putq:    mov    a,b
  910.     ani    06H
  911.     rrc
  912.     lxi    h,tq
  913.     call    tndx
  914.     jmp    trey
  915.  
  916. done:    pop    h
  917.     inx    h
  918.     ret
  919.  
  920. daddr:    inx    sp
  921.     inx    sp
  922.     pop    h
  923.     inx    h
  924.     mov    e,m
  925.     inx    h
  926.     mov    d,m
  927.     push    h
  928.     call    word
  929.     jmp    done
  930.  
  931. node:    lxi    h,ta
  932.     call    three
  933. dopco:    inx    sp
  934.     inx    sp
  935.     pop    h
  936.     jmp    goby
  937.  
  938. ddata:    inx    sp
  939.     inx    sp
  940.     pop    h
  941.     inx    h
  942. goby:    mov    a,m
  943.     push    h
  944.     call    byte
  945.     jmp    done
  946.  
  947. ;    --------------------------------------------------------
  948. ;    Jump tables
  949. ;    --------------------------------------------------------
  950.  
  951. jq:    dw    DQ0,DQ1,DQ2,DQ3
  952.  
  953. ja:    dw    DA0,DA1,DA2,DA3,DA4,DA4,DA6,DA7
  954.  
  955. jb:    dw    DB0,DB1,DB2,DB3,DB4,DB5,DB6,DB7
  956.  
  957. ;    --------------------------------------------------------
  958. ;    Tables of mnemonics for the 8080 instructions
  959. ;    --------------------------------------------------------
  960.  
  961. ta:    db    'db '
  962. tb:    db    'mov'
  963. tc:    db    'nop'
  964. td:    db    'hlt'
  965. te:    db    'call'
  966. tf:    db    'push'
  967.  
  968. dtp:    db    'b d h sp'
  969.  
  970. tq:    db    'b  '
  971.     db    'd  '
  972.     db    'h  '
  973.     db    'psw'
  974.  
  975. DT4:    db    'lxi','dad','inx','dcx'
  976.     db    'inr','dcr','mvi','rst'
  977.  
  978. DT5:    db    'stax','ldax','stax','ldax'
  979.     db    'shld','lhld','sta ','lda '
  980.  
  981. DT7:    db    'pop ','ret ','pop ','db  '
  982.     db    'pop ','pchl','pop ','sphl'
  983.  
  984. DT8:    db    'jmp ','db  ','out ','in  '
  985.     db    'xthl','xchg','di  ','ei  '
  986.  
  987. ;    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  988.  
  989. DP    equ    16    ;paragraph length for D
  990. NL    equ    12    ;default lines in L
  991. NR    equ    12    ;number of registers to examine in X
  992. WW    equ    5    ;window halfwidth in register display
  993.  
  994. BDOS    equ    0005H    ;jump to BDOS
  995. RST7    equ    0038H    ;DDT breakpoint handler
  996. TFCB    equ    005CH    ;DDT's file control block
  997. TBUF    equ    0080H    ;DDT's sector buffer
  998. TORG    equ    0100H    ;program origin
  999.  
  1000. bsiz    equ    2000H    ;8K = size of bitmap
  1001.  
  1002. XDOS:    xthl        ;<<DDT analogue of 0005>>
  1003.     shld    sica    ;site of call to BDOS
  1004.     xthl
  1005. GDOS:    jmp    0000    ;BDOS address
  1006.  
  1007. ;    Initialize DDT
  1008.  
  1009. init:    lhld    BDOS+1
  1010.     shld    GDOS+1        ;BDOS address
  1011.     lxi    h,XDOS        ;DDT analogue of 0005
  1012.     shld    begn+1
  1013.     lxi    h,begn
  1014.     shld    BDOS+1
  1015.     xra    a
  1016.     sta    bkpt        ;breakpoint data
  1017.     lxi    h,TORG        ;CP/M transient origin
  1018.     shld    lorg        ;origin for L
  1019.     shld    dorg        ;origin for D
  1020.     shld    pmax        ;program high limit
  1021.     shld    savpc        ;PC at breakpoint
  1022.     shld    savmr        ;memory reference
  1023.     lxi    sp,savhl    ;breakpoint
  1024.     push    h
  1025.     lxi    h,0002
  1026.     push    h
  1027.     dcx    h
  1028.     dcx    h
  1029.     shld    savhl        ;HL at breakpoint
  1030.     push    h
  1031.     push    h
  1032.     mvi    a,0C3H        ;(jmp)
  1033.     sta    RST7        ;RST 7 destination
  1034.     lxi    h,rtbk        ;return from breakpoint
  1035.     shld    RST7+1
  1036.     lxi    b,begn        ;top of memory
  1037.     lxi    h,TORG        ;bottom of memory
  1038.     mov    a,c
  1039.     sub    l
  1040.     mov    c,a
  1041.     mov    a,b
  1042.     sbb    h
  1043.     mov    b,a
  1044. zero:    mov    a,c
  1045.     ora    b
  1046.     jz    zerd
  1047.     mvi    m,00
  1048.     inx    h
  1049.     dcx    b
  1050.     jmp    zero
  1051. zerd:    lxi    h,logo        ;"DDT/UAP"
  1052.     call    mssg
  1053.     mvi    c,25        ;(19) read logged in disk
  1054.     call    XDOS
  1055.     sta    ldsk        ;logged disk
  1056.     mvi    b,80H
  1057.     lxi    d,TBUF
  1058.     lxi    h,ctex
  1059.     shld    cptr        ;pointer to command buffer
  1060.     lxi    h,clen
  1061. muve:    ldax    d
  1062.     mov    m,a
  1063.     inx    h
  1064.     inx    d
  1065.     dcr    b
  1066.     jnz    muve
  1067.     mov    m,b
  1068.     lxi    h,loop        ;DDT loop
  1069.     push    h
  1070.     lda    TFCB+1        ;file name
  1071.     cpi    ' '
  1072.     rz
  1073.     lxi    h,TFCB+9    ;extension
  1074.     mov    a,m
  1075.     cpi    ' '
  1076.     jnz    scom
  1077.     mvi    m,'C'
  1078.     inx    h
  1079.     mvi    m,'O'
  1080.     inx    h
  1081.     mvi    m,'M'
  1082. scom:    lxi    h,0000        ;zero offset
  1083.     call    opra        ;R with implicit argument
  1084.     jmp    opia        ;I after discarding program name
  1085.  
  1086. ;    ----------------------------------------------
  1087. ;    DDT loop: waits for commands and executes them
  1088. ;    ----------------------------------------------
  1089.  
  1090. loop:    lxi    sp,savde    ;DDT's private stack
  1091.     lxi    h,loop        ;DDT loop
  1092.     push    h
  1093.     call    past        ;check limit transgression
  1094.     jc    looq
  1095.     lxi    h,XDOS        ;link to BDOS
  1096.     shld    0006H
  1097. looq:    call    crlf        ;type CR,LF
  1098.     mvi    a,'-'
  1099.     call    aout        ;A to console
  1100.     call    incl        ;fetch a command line
  1101.     call    decf        ;read decimal field
  1102.     cpi    CR
  1103.     rz
  1104.     shld    rept
  1105.     call    alta        ;alternate table
  1106.     db    14
  1107.     db    'A'
  1108.     dw    opta        ;A = assemble
  1109.     db    'B'
  1110.     dw    bmap        ;B = bitmap
  1111.     db    'D'
  1112.     dw    optd        ;D = display
  1113.     db    'F'
  1114.     dw    optf        ;F = fill
  1115.     db    'G'
  1116.     dw    optg        ;G = go
  1117.     db    'H'
  1118.     dw    opth        ;H = hex sum, difference
  1119.     db    'I'
  1120.     dw    opti        ;I = initialize CCP command line
  1121.     db    'L'
  1122.     dw    optl        ;L = list program
  1123.     db    'M'
  1124.     dw    optm        ;M = move
  1125.     db    'R'
  1126.     dw    optr        ;R = read file
  1127.     db    'S'
  1128.     dw    opts        ;S = store
  1129.     db    'T'
  1130.     dw    optt        ;T = type registers
  1131.     db    'V'
  1132.     dw    optv        ;V = single step w/ call as 1 step
  1133.     db    'X'
  1134.     dw    optx        ;X = examine registers
  1135.  
  1136. ;    (A) Assemble 8080 code. <nAx> will assemble n lines
  1137. ;    of code beginning at address x. Defaults are x=lorg,
  1138. ;    while no limit is set if n is missing or zero.
  1139.  
  1140. opta:    call    past    ;check limit transgression
  1141.     jnc    error    ;<A has been overwritten>
  1142.     lhld    lorg    ;origin for L
  1143.     call    hef
  1144. opaa:    shld    lorg    ;origin for L
  1145.     call    dubl
  1146.     call    tyhl    ;type HL as four nibbles
  1147.     call    dubl
  1148.     call    incl    ;fetch a command line
  1149.     jz    opac
  1150.     call    assm
  1151.     inr    a    ;FF means done
  1152.     rz
  1153.     inr    a    ;FE means new origin
  1154.     jnz    opab
  1155.     call    crlf
  1156.     jmp    opaa
  1157. opab:    call    ctlx
  1158.     lhld    lorg    ;origin for L
  1159.     inr    a    ;FD means error - retry
  1160.     jz    opaa
  1161. opac:    call    dubl    ;otherwise confirm & advance
  1162.     call    tyhl    ;type HL as four nibbles
  1163.     call    dubl
  1164.     call    dism
  1165.     call    crlf
  1166.     call    drnz    ;decrement retn if nonzero
  1167.     jnz    opaa
  1168.     shld    lorg    ;origin for L
  1169.     ret
  1170.  
  1171. ;    (B)  Generate a bitmap of all bytes in the range
  1172. ;    100H - (pmax) which could possibly be the address
  1173. ;    of an instruction.
  1174.  
  1175. bmap:    lhld    pmax
  1176.     xchg
  1177.     lxi    h,begn
  1178.     lxi    b,-bsiz
  1179.     dad    b
  1180.     mov    a,l
  1181.     sub    e
  1182.     mov    a,h
  1183.     sbb    d
  1184.     jc    error    ;<bitmap would overlap program>
  1185.     lxi    b,bsiz
  1186. bzer:    mvi    m,00H
  1187.     inx    h
  1188.     dcx    b
  1189.     mov    a,c
  1190.     ora    b
  1191.     jnz    bzer
  1192.     lhld    pmax    ;program high limit
  1193.     xchg
  1194.     lxi    h,TORG    ;CP/M transient origin
  1195.     mov    a,e
  1196.     sub    l
  1197.     mov    c,a
  1198.     mov    a,d
  1199.     sbb    h
  1200.     mov    b,a
  1201. bbit:    push    b
  1202.     mov    a,m
  1203.     call    twob
  1204.     jnc    bbjt
  1205.     push    h
  1206.     inx    h
  1207.     mov    e,m
  1208.     inx    h
  1209.     mov    d,m
  1210.     xchg
  1211.     call    wrib
  1212.     pop    h
  1213. bbjt:    inx    h
  1214.     pop    b
  1215.     dcx    b
  1216.     mov    a,c
  1217.     ora    b
  1218.     jnz    bbit
  1219.     ret
  1220.  
  1221. ;    Decide if opcode has one-byte sequel.
  1222.  
  1223. oneb:    cpi    0D3H
  1224.     jz    oney
  1225.     cpi    0DBH
  1226.     jz    oney
  1227.     ani    0C7H
  1228.     cpi    006H
  1229.     jz    oney
  1230.     cpi    0C6H
  1231.     jz    oney
  1232.     stc
  1233.     cmc
  1234.     ret
  1235. oney:    stc
  1236.     ret
  1237.  
  1238. ;    decide if opcode has two-byte address
  1239.  
  1240. twob:    push    b
  1241.     cpi    0C3H
  1242.     jz    twoy
  1243.     cpi    0CDH
  1244.     jz    twoy
  1245.     mov    b,a
  1246.     ani    0C7H
  1247.     cpi    0C2H
  1248.     jz    twoy
  1249.     cpi    0C4H
  1250.     jz    twoy
  1251.     mov    a,b
  1252.     ani    0CFH
  1253.     cpi    001H
  1254.     jz    twoy
  1255.     mov    a,b
  1256.     ani    0E7H
  1257.     cpi    022H
  1258.     jz    twoy
  1259.     stc
  1260.     cmc
  1261.     pop    b
  1262.     ret
  1263. twoy:    stc
  1264.     pop    b
  1265.     ret
  1266.  
  1267. ;    read bit corresponding to address HL
  1268.  
  1269. reab:    push    h
  1270.     call    biby    ;addr = byte + bit
  1271.     mov    a,m
  1272. rea:    rrc
  1273.     dcr    c
  1274.     jnz    rea
  1275.     pop    h
  1276.     ret
  1277.  
  1278. ;    define bit corresponding to address HL
  1279.  
  1280. wrib:    push    psw
  1281.     call    biby    ;addr = byte + bit
  1282.     push    b
  1283.     mov    a,m
  1284. wra:    rrc
  1285.     dcr    c
  1286.     jnz    wra
  1287.     mov    m,a
  1288.     pop    b
  1289.     pop    psw
  1290.     mov    a,m
  1291.     ral
  1292.     rrc
  1293. wrb:    rlc
  1294.     dcr    c
  1295.     jnz    wrb
  1296.     mov    m,a
  1297.     ret
  1298.  
  1299. ;    reduce an address to byte (HL), bit (C).
  1300.  
  1301. biby:    mov    a,l
  1302.     ani    07H
  1303.     inr    a
  1304.     mov    c,a
  1305.     mvi    b,3
  1306. bib:    mov    a,h
  1307.     rar
  1308.     mov    h,a
  1309.     mov    a,l
  1310.     rar
  1311.     mov    l,a
  1312.     dcr    b
  1313.     jnz    bib
  1314.     mov    a,h
  1315.     ani    1FH
  1316.     mov    h,a
  1317.     lxi    d,begn
  1318.     dad    d
  1319.     lxi    d,-bsiz
  1320.     dad    d
  1321.     ret
  1322.  
  1323. ;    (D) Display the memory in groups of 16 bytes, both as
  1324. ;    pairs of hexadecimal nibbles and as ASCII characters,
  1325. ;    when the latter is appropriate. The command <nDa,b>
  1326. ;    will display n lines, or else the interval between
  1327. ;    hexadecimal addresses a and b; the interval takes
  1328. ;    precedence but if a or b or both are null, the line
  1329. ;    count helps determine the interval. When a is null the
  1330. ;    display will usually continue from where it last ended,
  1331. ;    but nD,b will display b-n up to b. In general:
  1332. ;        nDa,b    a through b-1, n lines of 16 bytes
  1333. ;         Da,b   a through b-1, DP lines of 16 bytes
  1334. ;        nDa,    a through a+n
  1335. ;        nD,b    b-n through b
  1336. ;        nD,    PC through PC+n
  1337. ;         Da,    a to the end
  1338. ;         Da    just line containing a
  1339. ;         D,b    PC through b
  1340. ;         D,    PC to the end
  1341. ;         D    just line beginning at PC
  1342.  
  1343. optd:    lxi    h,pinc    ;paragraph length
  1344.     mvi    m,DP
  1345.     lhld    rept
  1346.     mov    a,l
  1347.     ora    h
  1348.     sui    1
  1349.     sbb    a
  1350.     ani    01H
  1351.     mov    b,a    ;1 means n=0
  1352.     dad    h
  1353.     dad    h
  1354.     dad    h
  1355.     dad    h
  1356.     shld    rept    ;1 line is worth 16 bytes
  1357.     lhld    dorg    ;default <a> is dorg
  1358.     call    hef    ;read <a>
  1359.     mov    c,a
  1360.     mov    a,b
  1361.     ral
  1362.     mov    b,a    ;0 means null <a>
  1363.     xchg
  1364.     lhld    rept
  1365.     dad    d    ;<a+n> is default <b>
  1366.     mov    a,c
  1367.     sui    CR
  1368.     jz    opda
  1369.     lxi    h,0FFF0H
  1370. opda:    sui    1
  1371.     mov    c,a    ;FF means CR
  1372.     mov    a,b
  1373.     ral
  1374.     mov    b,a    ;1 means CR
  1375.     call    hef    ;read <b>
  1376.     mov    a,b
  1377.     ral
  1378.     mov    b,a
  1379.     inr    c
  1380.     jnz    opdb    ;z means CR
  1381.     lhld    rept
  1382.     dad    d
  1383. opdb:    shld    dorg
  1384.  
  1385. ;    At this point, DE=<a>, HL=<b>, B defines case,
  1386. ;    but a few anomalies still have to be resolved.
  1387.  
  1388.     mov    a,b
  1389.     cpi    01H
  1390.     jnz    opdc
  1391.     lhld    dorg
  1392.     xchg
  1393.     lhld    rept
  1394.     mov    a,e
  1395.     sub    l
  1396.     mov    l,a
  1397.     mov    a,d
  1398.     sbb    h
  1399.     mov    h,a
  1400.     xchg        ;else a=b-n
  1401. opdc:    cpi    05H
  1402.     jz    opdd
  1403.     cpi    04H
  1404.     jz    opdd
  1405.     cpi    00H
  1406.     jnz    opde
  1407. opdd:    lhld    rept
  1408.     dad    h
  1409.     dad    h
  1410.     dad    h
  1411.     dad    h
  1412.     mov    a,h
  1413.     sta    pinc    ;paragraph length
  1414.  
  1415. ;    The parameters are now ready to start typing.
  1416.  
  1417. opde:    lhld    dorg
  1418.     xchg
  1419.     mov    a,e
  1420.     sub    l
  1421.     mov    a,d
  1422.     sbb    h
  1423.     jc    error    ;<inverted interval>
  1424.     lda    pinc    ;paragraph length
  1425.     mov    b,a
  1426. opdf:    call    crlf    ;type CR,LF
  1427.     call    inst    ;read console status
  1428.     jz    opdg
  1429.     shld    dorg    ;mark stopping point
  1430.     ret
  1431. opdg:    call    tyhl    ;type HL as four nibbles
  1432.     push    h
  1433.     call    dubl
  1434.     call    hebl
  1435.     call    sngl    ;type space
  1436.     pop    h
  1437.     mvi    c,10H
  1438.     call    ascl
  1439.     dcr    b
  1440.     jnz    opdh
  1441.     lda    pinc    ;paragraph length
  1442.     mov    b,a
  1443.     call    crlf
  1444. opdh:    mov    a,l
  1445.     sub    e
  1446.     mov    a,h
  1447.     sbb    d
  1448.     jc    opdf
  1449.     ret
  1450.  
  1451. hebl:    call    oobl
  1452. oobl:    call    fobl
  1453. fobl:    call    tetr
  1454.     jmp    sngl
  1455.  
  1456. tetr:    call    duce
  1457. duce:    call    once
  1458. once:    mov    a,m
  1459.     call    byte
  1460.     inx    h
  1461.     jmp    sngl
  1462.  
  1463. ;    (F) Fill an interval. <Fx,y,a> will fill the interval
  1464. ;    from x to y with the hexadecimal value a.
  1465.  
  1466. optf:    call    onar
  1467.     push    h
  1468.     call    onar
  1469.     xchg
  1470.     call    hxar
  1471.     jnz    error    ;<nonstandard argument>
  1472.     mov    b,a
  1473.     pop    h
  1474. opfa:    mov    a,l    ;cmp(HL,DE)
  1475.     sub    e
  1476.     mov    a,h
  1477.     sbb    d
  1478.     rnc
  1479.     mov    m,b
  1480.     inx    h
  1481.     jmp    opfa
  1482.  
  1483. ;    (G)  Go to the program for execution. The form <nG,a,b,c>
  1484. ;    allows the insertion of up to two breakpoints, b and c,
  1485. ;    before jumping to the address a. If a count n is also
  1486. ;    included, the breakpoints will be traversed n times
  1487. ;    before control is t returned to DDT. If the field a is
  1488. ;    null, the program will continue from the point where
  1489. ;    control was surrendered to DDT (or 100H if it is an
  1490. ;    initial call.
  1491.  
  1492. optg:    call    crlf    ;type CR,LF
  1493.     xra    a
  1494.     sta    swtv    ;T/V = z/nz
  1495.     sta    swgt    ;G/T = z/nz
  1496.     lhld    rept
  1497.     dad    h
  1498.     shld    rept
  1499.     lhld    savpc    ;PC at breakpoint
  1500.     call    hef    ;fetch a
  1501.     shld    savpc
  1502.     push    h
  1503.     cpi    CR
  1504.     mvi    a,1
  1505.     jz    opga
  1506.     call    hexf    ;fetch b
  1507.     jnc    gnex
  1508.     shld    gbrk    ;nG's breakpoint
  1509.     xchg
  1510.     call    hexf    ;fetch c
  1511.     mvi    a,2
  1512.     jnc    opga
  1513.     shld    gbrl
  1514.     inr    a
  1515.     mov    b,h
  1516.     mov    c,l
  1517. opga:    pop    h
  1518.     sta    gbrn
  1519.     ora    a
  1520.     jmp    gprg    ;G without arguments
  1521.  
  1522. ;    G without arguments
  1523. ;        z    unconditional go (savsp)
  1524. ;        c    ignore HL, but set breakpoints
  1525. ;        A    number of arguments - 0,1,2,3
  1526. ;        HL   explicit destination
  1527. ;        DE   first breakpoint
  1528. ;        BC   second breakpoint
  1529.  
  1530. gnex:    call    step
  1531. gprg:    di
  1532.     jz    gnez    ;no arg, unconditional go
  1533.     jc    gney    ;comma, set breakpoint & go
  1534.     shld    savpc    ;PC at breakpoint
  1535. gney:    dcr    a
  1536.     sta    bkpt
  1537.     jz    gnez    ;one arg already noted
  1538.     xchg
  1539.     mov    e,a
  1540.     mov    a,m
  1541.     sta    brkx
  1542.     mvi    m,0FFH    ;RST 7
  1543.     shld    brkp
  1544.     dcr    e
  1545.     jz    gnez    ;unless 2nd breakpoint
  1546.     mov    l,c
  1547.     mov    h,b
  1548.     mov    a,m
  1549.     sta    brky
  1550.     mvi    m,0FFH    ;RST 7
  1551.     shld    brkq
  1552.  
  1553. ;    Restore registers and return to program.
  1554.  
  1555. gnez:    lxi    sp,savde    ;DDT's private stack
  1556.     pop    d
  1557.     pop    b
  1558.     pop    psw
  1559.     pop    h
  1560.     sphl
  1561.     lhld    savpc    ;PC at breakpoint
  1562.     push    h
  1563.     lhld    savhl    ;HL at breakpoint
  1564.     NOP    
  1565.     ret    
  1566.  
  1567. ;    (H) Display a hexadecimal sum and difference. <Hx,y>
  1568. ;    will result in typing '+'x+y '-'x-y. Mainly used to
  1569. ;    help patch CP/M during system generation.
  1570.  
  1571. opth:    call    onar
  1572.     xchg
  1573.     call    onar
  1574.     xra    a
  1575.     sub    l
  1576.     mov    c,a
  1577.     sbb    h
  1578.     sub    c
  1579.     mov    b,a
  1580.     call    crlf    ;type CR,LF
  1581.     dad    d
  1582.     mvi    a,'s'    ;"sum"
  1583.     call    aout
  1584.     call    tyhl    ;type HL as four nibbles
  1585.     call    sngl    ;type space
  1586.     xchg
  1587.     dad    b
  1588.     mvi    a,'d'    ;"difference"
  1589.     call    aout
  1590.     jmp    tyhl    ;type HL as four nibbles
  1591.  
  1592. ;    (I) Input a command line, according to the same
  1593. ;    criteria used by CCP; in other words a parameter
  1594. ;    list can follow the file name.
  1595.  
  1596. opia:    call    fico
  1597. opti:    lxi    d,TBUF
  1598.     lhld    cptr    ;pointer to command buffer
  1599.     lda    clen
  1600.     mov    b,a
  1601.     inr    b
  1602. moov:    stax    d
  1603.     mov    a,m
  1604.     call    lcfo
  1605.     inx    d
  1606.     inx    h
  1607.     dcr    b
  1608.     jnz    moov
  1609.     mvi    a,00
  1610.     stax    d
  1611.     lxi    h,TBUF+1
  1612.     shld    cptr    ;pointer to command buffer
  1613.     call    fico
  1614.     lxi    h,adsk    ;active disk
  1615.     push    h
  1616.     mov    a,m
  1617.     sta    TFCB    ;CP/M default FCB
  1618.     mvi    a,10H
  1619.     call    fica
  1620.     pop    h
  1621.     mov    a,m
  1622.     sta    TFCB+16
  1623.     xra    a
  1624.     sta    TFCB+32
  1625.     jmp    crlf
  1626.  
  1627. zsep:    ora    a
  1628.     rz
  1629.     cpi    CR
  1630.     rz
  1631.     cpi    ' '
  1632.     jc    error    ;<control chars in command line>
  1633.     rz
  1634.     cpi    '='
  1635.     rz
  1636.     cpi    '_'
  1637.     rz
  1638.     cpi    '.'
  1639.     rz
  1640.     cpi    ':'
  1641.     rz
  1642.     cpi    ';'
  1643.     rz
  1644.     cpi    '<'
  1645.     rz
  1646.     cpi    '>'
  1647.     ret
  1648.  
  1649. fsep:    call    zsep
  1650.     rz
  1651.     call    rech    ;read one character
  1652.     jmp    fsep
  1653.     ret
  1654.  
  1655. ;    Advance to a non blank character in the console
  1656. ;    buffer unless there is none, indicated by a 00.
  1657.  
  1658. zonb:    call    rech    ;read one character
  1659.     ora    a
  1660.     rz
  1661.     cpi    ' '
  1662.     jz    zonb    ;zero or non-blank
  1663.     ret
  1664.  
  1665. ;    Generate a file control block in the manner of CCP.
  1666.  
  1667. fico:    mvi    a,00
  1668. fica:    lxi    h,TFCB
  1669.     add    l
  1670.     mov    l,a
  1671.     mov    a,h
  1672.     aci    00
  1673.     mov    h,a
  1674.     xra    a
  1675.     sta    adsk    ;active disk
  1676.     call    zonb    ;zero or non-blank
  1677.     push    psw
  1678.     jz    ficb
  1679.     sbi    '@'
  1680.     mov    b,a
  1681.     push    h
  1682.     lhld    cptr    ;pointer to command buffer
  1683.     mov    a,m
  1684.     pop    h
  1685.     cpi    ':'
  1686.     jz    ficc
  1687. ficb:    lda    ldsk    ;logged disk
  1688.     jmp    ficd
  1689. ficc:    call    rech    ;read one character
  1690.     pop    psw
  1691.     call    rech    ;read one character
  1692.     push    psw
  1693.     mov    a,b
  1694.     sta    adsk    ;active disk
  1695. ficd:    mov    m,a
  1696.     inx    h
  1697.     mvi    b,08
  1698.     pop    psw
  1699.     call    ffil
  1700.     call    fsep
  1701.     mvi    b,03
  1702.     cpi    '.'
  1703.     jnz    ficp
  1704.     call    rech    ;read one character
  1705.     call    ffil
  1706.     call    fsep
  1707.     jmp    ficq
  1708. ficp:    call    bfil
  1709. ficq:    mvi    b,03
  1710.     mvi    c,00
  1711.     jmp    kfil
  1712.  
  1713. ;    Fill a field
  1714.  
  1715. ffil:    call    zsep
  1716.     jz    bfil
  1717.     cpi    '*'
  1718.     jz    qfil
  1719.     mov    m,a
  1720.     inx    h
  1721.     dcr    b
  1722.     rz
  1723.     call    rech    ;read one character
  1724.     jmp    ffil
  1725.  
  1726. ;    Block fill
  1727.  
  1728. qfil:    mvi    c,'?'
  1729.     jmp    kfil
  1730. bfil:    mvi    c,' '
  1731. kfil:    mov    m,c
  1732.     inx    h
  1733.     dcr    b
  1734.     jnz    kfil
  1735.     ret
  1736.  
  1737. ;    (L) List the memory as 8080 operation codes. The
  1738. ;    command <nLa,b> will list n lines of code between
  1739. ;    the hexadecimal addresses a and b, with the interval
  1740. ;    taking precedence over the number of lines, unless
  1741. ;    either a or b is missing.
  1742.  
  1743. optl:    call    past    ;check limit transgression
  1744.     jnc    error    ;<L may have been overwritten>
  1745.     lhld    rept
  1746.     mov    a,l
  1747.     sta    pinc    ;paragraph length
  1748.     ora    h
  1749.     jnz    opla
  1750.     lxi    h,NL    ;default length
  1751. opla:    inx    h
  1752.     shld    rept    ;line counter for L
  1753.     xra    a
  1754.     sta    pctr    ;paragraph counter
  1755.     lhld    lorg    ;origin for L
  1756.     call    hef    ;read <a>
  1757.     shld    lorg    ;origin for L
  1758.     mov    b,a
  1759.     xchg
  1760.     lxi    h,begn    ;bottom DDT = top memory
  1761.     call    hef    ;read <b>
  1762.     shld    llim    ;limit for L
  1763.     jc    oplc    ;c means <b> not null
  1764.     mov    a,b
  1765.     cpi    CR
  1766.     jz    opld
  1767. oplc:    lxi    h,0000H
  1768.     shld    rept    ;line counter for L
  1769.     lda    pinc    ;paragraph length
  1770.     sta    pctr    ;paragraph counter
  1771.  
  1772. ;    The parameters have been established, start typing.
  1773.  
  1774. opld:    call    inst    ;read console status
  1775.     rnz
  1776.     lhld    rept    ;line counter for L
  1777.     mov    a,l
  1778.     ora    h
  1779.     jnz    oplf    ;nz means counter working
  1780.     lda    pctr    ;paragraph counter
  1781.     ora    a
  1782.     jz    oplg    ;z means no paragraphing
  1783.     dcr    a
  1784.     jnz    ople
  1785.     call    crlf
  1786.     lda    pinc    ;paragraph length
  1787. ople:    sta    pctr    ;paragraph counter
  1788.     jmp    oplg
  1789. oplf:    dcx    h
  1790.     mov    a,l
  1791.     ora    h
  1792.     rz
  1793.     shld    rept    ;line counter for L
  1794. oplg:    call    dubl
  1795.     lhld    lorg    ;origin for L
  1796.     call    reab
  1797.     jnc    nox
  1798.     mvi    a,'X'
  1799.     call    aout    ;A to console
  1800. nox:    call    tyhl    ;type HL as four nibbles
  1801.     call    dubl
  1802.     lhld    llim    ;upper limit for "L"
  1803.     xchg
  1804.     lhld    lorg    ;origin for L
  1805.     mov    a,e    ;cmp(DE,HL)
  1806.     sub    l
  1807.     mov    a,d
  1808.     sbb    h
  1809.     rc
  1810.     call    dism
  1811.     shld    lorg    ;origin for L
  1812.     call    crlf
  1813.     jmp    opld
  1814.  
  1815. ;    (M) Move part of the memory from one place to another.
  1816. ;    <Mx,y,z> will move the interval x,y to begin at z. The
  1817. ;    direction of movement compensates for possible overlap.
  1818.  
  1819. optm:    call    onar
  1820.     mov    c,l
  1821.     mov    b,h
  1822.     call    onar
  1823.     xchg
  1824.     call    onar
  1825.     mov    a,e    ;cmp(DE,BC)
  1826.     sub    c
  1827.     mov    a,d
  1828.     sbb    b
  1829.     jc    error    ;<interval inverted>
  1830.     mov    a,e    ;cmp(DE,HL)
  1831.     sub    l
  1832.     mov    a,d
  1833.     sbb    h
  1834.     jc    opmb
  1835.     mov    a,c    ;cmp(BC,HL)
  1836.     sub    l
  1837.     mov    a,b
  1838.     sbb    h
  1839.     jnc    opmb
  1840.     mov    a,e    ;BC=DE-BC
  1841.     sub    c
  1842.     mov    c,a
  1843.     mov    a,d
  1844.     sbb    b
  1845.     mov    b,a
  1846.     dad    b    ;HL=HL+(DE-BC)
  1847. opma:    mov    a,c
  1848.     ora    b
  1849.     rz
  1850.     ldax    d
  1851.     mov    m,a
  1852.     dcx    h
  1853.     dcx    d
  1854.     dcx    b
  1855.     jmp    opma
  1856. opmb:    mov    a,e    ;cmp(DE,BC)
  1857.     sub    c
  1858.     mov    a,d
  1859.     sbb    b
  1860.     rc
  1861.     ldax    b
  1862.     mov    m,a
  1863.     inx    b
  1864.     inx    h
  1865.     jmp    opmb
  1866.  
  1867. ;    (R) Read into memory the file specified by TFCB.
  1868. ;    It was probably defined by a preceding I command,
  1869. ;    but might still be the program defined in the DDT
  1870. ;    command line. <Rx> will start loading at TORG+x.
  1871.  
  1872. optr:    call    hexf    ;with zero default
  1873. opra:    push    h
  1874.     call    openf    ;open file
  1875.     cpi    0FFH
  1876.     jz    error    ;<failure to open file>
  1877.     call    chex    ;check for .HEX
  1878.     jz    ihex    ;load INTEL HEX file
  1879.     pop    h
  1880.     lxi    d,TORG    ;CP/M transient origin
  1881.     dad    d
  1882.     shld    savpc    ;PC at breakpoint
  1883. oprb:    push    h
  1884.     lxi    d,TFCB    ;CP/M default FCB
  1885.     mvi    c,20    ;(14) read one record
  1886.     call    XDOS    ;DDT analogue of 0005
  1887.     pop    h
  1888.     ora    a
  1889.     jnz    efil    ;EOF
  1890.     lxi    d,TBUF    ;CP/M default FCB
  1891.     mvi    c,80H    ;size of one record
  1892. oprc:    ldax    d
  1893.     inx    d
  1894.     mov    m,a
  1895.     inx    h
  1896.     dcr    c
  1897.     jnz    oprc    ;move to memory
  1898.     call    rmax    ;record upper limit
  1899.     jmp    oprb    ;read another record
  1900.  
  1901. ;    Test whether HL beyond previous maximum.
  1902.  
  1903. tmax:    xchg
  1904.     lhld    pmax    ;program high limit
  1905.     mov    a,l    ;cmp(HL,DE)
  1906.     sub    e
  1907.     mov    a,h
  1908.     sbb    d
  1909.     xchg
  1910.     ret    
  1911.  
  1912. ;    Record maximum program length.
  1913.  
  1914. rmax:    call    tmax
  1915.     rnc    
  1916.     shld    pmax    ;program high limit
  1917.     ret    
  1918.  
  1919. ;    Test for limit transgression.
  1920.  
  1921. past:    push    h
  1922.     lxi    h,begn    ;lower DDT limit
  1923.     call    tmax
  1924.     pop    h
  1925.     ret    
  1926.  
  1927. ;    Check for the extension 'HEX'
  1928.  
  1929. chex:    lxi    h,TFCB+9    ;extension
  1930.     mov    a,m
  1931.     ani    07FH
  1932.     cpi    'H'
  1933.     rnz    
  1934.     inx    h
  1935.     mov    a,m
  1936.     ani    07FH
  1937.     cpi    'E'
  1938.     rnz    
  1939.     inx    h
  1940.     mov    a,m
  1941.     ani    07FH
  1942.     cpi    'X'
  1943.     ret    
  1944.  
  1945. ;    Load INTEL HEX file, whose records have the form:
  1946. ;    :NNAAAA00DDDDDDDDDD....DDXX
  1947. ;        :       start of line
  1948. ;        NN     number of bytes in line
  1949. ;        AAAA   first address of line
  1950. ;        00       class of line (zero in CP/M)
  1951. ;        DD       byte of data - NNH altogether
  1952. ;        XX       checksum - full bytesum w/XX = 00
  1953. ;    :00AAAA -  end of file, start address AAAA.
  1954.  
  1955. ihex:    call    renb    ;next byte from CP/M buffer
  1956.     cpi    01AH    ;^Z
  1957.     jz    error    ;<no EOF in legal text>
  1958.     sbi    ':'    ;line begins with colon
  1959.     jnz    ihex    ;load INTEL HEX file
  1960.     mov    d,a    ;start checksum w/zero
  1961.     pop    h
  1962.     push    h
  1963.     call    nbyt    ;next byte w/checksum
  1964.     mov    e,a
  1965.     call    nbyt    ;next byte w/checksum
  1966.     push    psw    
  1967.     call    nbyt    ;next byte w/checksum
  1968.     pop    b
  1969.     mov    c,a
  1970.     dad    b
  1971.     mov    a,e
  1972.     ora    a
  1973.     jnz    ihxx    ;read non-null line
  1974.     mov    h,b
  1975.     mov    l,c
  1976.     shld    savpc    ;PC at breakpoint
  1977.     pop    h    ;displacement not added to AAAA <<---
  1978.     jmp    efil    ;EOF
  1979.  
  1980. ihxx:    call    nbyt    ;next byte w/checksum
  1981. hlin:    call    nbyt    ;next byte w/checksum
  1982.     mov    m,a
  1983.     inx    h
  1984.     dcr    e
  1985.     jnz    hlin    ;read the full line
  1986.     call    nbyt    ;next byte w/checksum
  1987.     push    psw    
  1988.     call    rmax    ;record upper limit
  1989.     pop    psw    
  1990.     jnz    error    ;<checksum failed>
  1991.     jmp    ihex    ;load INTEL HEX file
  1992.  
  1993. ;    Form next byte, add to checksum
  1994.  
  1995. nbyt:    push    b
  1996.     push    h
  1997.     push    d
  1998.     call    renb    ;next byte from CP/M buffer
  1999.     call    cnh
  2000.     jc    error    ;<not hex digit>
  2001.     add    a    
  2002.     add    a    
  2003.     add    a    
  2004.     add    a    
  2005.     push    psw    
  2006.     call    renb    ;next byte from CP/M buffer
  2007.     call    cnh
  2008.     jc    error    ;<not hex digit>
  2009.     pop    b
  2010.     ora    b
  2011.     mov    b,a
  2012.     pop    d
  2013.     add    d
  2014.     mov    d,a
  2015.     mov    a,b
  2016.     pop    h
  2017.     pop    b
  2018.     ret    
  2019.  
  2020. ;    EOF after reading file
  2021.  
  2022. efil:    mvi    c,12    ;(0C) lift disk head
  2023.     call    XDOS    ;DDT analogue of 0005
  2024.     lxi    h,rmsg    ;header: 'NEXT  PC'
  2025.     call    mssg
  2026.     call    crlf    ;type CR,LF
  2027.     lhld    pmax    ;program high limit
  2028.     call    tyhl    ;type HL as four nibbles
  2029.     call    sngl    ;type space
  2030.     lhld    savpc    ;PC at breakpoint
  2031.     shld    dorg    ;origin for D
  2032.     shld    lorg    ;origin for L
  2033.     jmp    tyhl    ;type HL as four nibbles
  2034.  
  2035. rmsg:    db    CR,LF,'NEXT  PC',00
  2036.  
  2037. ;    (S) Store hexadecimal bytes. <nSx> will store
  2038. ;    n bytes starting at address x, read one by one
  2039. ;    from the console. Missing n means indefinite
  2040. ;    repetition, missing x means TORG. Confirmation
  2041. ;    and progression is automatic while hexadecimal
  2042. ;    bytes are being received; however, for
  2043. ;         -  go back one byte,
  2044. ;        'x  deposit ASCII x,
  2045. ;        ^x  deposit ctl x,
  2046. ;        CR  go on to next byte.
  2047. ;    Any other input terminates the cycle.
  2048.  
  2049. opts:    lxi    h,TORG
  2050.     call    hef    ;read hex field
  2051.     xchg
  2052. opsa:    call    crlf    ;type CR,LF
  2053.     call    typs    ;verify the line
  2054.     call    incl    ;fetch a command line
  2055.     jz    opsc    ;null buffer, go next line
  2056.     call    hxar    ;read one-byte arg
  2057.     jz    opsb    ;<standard field>
  2058.     cpi    '-'    ;go back
  2059.     rnz        ;leave the cycle
  2060.     dcx    d
  2061.     jmp    opsa
  2062. opsb:    stax    d
  2063.     call    ctlx
  2064.     call    typs    ;verify the line
  2065. opsc:    inx    d
  2066.     call    drnz
  2067.     jnz    opsa
  2068.     ret
  2069.  
  2070. ;    Type the format line for S.
  2071.  
  2072. typs:    ldax    d
  2073.     call    prip    ;type printable or .
  2074.     call    sngl
  2075.     call    word    ;type DE as four nibbles
  2076.     call    sngl    ;type space
  2077.     ldax    d
  2078.     call    byte    ;type A as two nibbles
  2079.     jmp    sngl    ;type space
  2080.  
  2081. ;    (T)  Type the register status line while single-stepping
  2082. ;    through the program. <nT> runs through n steps typing
  2083. ;    each one, while <nT/> executes without typing. The option
  2084. ;    V, with the same alternatives <nV> and <nV/> treats a
  2085. ;    call or a conditional call as a single step, avoiding a
  2086. ;    detailled examination of the interior contents of each
  2087. ;    subroutine.
  2088.  
  2089.  
  2090. optt:    xra    a
  2091. oooa:    sta    swtv    ;T/V = z/nz
  2092.     mvi    a,0FFH
  2093.     sta    swgt    ;G/T = z/nz
  2094.     call    reuc
  2095.     cpi    '/'
  2096.     jnz    ooob
  2097.     xra    a
  2098. ooob:    sta    swtu    ;T/U = nz/z
  2099.     lhld    rept
  2100.     mov    a,l
  2101.     ora    h
  2102.     jz    oooc
  2103.     dcx    h
  2104. oooc:    shld    rept    ;repetition counter
  2105.     call    line    ;type display line
  2106.     jmp    gnex
  2107.  
  2108. ;    (V) A variant of T.
  2109.  
  2110. optv:    mvi    a,0FFH
  2111.     jmp    oooa
  2112.  
  2113. ;    (X) Examine registers. Any one of the registers or
  2114. ;    register pairs A, BC, HL, DE, SP, PC may be examined,
  2115. ;    or one of the five flag bits C, Z, M, E, I, by typing
  2116. ;    Xr, with r = czmeiabhdsp*, or =xxxx with a hexadecimal
  2117. ;    address xxxx. The latter defines the register * at
  2118. ;    first. A display line is typed, of the form
  2119. ;    r=xxxx  xx ...  xx  ... xx  +++++  + +++++  ooo ooooo
  2120. ;    where xxxx is the contents of register r, xx etc is
  2121. ;    a window of hexadecimal bytes centered on xxxx, ++ etc
  2122. ;    is a similar window of ASCII characters, and finally
  2123. ;    ooo ooooo is the instruction, if meaningful, at xxxx.
  2124. ;
  2125. ;    Once an examination is underway, the window may be
  2126. ;    moved by various operators:
  2127. ;        *      indirect from window
  2128. ;        ^      indirect from instruction address
  2129. ;        excl   save value
  2130. ;        ?      recover value
  2131. ;        /      next instruction
  2132. ;        +      1 byte forward
  2133. ;        -      1 byte backward
  2134. ;        #      forward, stop at nonzero
  2135. ;        @      backward, stop at nonzero
  2136. ;        =xx    search for byte xx ('x or ^x also)
  2137. ;        |xxxx  search for pair xxxx
  2138. ;        >      forward half-window
  2139. ;        <      backward half-window
  2140. ;        .      type crlf - make new line
  2141.  
  2142. optx:    call    relc    ;char to A from buffer
  2143.     cpi    CR
  2144.     jz    ljne    ;type display line
  2145.     cpi    '='
  2146.     jnz    opxa
  2147.     call    hexf
  2148.     shld    savmr    ;save memory reference
  2149.     mvi    a,'*'
  2150. opxa:    lxi    b,NR    ;B=0, C=# registers
  2151.     lxi    h,regs    ;register list
  2152. opxb:    cmp    m
  2153.     jz    opxc    ;modify given register
  2154.     inx    h
  2155.     inr    b
  2156.     dcr    c
  2157.     jnz    opxb    ;repeat for all
  2158.     jmp    error    ;<no such register>
  2159.  
  2160. opxc:    push    h
  2161.     mov    a,b
  2162.     call    gesr    ;fetch saved register
  2163.     shld    savxx    ;?/! cell
  2164.     call    reuc    ;char to A from buffer
  2165.     cpi    CR
  2166.     jnz    error    ;<null field>
  2167.     push    b
  2168. opxd:    pop    b
  2169.     pop    h
  2170.     push    h
  2171.     push    b
  2172.     call    ctlx    ;type ^X
  2173.     call    tyfr    ;type flag or register
  2174.     call    sngl    ;type space
  2175.     call    incl    ;fetch a command line
  2176.     call    hexf
  2177.     pop    b
  2178.     jnc    opxg    ;nc means null hex field
  2179.     push    b
  2180. opxe:    mov    a,b
  2181.     cpi    05
  2182.     jnc    uacc    ;update register
  2183.     mov    a,h
  2184.     ora    a
  2185.     jnz    error    ;<only one byte admitted>
  2186.     mov    a,l
  2187.     cpi    02
  2188.     jnc    error    ;<only 1 bit (0,1) allowed>
  2189.     call    fmaf    ;fetch mask & flags
  2190.     mov    h,a
  2191.     mov    b,c
  2192.     mvi    a,0FEH    ;-2
  2193.     call    shla    ;shl(A,B)
  2194.     ana    h
  2195.     mov    b,c
  2196.     mov    h,a
  2197.     mov    a,l
  2198.     call    shla    ;shl(A,B)
  2199.     ora    h
  2200.     stax    d
  2201.     jmp    opxd
  2202.  
  2203. ;    Window modifiers are possible with a null hex field.
  2204.  
  2205. opxg:    push    psw
  2206.     mov    a,b
  2207.     call    gesr    ;fetch saved register
  2208.     pop    psw
  2209.     cpi    CR
  2210.     jnz    opxh
  2211.     shld    dorg
  2212.     shld    lorg
  2213.     pop    h
  2214.     ret
  2215. opxh:    push    b
  2216.     lxi    d,opxe
  2217.     push    d
  2218.     call    alta
  2219.     db    14
  2220.     db    '*'    ;indirect address from window
  2221.     dw    opxv
  2222.     db    '^'    ;indirect address from instruction
  2223.     dw    opxu
  2224.     db    '!'    ;save address
  2225.     dw    opxw
  2226.     db    '?'    ;restore address
  2227.     dw    opxx
  2228.     db    '/'    ;next instruction
  2229.     dw    opxy
  2230.     db    '+'    ;advance 1 byte
  2231.     dw    opxz
  2232.     db    '-'    ;return 1 byte
  2233.     dw    opxt
  2234.     db    '#'    ;advance to nonzero byte
  2235.     dw    opxs
  2236.     db    '.'    ;type crlf
  2237.     dw    crlf
  2238.     db    '='    ;=x: search for xx, 'x, ^x
  2239.     dw    opxr
  2240.     db    '|'    ;|xxxx: search for pair xxxx
  2241.     dw    opxm
  2242.     db    '>'    ;advance halfwindow
  2243.     dw    opxp
  2244.     db    '<'    ;return halfwindow
  2245.     dw    opxo
  2246.     db    '@'    ;return to nonzero
  2247.     dw    opxn
  2248.  
  2249. opxu:    inx    h    ;^
  2250. opxv:    mov    e,m    ;*
  2251.     inx    h
  2252.     mov    d,m
  2253.     xchg
  2254.     ret
  2255.  
  2256. opxw:    shld    savxx    ;excl
  2257.     ret
  2258.  
  2259. opxx:    lhld    savxx    ;?
  2260.     ret
  2261.  
  2262. opxy:    mov    a,m    ;/
  2263.     inx    h
  2264.     inx    h
  2265.     inx    h
  2266.     call    twob
  2267.     rc
  2268.     dcx    h
  2269.     call    oneb
  2270.     rc
  2271. opxt:    dcx    h    ;- (beware - it's part of opxy)
  2272.     ret
  2273.  
  2274. opxz:    inx    h    ;+
  2275.     ret
  2276.  
  2277. opxs:    xra    a    ;#
  2278. oxs:    inx    h
  2279.     cmp    m
  2280.     jz    oxs
  2281.     ret
  2282.  
  2283. opxr:    xchg        ;=
  2284.     lhld    rept
  2285.     call    hxr    ;hex argument w/default
  2286.     shld    rept    ;be sure to find it again
  2287.     mov    a,l
  2288.     xchg
  2289. oxr:    inx    h
  2290.     cmp    m
  2291.     jnz    oxr
  2292.     ret
  2293.  
  2294. opxp:    lxi    d,WW+1    ;>
  2295.     dad    d
  2296.     ret
  2297.  
  2298. opxo:    lxi    d,-WW-1    ;<
  2299.     dad    d
  2300.     ret
  2301.  
  2302. opxn:    xra    a    ;@
  2303. oxn:    dcx    h
  2304.     cmp    m
  2305.     jz    oxn
  2306.     ret
  2307.  
  2308. opxm:    xchg        ;|
  2309.     lhld    rept
  2310.     call    hef
  2311.     shld    rept    ;be sure we'll find the pair
  2312.     xchg
  2313.     inx    h
  2314. oxm:    mov    a,e
  2315.     call    oxr
  2316.     inx    h
  2317.     mov    a,d
  2318.     cmp    m
  2319.     dcx    h
  2320.     jnz    oxm
  2321.     dcx    h
  2322.     ret
  2323.  
  2324. ;    shl(A,B)
  2325.  
  2326. shla:    dcr    b
  2327.     rz    
  2328.     rlc    
  2329.     jmp    shla    ;shl(A,B)
  2330.  
  2331. ;    Decrement REPT if it is non-zero.
  2332.  
  2333. drnz:    push    h
  2334.     lhld    rept
  2335.     mov    a,h
  2336.     ora    l
  2337.     sui    1
  2338.     sbb    a
  2339.     jnz    dnz
  2340.     dcx    h
  2341.     shld    rept
  2342.     mov    a,h
  2343.     ora    l
  2344. dnz:    pop    h
  2345.     ret
  2346.  
  2347. ;    Update register
  2348.  
  2349. uacc:    jnz    ureg
  2350.     mov    a,h
  2351.     ora    a
  2352.     jnz    error    ;<only one byte allowed>
  2353.     mov    a,l
  2354.     sta    sava    ;save A
  2355.     jmp    opxd
  2356.  
  2357. ureg:    push    h
  2358.     call    gasr    ;get address of saved register
  2359.     pop    d
  2360.     mov    m,e
  2361.     inx    h
  2362.     mov    m,d
  2363.     jmp    opxd
  2364.  
  2365. ;    Open file
  2366.  
  2367. openf:    push    h
  2368.     push    d
  2369.     push    b
  2370.     xra    a
  2371.     sta    TFCB-1
  2372.     sta    TFCB+32
  2373.     mvi    c,15    ;(0F) open file
  2374.     lxi    d,TFCB    ;CP/M default FCB
  2375.     call    XDOS    ;DDT analogue of 0005
  2376.     pop    b
  2377.     pop    d
  2378.     pop    h
  2379.     ret    
  2380.  
  2381. ;    Read next byte from CP/M buffer,
  2382. ;    replenish when exhausted.
  2383.  
  2384. renb:    push    h
  2385.     push    d
  2386.     push    b
  2387.     lda    TFCB-1
  2388.     ani    07FH
  2389.     jz    ror    ;read one record
  2390. rnb:    mvi    d,00
  2391.     mov    e,a
  2392.     lxi    h,TBUF    ;CP/M default FCB
  2393.     dad    d
  2394.     mov    a,m
  2395.     cpi    01AH    ;^Z
  2396.     jz    reen    ;end of record
  2397.     lxi    h,TFCB-1
  2398.     inr    m
  2399.     ora    a
  2400.     jmp    reex    ;return
  2401.  
  2402. ror:    mvi    c,20    ;(14) read one record
  2403.     lxi    d,TFCB    ;CP/M default FCB
  2404.     call    XDOS    ;DDT analogue of 0005
  2405.     ora    a
  2406.     jnz    reen    ;end of record
  2407.     sta    TFCB-1
  2408.     jmp    rnb
  2409.  
  2410. reen:    stc        ;end of record
  2411. reex:    pop    b    ;return
  2412.     pop    d
  2413.     pop    h
  2414.     ret    
  2415.  
  2416. ;    Error
  2417.  
  2418. error:    mvi    a,'?'
  2419.     call    aout    ;A to console
  2420.     jmp    loop    ;clear out the stack
  2421.  
  2422. ;    Read console status.
  2423.  
  2424. inst:    push    b
  2425.     push    d
  2426.     push    h
  2427.     mvi    c,11    ;(0B) console status
  2428.     call    XDOS    ;DDT analogue of 0005
  2429.     ani    01
  2430.     pop    h
  2431.     pop    d
  2432.     pop    b
  2433.     ret    
  2434.  
  2435. ;    Fill command line buffer from console. The z flag
  2436. ;    on return indicates whether a null line was read.
  2437.  
  2438. incl:    push    h
  2439.     push    d
  2440.     push    b
  2441.     mvi    c,10    ;(0A) read buffer
  2442.     lxi    d,cbuf    ;command buffer
  2443.     call    XDOS    ;DDT analogue of 0005
  2444.     lxi    h,ctex    ;command text
  2445.     shld    cptr    ;pointer to command buffer
  2446.     lda    clen
  2447.     pop    b
  2448.     pop    d
  2449.     pop    h
  2450.     ora    a
  2451.     ret    
  2452.  
  2453. ;    Read a one-byte argument, which may be hexadecimal,
  2454. ;    'x or ^x. Blatant errors are rejected, but nz at
  2455. ;    return means null field not terminated by CR, ', or^.
  2456.  
  2457. hxar:    lxi    h,0000
  2458. hxr:    call    hef
  2459.     jnc    har
  2460.     mov    a,h
  2461.     ora    a
  2462.     jnz    error    ;<not one byte>
  2463.     mov    a,l
  2464.     ret
  2465. har:    cpi    ''''
  2466.     jnz    has
  2467.     call    rech
  2468.     cpi    ' '
  2469.     jc    error    ;<quoted ctrl char>
  2470.     jmp    hat
  2471. has:    cpi    '^'
  2472.     rnz
  2473.     call    rech
  2474.     sui    '@'
  2475.     jc    error    ;<number, symbol, &c>
  2476.     cpi    ' '
  2477.     jc    hat
  2478.     sui    ' '
  2479.     cpi    ' '
  2480.     jnc    error    ;<beyond ASCII range>
  2481. hat:    mov    l,a
  2482.     call    rech
  2483.     cpi    CR
  2484.     jnz    error    ;<not single character>
  2485.     mov    a,l
  2486.     ret
  2487.  
  2488. ;    Read a hexadecimal field; error if null.
  2489.  
  2490. onar:    call    hexf
  2491.     jnc    error    ;<insufficient arguments>
  2492.     ret
  2493.  
  2494. ;    Type CR,LF.
  2495.  
  2496. crlf:    mvi    a,CR
  2497.     call    aout    ;A to console
  2498.     mvi    a,LF
  2499.     jmp    aout    ;A to console
  2500.  
  2501. ;    Type ^X [erase line]
  2502.  
  2503. ctlx:    mvi    a,18H    ;^X
  2504.     jmp    aout    ;A to console
  2505.  
  2506. ;    Type one or two spaces.
  2507.  
  2508. dubl:    call    sngl
  2509. sngl:    mvi    a,' '
  2510.  
  2511. ;    A to console
  2512.  
  2513. aout:    push    h
  2514.     push    d
  2515.     push    b
  2516.     mov    e,a
  2517.     mvi    c,02
  2518.     call    XDOS    ;DDT analogue of 0005
  2519.     pop    b
  2520.     pop    d
  2521.     pop    h
  2522.     ret    
  2523.  
  2524. ;    Lower case fold excepting rubout
  2525.  
  2526. reuc:    call    rech    ;read one character
  2527. lcfo:    cpi    'a'
  2528.     rc
  2529.     cpi    '{'
  2530.     rnc
  2531.     ani    5FH
  2532.     ret    
  2533.  
  2534. ;    Upper case fold
  2535.  
  2536. relc:    call    rech    ;read one character
  2537. ucfo:    cpi    '['
  2538.     rnc
  2539.     cpi    'A'
  2540.     rc
  2541.     ori    20H
  2542.     ret
  2543.  
  2544. ;    Fetch a character into A from command line
  2545.  
  2546. rech:    push    h
  2547.     lxi    h,clen    ;command string length
  2548.     mov    a,m
  2549.     ora    a
  2550.     mvi    a,CR    ;fake CR from empty buffer
  2551.     jz    recx
  2552.     dcr    m
  2553.     lhld    cptr    ;pointer to command buffer
  2554.     mov    a,m
  2555.     inx    h
  2556.     shld    cptr    ;pointer to command buffer
  2557. recx:    pop    h
  2558.     ret    
  2559.  
  2560. ;    Type A as two nibbles
  2561.  
  2562. word:    mov    a,d
  2563.     call    byte
  2564.     mov    a,e
  2565. byte:    push    psw    
  2566.     rar    
  2567.     rar    
  2568.     rar    
  2569.     rar    
  2570.     call    nybl
  2571.     pop    psw
  2572. nybl:    ani    0FH
  2573.     adi    90H
  2574.     daa
  2575.     aci    40H
  2576.     daa
  2577.     jmp    aout    ;A to console
  2578.  
  2579. ;    Type HL as four nibbles
  2580.  
  2581. tyhl:    xchg
  2582.     call    word
  2583.     xchg
  2584.     ret
  2585.  
  2586. ;    Message terminated by zero to console
  2587.  
  2588. mssg:    mov    a,m
  2589.     ora    a
  2590.     rz
  2591.     call    aout    ;A to console
  2592.     inx    h
  2593.     jmp    mssg
  2594.  
  2595. ;    Print printables, put dot for the rest
  2596.  
  2597. prip:    cpi    RO
  2598.     jnc    priq
  2599.     cpi    ' '
  2600.     jnc    aout    ;A to console
  2601. priq:    mvi    a,'.'
  2602.     jmp    aout    ;A to console
  2603.  
  2604. ;    Type minus or B, according to sign.
  2605.  
  2606. morb:    rlc
  2607.     push    psw
  2608.     mvi    a,'-'
  2609.     jnc    morc
  2610.     mov    a,b
  2611. morc:    call    aout
  2612.     pop    psw
  2613.     ret
  2614.  
  2615. ;    Type 5 flags as letter (1) or minus (0).
  2616.  
  2617. feql:    lda    savf
  2618.     mvi    b,'s'
  2619.     call    morb
  2620.     mvi    b,'z'
  2621.     call    morb
  2622.     rlc
  2623.     mvi    b,'i'
  2624.     call    morb
  2625.     rlc
  2626.     mvi    b,'p'
  2627.     call    morb
  2628.     rlc
  2629.     mvi    b,'c'
  2630.     call    morb
  2631.     jmp    sngl
  2632.  
  2633. ;    Type <R=XX x > to display a register.
  2634.  
  2635. reql:    push    psw
  2636.     mov    a,b
  2637.     call    aout
  2638.     mvi    a,'='
  2639.     call    aout
  2640.     pop    psw
  2641.     push    psw
  2642.     call    byte
  2643.     call    sngl
  2644.     pop    psw
  2645.     call    prip
  2646.     jmp    sngl
  2647.  
  2648. ;    Type <P=XXXX > to display a register pair.
  2649.  
  2650. peql:    mov    a,b
  2651.     call    aout
  2652.     mvi    a,'='
  2653.     call    aout
  2654.     call    tyhl
  2655.     jmp    sngl
  2656.  
  2657. ;    Test for separators, which are characters which can
  2658. ;    be passed over at the beginning of a field, but which
  2659. ;    terminate it when found at the end. The character to
  2660. ;    be tested is in the accumulator, where it remains.
  2661.  
  2662. sepa:    cpi    ' '
  2663.     rz    
  2664.     cpi    HT
  2665.     ret    
  2666.  
  2667. ;    Test for terminators, which mean that a field must
  2668. ;    end, even if it is null.
  2669.  
  2670. term:    cpi    ','
  2671.     rz
  2672.     cpi    CR
  2673.     ret
  2674.  
  2675. ;    Test whether the character in the accumulator is a
  2676. ;    decimal digit. If so, it is replaced by its  binary
  2677. ;    value, otherwise remaining unchanged. The carry
  2678. ;    flag distinguishes the cases - carry if not decimal.
  2679.  
  2680. cnd:    cpi    '0'
  2681.     rc
  2682.     cpi    ':'
  2683.     cmc
  2684.     rc
  2685.     sui    '0'
  2686.     ret
  2687.  
  2688. ;    Read a decimal field, leaving the last four
  2689. ;    digits read in HL, with leading zeros for fewer
  2690. ;    digits.  BC, DE remain unchanged. A null field
  2691. ;    is zero.  Leading separators are passed by, but
  2692. ;    trailing separators terminate.    A null field is
  2693. ;    marked by the carry flag, which is 0 for a null
  2694. ;    field delimited by a terminator, 1 otherwise.
  2695. ;    A non-zero default value can be given to a null
  2696. ;    field using <call def> rather than <call decf>.
  2697.  
  2698. decf:    lxi    h,0000
  2699. def:    call    reuc
  2700.     call    sepa
  2701.     jz    def
  2702.     call    cnd
  2703.     cmc
  2704.     rnc
  2705.     lxi    h,0000
  2706.     push    d
  2707. dec:    mov    e,l
  2708.     mov    d,h
  2709.     dad    h
  2710.     dad    h
  2711.     dad    d
  2712.     dad    h
  2713.     mov    e,a
  2714.     mvi    d,0
  2715.     dad    d
  2716.     call    reuc
  2717.     call    cnd
  2718.     jnc    dec
  2719.     pop    d
  2720.     ret
  2721.  
  2722. ;    Test whether the character in the accumulator is a
  2723. ;    hexadecimal digit. If so, it is replaced by its 
  2724. ;    binary value, otherwise remaining unchanged. The
  2725. ;    carry flag distinguishes the cases - carry if not
  2726. ;    hexadecimal.
  2727.  
  2728. cnh:    cpi    '0'
  2729.     rc
  2730.     cpi    ':'
  2731.     jc    cni
  2732.     cpi    'A'
  2733.     rc
  2734.     cpi    'G'
  2735.     jnc    cnj
  2736.     sui    07
  2737. cni:    sui    '0'
  2738.     stc
  2739. cnj:    cmc
  2740.     ret
  2741.  
  2742. ;    Read a hexadecimal field, leaving the last four
  2743. ;    digits read in HL, with leading zeros for fewer
  2744. ;    digits.  BC, DE remain unchanged. A null field
  2745. ;    is zero.  Leading separators are passed by, but
  2746. ;    trailing separators terminate.    A null field is
  2747. ;    marked by the carry flag, which is 0 for a null
  2748. ;    field delimited by a terminator, 1 otherwise.
  2749. ;    A non-zero default value can be given to a null
  2750. ;    field using <call hef> rather than <call hexf>.
  2751.  
  2752. hexf:    lxi    h,0000
  2753. hef:    call    reuc
  2754.     call    sepa
  2755.     jz    hef
  2756.     call    cnh
  2757.     cmc
  2758.     rnc
  2759.     lxi    h,0000
  2760. hex:    dad    h
  2761.     dad    h
  2762.     dad    h
  2763.     dad    h
  2764.     ora    l
  2765.     mov    l,a
  2766.     call    reuc
  2767.     call    cnh
  2768.     jnc    hex
  2769.     ret
  2770.  
  2771. ;    Fetch mask and saved flags
  2772.  
  2773. fmaf:    push    h
  2774.     lxi    h,fmsk    ;flag masks
  2775.     mov    e,b
  2776.     mvi    d,00
  2777.     dad    d
  2778.     mov    c,m
  2779.     lxi    h,savf    ;save AF
  2780.     mov    a,m
  2781.     xchg
  2782.     pop    h
  2783.     ret    
  2784.  
  2785. ;    Get value of saved flag
  2786.  
  2787. fval:    call    fmaf    ;fetch mask & flags
  2788. val:    dcr    c
  2789.     jz    vam    ;ani a,01
  2790.     rar    
  2791.     jmp    val
  2792. vam:    ani    01
  2793.     ret    
  2794.  
  2795. ;    Get address of saved register
  2796.  
  2797. gasr:    sui    06
  2798.     lxi    h,rdsp    ;list of displacements
  2799.     mov    e,a
  2800.     mvi    d,00
  2801.     dad    d
  2802.     dad    d
  2803.     mov    e,m
  2804.     inx    h
  2805.     mov    d,m
  2806.     lxi    h,savmr    ;save memory reference
  2807.     dad    d
  2808.     ret    
  2809.  
  2810. ;    Fetch saved register
  2811.  
  2812. gesr:    call    gasr    ;get address of saved register
  2813.     mov    e,m
  2814.     inx    h
  2815.     mov    d,m
  2816.     xchg
  2817.     ret    
  2818.  
  2819. ;    Type flag or register
  2820.  
  2821. tyfr:    mov    a,b
  2822.     cpi    05
  2823.     jnc    tyra
  2824.     mov    a,m
  2825.     call    aout    ;A to console
  2826.     call    fval    ;get saved flag
  2827.     jmp    nybl    ;type A as DEC or HEX
  2828.  
  2829. tyra:    mov    b,m
  2830.     jnz    tyre    ;type saved register
  2831.     lda    sava    ;save A
  2832.     jmp    reql
  2833.  
  2834. ;    Type register and the memory pointed to in the format:
  2835. ;        r=value, window, ASCII window, dism
  2836.  
  2837. tyre:    call    gesr    ;get saved register
  2838.     call    peql
  2839.     call    sngl
  2840.     push    h
  2841.     lxi    d,-WW    ;go back window halfwidth
  2842.     dad    d
  2843.     push    h
  2844.     call    tyrg
  2845.     call    sngl
  2846.     pop    h
  2847.     call    tyrj
  2848.     call    dubl
  2849.     pop    h
  2850.     jmp    dism
  2851.  
  2852. ;    Type 2*WW+1 bytes centered on pointer, as nibble pairs.
  2853.  
  2854. tyrg:    call    tyrh
  2855.     call    sngl
  2856.     mov    a,m
  2857.     call    byte
  2858.     call    dubl
  2859.     inx    h
  2860. tyrh:    mvi    c,WW
  2861. tyri:    mov    a,m
  2862.     call    byte
  2863.     call    sngl
  2864.     inx    h
  2865.     dcr    c
  2866.     jnz    tyri
  2867.     ret
  2868.  
  2869. ;    Then type the same window using ASCII characters or points.
  2870.  
  2871. tyrj:    call    tyrk
  2872.     call    sngl
  2873.     mov    a,m
  2874.     call    prip    ;type printable or .
  2875.     inx    h
  2876.     call    sngl
  2877. tyrk:    mvi    c,WW
  2878. ascl:    mov    a,m
  2879.     call    prip    ;type printable or .
  2880.     inx    h
  2881.     dcr    c
  2882.     jnz    ascl
  2883.     ret
  2884.  
  2885. ;    Type display line.
  2886.  
  2887. line:    call    ljne
  2888.     jmp    crlf
  2889. ljne:    mvi    b,'b'
  2890.     lhld    savbc
  2891.     call    peql
  2892.     mvi    b,'d'
  2893.     lhld    savde
  2894.     call    peql
  2895.     mvi    b,'h'
  2896.     lhld    savhl
  2897.     push    h
  2898.     call    peql
  2899.     pop    h
  2900.     mvi    b,'m'
  2901.     mov    a,m
  2902.     call    reql
  2903.     mvi    b,'a'
  2904.     lda    sava
  2905.     call    reql
  2906.     call    feql
  2907.     mvi    b,'s'
  2908.     lhld    savsp
  2909.     call    peql
  2910.     mvi    b,'p'
  2911.     lhld    savpc
  2912.     call    peql
  2913.     call    sngl
  2914.     jmp    dism
  2915.  
  2916. regs:    db    'czmeiabdhsp*'
  2917.  
  2918. rdsp:    dw    -10,-12,-4,-6,-2,0
  2919.  
  2920. fmsk:    db    1,7,8,3,5
  2921.  
  2922. ;    Jump guided by a table of alternatves. The table
  2923. ;    should have the form:
  2924. ;        call    alta
  2925. ;        db    n
  2926. ;        db    'x'
  2927. ;        dw    xxxx
  2928. ;    The last two lines are to be repeated n times, for
  2929. ;    each of which xxxx is the jump address corresponding
  2930. ;    to the alternative x. The table is used by jumping
  2931. ;    to its heading with the alternative in A. Registers
  2932. ;    C, D, and E are lost in the process.
  2933.  
  2934. alta:    xthl
  2935.     mov    c,m
  2936. alt:    inx    h
  2937.     cmp    m
  2938.     inx    h
  2939.     jnz    alu
  2940.     mov    e,m
  2941.     inx    h
  2942.     mov    d,m
  2943.     xchg
  2944.     xthl
  2945.     ret
  2946. alu:    dcr    c
  2947.     inx    h
  2948.     jnz    alt
  2949.     jmp    error    ;<alternative not present>
  2950.  
  2951. ;    Indexed jump through a table.
  2952.  
  2953. juta:    pop    h
  2954.     mov    e,a
  2955.     mvi    d,00
  2956.     dad    d
  2957.     dad    d
  2958.     mov    e,m
  2959.     inx    h
  2960.     mov    d,m
  2961.     xchg
  2962.     pchl
  2963.  
  2964. ;    Return from breakpoint
  2965.  
  2966. rtbk:    di
  2967.     shld    savhl;    HL at breakpoint
  2968.     pop    h
  2969.     dcx    h
  2970.     shld    savpc    ;PC at breakpoint
  2971.     push    psw    
  2972.     lxi    h,0002
  2973.     dad    sp
  2974.     pop    psw    
  2975.     lxi    sp,savhl    ;HL at breakpoint
  2976.     push    h
  2977.     push    psw    
  2978.     push    b
  2979.     push    d
  2980.     lhld    savpc    ;PC at breakpoint
  2981.     mov    a,m
  2982.     cpi    0FFH    ;RST 7
  2983.     push    psw    
  2984.     push    h
  2985.     lxi    h,bkpt    ;breakpoint data
  2986.     mov    a,m
  2987.     mvi    m,00
  2988.     ora    a
  2989.     jz    rtbb
  2990.     dcr    a
  2991.     jz    rtba
  2992.     lda    brky
  2993.     lhld    brkq
  2994.     mov    m,a
  2995. rtba:    lda    brkx
  2996.     lhld    brkp
  2997.     mov    m,a
  2998. rtbb:    pop    h
  2999.     pop    psw    
  3000.     jz    rtbc    ;if RST 7
  3001.     inx    h
  3002.     shld    savpc    ;PC at breakpoint
  3003.     xchg
  3004.     lxi    h,GDOS+1    ;BDOS address
  3005.     mov    c,m
  3006.     inx    h
  3007.     mov    b,m
  3008.     mov    a,e    ;cmp(DE,BC)
  3009.     sub    c
  3010.     mov    a,d
  3011.     sbb    b
  3012.     jc    rtbc    ;if RST 7
  3013.     lxi    h,0000
  3014.     shld    rept
  3015.     lhld    sica    ;site of call to BDOS
  3016.     xchg
  3017.     mvi    a,02H
  3018.     ora    a
  3019.     stc    
  3020.     jmp    gprg    ;G without arguments
  3021.  
  3022.  
  3023. ;    If RST 7 brought us to the breakpoint.
  3024.  
  3025. rtbc:    NOP
  3026.     lhld    rept    ;repetition counter
  3027.     mov    a,h
  3028.     ora    l
  3029.     jz    rtbd    ;we won't continue
  3030.     dcx    h
  3031.     shld    rept    ;repetition counter
  3032.     lda    swgt    ;G/T = z/nz
  3033.     ora    a
  3034.     jz    rtbf
  3035.     call    inst    ;read console status
  3036.     jnz    rtbd    ;we won't continue
  3037.     lda    swtu    ;T/U = nz/z
  3038.     ora    a
  3039.     cnz    line    ;type display line
  3040.     jmp    gnex
  3041.  
  3042. ;    Return to DDT rather than program.
  3043.  
  3044. rtbd:    mvi    a,'*'
  3045.     call    aout    ;A to console
  3046.     lhld    savpc    ;PC at breakpoint
  3047.     shld    dorg    ;origin for D
  3048.     call    past    ;check limit transgression
  3049.     jnc    rtbe    ;can't count on using L
  3050.     shld    lorg    ;origin for L
  3051. rtbe:    call    tyhl    ;type HL as four nibbles
  3052.     jmp    loop    ;DDT loop - cannot be <ret>
  3053.  
  3054. rtbf:    mov    a,l
  3055.     ani    01H
  3056.     jnz    gnex
  3057.     lhld    gbrl
  3058.     mov    c,l
  3059.     mov    b,h
  3060.     lhld    gbrk
  3061.     xchg
  3062.     lda    gbrn
  3063.     ora    a
  3064.     stc
  3065.     jmp    gprg    ;G without arguments
  3066.  
  3067. ;    Surround instruction by breakpoints for single-step.
  3068.  
  3069. type:    lxi    d,000DH
  3070.     lxi    h,mtbl    ;table of type codes
  3071. tyqe:    mov    a,m
  3072.     ana    b
  3073.     inx    h
  3074.     cmp    m
  3075.     inx    h
  3076.     jz    tyse
  3077.     inr    d
  3078.     dcr    e
  3079.     jnz    tyqe
  3080. tyse:    mov    a,d
  3081.     ret    
  3082.  
  3083. step:    lhld    savpc    ;PC at breakpoint
  3084.     mov    b,m
  3085.     inx    h
  3086.     push    h
  3087.     call    type
  3088.     call    juta
  3089.     dw    xjmp    ;jump
  3090.     dw    xcju    ;conditional jump
  3091.     dw    ding    ;call
  3092.     dw    dong    ;conditional call
  3093.     dw    xret    ;return
  3094.     dw    xrst    ;restart
  3095.     dw    xpch    ;pchl
  3096.     dw    xmvi    ;immediate move
  3097.     dw    xmvi    ;immediate arithmetic
  3098.     dw    xlxi    ;lxi
  3099.     dw    xlxi    ;lhld
  3100.     dw    xcrt    ;conditional return
  3101.     dw    xmvi    ;in, out
  3102.     dw    xoth    ;others
  3103.  
  3104. ding:    lda    swtv    ;T/V = z/nz
  3105.     inr    a
  3106.     jz    xlxi    ;lxi, lhld
  3107.     jmp    xjmp    ;jump, call
  3108.  
  3109. dong:    lda    swtv    ;T/V = z/nz
  3110.     inr    a
  3111.     jz    xlxi    ;lxi, lhld
  3112.     jmp    xcju    ;cndl jmp, cndl call
  3113.  
  3114. ;    Jump or call
  3115.  
  3116. xjmp:    call    idos
  3117.     jnz    xtwo
  3118.  
  3119. ;    Return
  3120.  
  3121. xret:    call    xrtn
  3122.     jmp    xtwo
  3123.  
  3124. ;    qdos - check whether DE = BDOS
  3125. ;    idos - check whether (DE) = BDOS
  3126.  
  3127. idos:    pop    b
  3128.     pop    h
  3129.     mov    e,m
  3130.     inx    h
  3131.     mov    d,m
  3132.     inx    h
  3133.     push    h
  3134.     push    b
  3135. qdos:    lda    GDOS+1    ;BDOS address
  3136.     cmp    e
  3137.     rnz    
  3138.     lda    GDOS+2    ;BDOS address
  3139.     cmp    d
  3140.     ret    
  3141.  
  3142. xrtn:    lhld    savsp    ;SP at breakpoint
  3143.     mov    e,m
  3144.     inx    h
  3145.     mov    d,m
  3146.     ret    
  3147.  
  3148. ;    Conditional jump or call
  3149.  
  3150. xcju:    call    idos
  3151.     jz    zdos
  3152.     pop    b
  3153.     push    b
  3154.     mvi    a,02
  3155.     jmp    xone
  3156.  
  3157. zdos:    pop    d
  3158.     push    d
  3159.     jmp    xtwo
  3160.  
  3161. ;    Restart
  3162.  
  3163. xrst:    mov    a,b
  3164.     cpi    0FFH
  3165.     jnz    xsvn
  3166.     xra    a
  3167.     jmp    xzer
  3168.  
  3169. xsvn:    ani    38H
  3170.     mov    e,a
  3171.     mvi    d,00
  3172.     jmp    xtwo
  3173.  
  3174. ;    PCHL
  3175.  
  3176. xpch:    lhld    savhl    ;HL at breakpoint
  3177.     xchg
  3178.     call    qdos    ;does DE = BDOS?
  3179.     jnz    xtwo
  3180.     jmp    xret
  3181.  
  3182. jtwo:    jmp    xtwo
  3183.  
  3184. ;    Other.
  3185.  
  3186. xoth:    pop    d
  3187.     push    d
  3188.     jmp    xtwo
  3189.  
  3190. ;    Conditional return.
  3191.  
  3192. xcrt:    call    xrtn
  3193.     pop    b
  3194.     push    b
  3195.     mvi    a,02
  3196.     jmp    xone
  3197.  
  3198. ;    LXI, LHLD
  3199.  
  3200. xlxi:    pop    d
  3201.     inx    d
  3202.     push    d
  3203.  
  3204. ;    Immediate move or arithmetic, in, out.
  3205.  
  3206. xmvi:    pop    d
  3207.     inx    d
  3208.     push    d
  3209. xtwo:    mvi    a,01
  3210. xone:    inr    a
  3211.     stc    
  3212. xzer:    pop    h
  3213.     ret    
  3214.  
  3215. mtbl:    db    0FFH,0C3H,0C7H,0C2H    ;jump, conditional jump
  3216.     db    0FFH,0CDH,0C7H,0C4H    ;call, conditional call
  3217.     db    0FFH,0C9H,0C7H,0C7H    ;return, restart
  3218.     db    0FFH,0E9H,0C7H,006H    ;pchl, immediate moves
  3219.     db    0C7H,0C6H,0CFH,001H    ;immediate arithmetc, lxi
  3220.     db    0E7H,022H,0C7H,0C0H    ;lhlf, conditional return
  3221.     db    0F7H,0D3H        ;in, out
  3222.  
  3223. ;    ---------------------------------------------------------
  3224.  
  3225. logo:    db    '       DDT(8080)/ICUAP',CR,LF
  3226.     db    'Universidad Autonoma de Puebla',CR,LF
  3227.     db    '      November 20, 1983',00
  3228.     dw    00,00,00,00,00,00,00;can't overwrite logo yet
  3229. savde:    dw    0000    ;save DE, tail of DDT stack    1
  3230. savbc:    dw    0000    ;save BC            2
  3231. savf:    db    00    ;save F                3
  3232. sava:    db    00    ;save A                4
  3233. savsp:    dw    0000    ;SP at breakpoint        5
  3234. savhl:    dw    0000    ;HL at breakpoint        6
  3235. savpc:    dw    0000    ;PC at breakpoint        7
  3236. savmr:    dw    0000    ;save memory reference        8
  3237. savxx:    dw    0000    ;storage for optx        9
  3238. sica:    dw    0000    ;site of call to BDOS
  3239. swtv:    db    00    ;T/V = z/nz
  3240. swtu:    db    00    ;T/U = nz/z
  3241. swgt:    db    00    ;G/T = z/nz
  3242. rept:    dw    0000    ;counter for commands
  3243. gbrk:    dw    0000    ;nG's breakpoint
  3244. gbrl:    dw    0000    ;nG's second breakpoint
  3245. gbrn:    db    00    ;nG's # of breakpoints
  3246. bkpt:    db    00    ;number of breakpoints
  3247. brkp:    dw    0000    ;first breakpoint
  3248. brkx:    db    00    ;first opcode
  3249. brkq:    dw    0000    ;second breakpoint
  3250. brky:    db    00    ;second opcode
  3251. pinc:    db    00    ;paragraph length
  3252. pctr:    db    00    ;paragraph counter
  3253. dorg:    dw    0000    ;origin for D
  3254. lorg:    dw    0000    ;origin for L
  3255. llim:    dw    0000    ;upper limit for "L"
  3256. pmax:    dw    0000    ;program high limit
  3257. ldsk:    db    00    ;logged disk
  3258. adsk:    db    00    ;active disk
  3259. cptr:    dw    0000    ;pointer to command buffer
  3260. cbuf:    db    80H    ;command buffer
  3261. clen:    db    00    ;command string length
  3262. ctex:    ds    80H    ;command text
  3263. enddt:    ds    0
  3264.  
  3265. ;    .dephase
  3266.  
  3267.     end
  3268.