home *** CD-ROM | disk | FTP | other *** search
-
- ; --------------------------------------------------------
- ; DDT.COM is a part of the collection of programs which
- ; one receives when buying CP/M from Digital Research. Of
- ; all the programs in the CP/M package, it is one of the
- ; weakest, and seems to have been mainly intended to use
- ; to insert the custom part of BIOS into CP/M when it is
- ; desired to generate a new system. Its strongest point is
- ; its single step facility and its suppression during the
- ; execution of BDOS. Its most frustrating point may be its
- ; lack of transparency to the command line of programs to
- ; which it is to be applied.
- ;
- ; The present program was based on a disassembly of the
- ; Digital Research version, which has now been very
- ; extensively rearranged, even though vestiges of that
- ; original program still remain. Several minor errors
- ; have been corrected, but the important changes consist
- ; in the greatly expanded capabilities of most of the
- ; options, besides a complete replacement of both the
- ; assembler and the disassembler. Many commands now admit
- ; a repeat factor, examination of registers and memory is
- ; much more extensive, and a bitmap can generated to mark
- ; significant memory locations. Other modifications or
- ; extensions may be deduced from the change log below.
- ;
- ; Since DDT will be coresident with the program it will
- ; examine, it is convenient to relocate it to high memory
- ; and adjust the BDOS call to reflect less free space. If
- ; an origin for the relocated DDT can be assigned, a small
- ; translation program is included to move it once loaded.
- ; It has been disabled by commenting it out. It would have
- ; to be assembled by Microsoft's M80 or a similar assembler
- ; allowing phasing and dephasing. It is much more general
- ; to generate a bitmap for a page relocator, for which the
- ; following script will serve as a guide. It assumes that
- ; the utilities LOHD.COM, GENBIM.COM, and PAGREL.COM are
- ; available; also that two separate copies of DDT were
- ; prepared: NDDT at origin 100H, and ZDDT at origin 000H,
- ; but otherwise identical.
- ;
- ; A>ASM NDDT.AAZ
- ; A>ASM ZDDT.AAZ
- ; A>LOHD NDDT
- ; A>LOHD ZDDT
- ; A>GENBIM ZDDT NDDT
- ; A>NDDT PAGREL [NEXT = 180]
- ; -IZDDT.COM
- ; -R100 [NEXT = 1600]
- ; -IZDDT.BIM
- ; -R1500 [NEXT = 1900]
- ; -S103
- ; . 0103 BB 00
- ; . 0104 BB 02
- ; . 0105 EE 00
- ; . 0106 EE 16
- ; h 0107 68 .
- ; -^C
- ; A>SAVE 24 NDDT.COM
- ;
- ; NDDT.ASM -- Copyright (C) 1983
- ; Universidad Autonoma de Puebla
- ; 20 November 1983
- ;
- ; ---------------: B generates a bitmap, L shows X's.
- ; ---------------: V is a T which ignores CALLs.
- ; 24 October 1982: R sets 007C to zero before starting.
- ; 24 October 1982: I will read an entire command line.
- ; 06 November 1982 - preliminary circulation copies.
- ; 12 December 1982 - XA shows both HEX, ASCII values.
- ; 12 December 1982 - X confirms register changes.
- ; 13 December 1982 - 007C zeroed while opening file.
- ; 13 December 1982 - I <pop h> when leaving HEX option.
- ; 13 December 1982 - <no extension> taken as .COM
- ; 13 December 1982 - P "Peek" added.
- ; 16 December 1982 - E "Execute" added.
- ; 18 December 1982 - S accepts quoted character.
- ; 20 December 1982 - edition for Assembler II.
- ; 7 August 1983 - correct overwrite of b in G.
- ; 7 August 1983 - zero 7C after initial program load.
- ; 20 August 1983 - clear memory before loading.
- ; 20 August 1983 - decimal prefix to all commands.
- ; 22 August 1983 - new format for display line.
- ; 22 August 1983 - En,xxxx superseded by nG,xxxx.
- ; 23 August 1983 - nV/, nT/, nU/ suppress display lines.
- ; 23 August 1983 - X=xxxx displays a window around xxxx.
- ; 23 August 1983 - nU superseded by nT/.
- ; 23 August 1983 - P incorporated into X.
- ; 26 August 1983 - M moves overlapping interval backwards.
- ; 26 August 1983 - A does not leave 3 0D's on exit.
- ; 28 August 1983 - General rearrangement and revision.
- ; 30 August 1983 - Edition for Languages II.
- ; 20 November 1983 - X - jz for jnz refused flag changes.
- ; 20 November 1983 - ASM - assembly of RST N was wrong.
- ; 20 November 1983 - stor - xra a to avoid false signals.
- ; [Harold V. McIntosh, 20 December 1982]
- ; [Harold V. McIntosh, 30 August 1983]
- ; --------------------------------------------------------
-
- HT equ 09H ;tab
- LF equ 0AH ;line feed
- CR equ 0DH ;carriage return
- KZ equ 1AH ;^Z
- RO equ 7FH ;rubout
-
- ;ddtorg equ 09000H ;absolute DDT origin
- ;
- ;
- ;; Move DDT up to higher memory.
- ;
- ;X0100: lxi b,enddt-begn
- ;X013D: lxi sp,begn
- ; lxi d,ddtorg
- ; lxi h,X0165
- ;X0158: mov a,b
- ; ora c
- ; jz ddtorg
- ; dcx b
- ; mov a,m
- ; stax d
- ; inx d
- ; inx h
- ; jmp X0158
- ;X0165: ds 0
- ;
- ;; -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;
- ; .phase ddtorg
-
- org 0100H
-
- begn: jmp init ;initialize DDT
-
- ; ========================================================
- ; Assembler for the INTEL 8080. As a "small" assembler,
- ; it is subject to the following restraints:
- ; 1) only hexadecimal numbers are accepted
- ; 2) opcode identification is merely sufficient
- ; 3) source code is not confined to a single line
- ; 4) error detection only for an unintelligible
- ; opcode or field; then three zero bytes are
- ; deposited to allow patches, assembler line
- ; is abandoned
- ; 5) implausible combinations are not rejected
- ;
- ; Register pair HL points to the byte in which the
- ; assembled opcode will be stored. If necessary, hex
- ; data or address fields will be read and HL will be
- ; incremented by 1, 2, or 3 as required. Flags are valid
- ; on return; zero means no error.
- ;
- ; No RAM memory is used directly by the program, so that
- ; it may be inscribed in its entirity in a PROM. All its
- ; requirements for temporary storage are met from the
- ; internal registers of the 8080 or the stack.
- ; ========================================================
-
- assm: push h
- lxi h,stor
- push h
- call alfa
- jmp aopco
-
- ; Read an alpha field by ignoring leading separators,
- ; storing letters in registers C,D,E, and terminating
- ; reading when a separator is again encountered. All
- ; fields are held to three letters, so that the only
- ; letters in a chain that are stored are the first,
- ; second, and last.
-
- alfa: lxi d,' '
- ala: call relc
- call sepa
- jz ala
- mov c,a
- call relc
- call sepa
- rz
- call term
- rz
- mov d,a
- alb: call relc
- call sepa
- rz
- call term
- rz
- mov e,a
- jmp alb
-
- ; Read an alpha field with the intention of keeping only
- ; the last letter in the field. Otherwise the same rules
- ; apply as in the subroutine alfa: leading separators are
- ; ignored, trailing separators terminate.
-
- beta: call relc
- call sepa
- jz beta
- bet: mov b,a
- call relc
- call sepa
- jz bta
- call term
- jnz bet
- bta: mov a,b
- ret
-
- ; Locate the operation codes. A simple linear search is
- ; made of some sixty mnemonics, grouping them mostly in
- ; sets of eight because their position within an octet
- ; translates directly into a source or destination field
- ; in the 2-3-3 decomposition of INTEL 8080 opcodes.
-
- aopco: mvi b,0CH
- lxi H,AT4 ;Quadrant 0 with minor modifications
- call mnem
- jp AQ0
- mvi b,01H
- lxi h,AT0 ;Quadrant 1: interregister movements
- call mnem
- jp AQ1
- mvi b,08H
- lxi h,AT1 ;Quadrant 3: arithmetic-logical
- call mnem
- jp AQ2
- mvi b,08H
- lxi h,AT2 ;Quadrant 2, column 6: immediate
- call mnem
- jp AB6
- mvi b,11H
- lxi h,AT5 ;All the sporadic opcodes
- call mnem
- jp qq
- mvi b,08H
- lxi h,AT3 ;Quadrant 0, column 7: accumulator
- call mnem
- jp AA7
- mov a,c
- cpi 'r'
- jz AB0 ;Quadrant 3, column 0: returns
- cpi 'j'
- jz AB2 ;Quadrant 3, column 2: jumps
- cpi 'c'
- jz AB4 ;Quadrant 3, column 4: calls
- mvi b,05H
- lxi h,AT7 ;Assembler directives
- call mnem
- jp QD
- jmp hexb
-
- ; Quadrant zero - memory to register - and some others.
-
- AQ0: mov c,a
- call juta
- dw X0 ;pop pair
- dw AA1 ;lxi pair,addr
- dw AA0 ;stax pair - beware - only b, d legal
- dw AA0 ;inx pair
- dw AA4 ;inr register
- dw AA4 ;dcr register
- dw AA6 ;mvi register,data
- dw AB7 ;rst digit in opcode
- dw Y0 ;push pair
- dw AA0 ;dad pair
- dw AA0 ;ldax pair - beware - only b, d legal
- dw AA0 ;dcx pair
-
- X0: mvi c,0C1H
- jmp AA0
- Y0: mvi c,0C5H
- AA0: call beta
- call apair
- ora c
- ret
-
- AA1: call AA0
- jmp addq
-
- AA4: call rdst
- ora c
- ret
-
- AA6: call AA4
- jmp datq
-
- AA7: add a
- add a
- add a
- ori 07H
- ret
-
- AQ1: call rdst
- mov c,a
- call rsrc
- ora c
- ori 040H
- ret
-
- AQ2: add a
- add a
- add a
- mov c,a
- call rsrc
- ora c
- ori 080H
- ret
-
- qq: cpi 09H
- jc ss
- lxi h,adata
- cpi 0BH
- jc rr
- lxi h,aaddr
- rr: xthl
- ss: lxi h,AT8
- jmp reta
-
- ; Quadrant 3 - mostly program counter modification
-
- AB0: mvi a,0C0H
- jmp abb
- AB2: mvi a,0C2H
- call abb
- jmp addq
- AB4: mvi a,0C4H
- call abb
- jmp addq
- abb: push psw
- mvi c,' '
- mvi b,08H
- lxi h,AT6
- call mnem
- pop b
- jm error
- add a
- add a
- add a
- ora b
- ret
-
- ; Immediates.
-
- AB6: add a
- add a
- add a
- ori 0C6H
- jmp datq
-
- ; Restarts.
-
- AB7: call beta
- rlc
- rlc
- rlc
- ani 038H
- ori 0C7H
- ret
-
- ; Assembler directives.
-
- QD: call juta
- dw D0 ;data byte
- dw D1 ;data word
- dw D2 ;data space
- dw D3 ;origin
- dw D4 ;end
-
- D0: inx sp ;data byte
- inx sp
- pop d
- call hxar
- mov l,a
- mvi a,0FDH ;error
- rnz
- inr a ;(org)
- xchg
- mov m,e
- inx h
- ret
-
- D1: inx sp ;data word
- inx sp
- pop d
- call hexf
- mvi a,0FDH ;error
- rnc
- inr a ;(org)
- xchg
- mov m,e
- inx h
- mov m,d
- inx h
- ret
-
- D2: inx sp ;data space
- inx sp
- pop d
- call hexf
- mvi a,0FDH ;error
- rnc
- inr a ;org
- dad d
- ret
-
- D3: inx sp ;origin
- inx sp
- inx sp
- inx sp
- call hexf
- mvi a,0FEH ;org
- rc
- dcr a
- ret
-
- D4: inx sp ;end
- inx sp
- inx sp
- inx sp
- mvi a,0FFH ;done
- ret
-
- ; If the operation field did not hold a valid opcode or
- ; assembler directive, try it out for a one-byte, two
- ; nibble hexadecimal byte.
-
- hexb: lxi h,error
- push h
- mov a,e
- cpi ' '
- rz
- mov a,c
- call cnh
- rc
- add a
- add a
- add a
- add a
- mov b,a
- mov a,d
- call cnh
- rc
- add b
- inx sp
- inx sp
- ret
-
- ; Read and deposit a hexadecimal address field.
-
- addq: inx sp
- inx sp
- aaddr: mov b,a
- call onar
- xchg
- pop h
- mov m,b
- inx h
- mov m,e
- inx h
- mov m,d
- inx h
- ret
-
- ; Read and deposit a one-byte hexadecimal data field.
-
- datq: inx sp
- inx sp
- adata: mov b,a
- call hxar
- jnz error ;<missing field>
- xchg
- pop h
- mov m,b
- inx h
- mov m,e
- inx h
- ret
-
- ; Deposit the assembled operation code
-
- stor: pop h
- mov m,a
- inx h
- xra a ;don't return the wrong signal
- ret
-
- ; Load accumulator with nth item in the list whose
- ; origin is contained in register pair HL, when n
- ; lies in the accumulator.
-
- reta: add l
- mov l,a
- mov a,h
- aci 00H
- mov h,a
- mov a,m
- ret
-
- ; Find numerical equivalents for register designations.
- ; Source registers are reported at their true value, but
- ; destination registers are multiplied by eight to have
- ; their value positioned correctly for its field.
-
- rsrc: call beta
- srce: mvi b,08H
- lxi h,atr
- call regi
- jm error
- ret
-
- rdst: call beta
- dest: call srce
- add a
- add a
- add a
- ret
-
- ; Find numerical equivalents for register pair symbols.
- ; They always left-pack their destination field.
-
- apair: mvi b,05H
- lxi h,atp
- call regi
- jm error
- cpi 04H
- cmc
- sbi 00H
- mov b,a
- add a
- add a
- add a
- add a
- ret
-
- ; Search a list of bytes whose origin is contained in
- ; in HL to find the one, if any, which matches the
- ; accumulator. The length of the list in is B on entry;
- ; on exit A contains either the position or FF if no
- ; match was found.
-
- regi: dcx h
- cmp m
- jz reg
- dcr b
- jnz regi
- reg: xra a
- dcr b
- ora b
- ret
-
- ; Search a table of three-letter mnemonics to find the
- ; code contained in registers C,D,E. Enter with the
- ; table origin in pair HL, the table size N in the
- ; accumulator. On exit the accumulator will contain
- ; either the position, ranging between 0 and N-1, of
- ; the item in the table, or else FF(hex) if it was not
- ; found.
-
- mnem: dcx h
- mov a,m
- cmp e
- jnz mnb
- dcx h
- mov a,m
- cmp d
- jnz mnc
- dcx h
- mov a,m
- sub c
- jnz mnd
- mna: dcr b
- ora b
- ret
- mnb: dcx h
- mnc: dcx h
- mnd: dcr b
- jnz mnem
- jmp mna
-
- ; Table of mnemonics grouped by octets and dodecuplets.
-
- dtr: db 'bcdehlma'
- atr: db 'bdhpw'
- atp: db 'mov'
- AT0: db 'add','adc','sub','sbb'
- db 'ana','xra','ora','cmp'
- AT1: db 'adi','aci','sui','sbi'
- db 'ani','xri','ori','cpi'
- AT2: db 'rlc','rrc','ral','rar'
- db 'daa','cma','stc','cmc'
- AT3: db 'pop','lxi','stx','inx'
- db 'inr','dcr','mvi','rst'
- db 'puh','dad','ldx','dcx'
- AT4: db 'nop','ret','pcl','spl'
- db 'xtl','xcg','di ','ei '
- db 'hlt','out','in ','jmp'
- db 'cal','shd','lhd','sta','lda'
- AT5: db ' nz',' z ',' nc',' c '
- db ' po',' pe',' p ',' m '
- AT6: db 'db ','dw ','ds ','org','end'
- AT7: db nop
- db ret
- db pchl
- db sphl
- db xthl
- db xchg
- db di
- db ei
- db hlt
- db 0D3H ;(out)
- db 0DBH ;(in)
- db 0C3H ;(jmp)
- db 0CDH ;(call)
- db 022H ;(shld)
- db 02AH ;(lhld)
- db 032H ;(sta)
- db 03AH ;(lda)
-
- ; T7 is the end of one table, T8 is the beginning of another.
-
- AT8 equ AT7
-
-
- ; =====================================================
- ; Disassembler for the INTEL 8080. Register pair HL
- ; points to the byte to be disassembled. HL will be
- ; incremented by 1, 2, or 3 according to the type of
- ; instruction encountered. No RAM storage is used
- ; within the program, which may therefore be entirely
- ; resident in ROM.
- ; =====================================================
-
- dism: mov a,m
- push h
- lxi h,done
- push h
- cpi 76H
- jnz split
- halt: lxi h,td
- jmp three
-
- ; separate the instruction field into groups of 2,3,3
- ; bits and then continue according to quadrants.
-
- split: push psw
- push psw
- ani 07H
- mov c,a
- pop psw
- rrc
- rrc
- rrc
- ani 07H
- mov b,a
- pop psw
- rlc
- rlc
- ani 03H
- lxi h,jq
- jump: call bndx
- mov e,m
- inx h
- mov d,m
- xchg
- pchl
-
- ; Indexing subroutines which add corresponding multiples
- ; [3,4,2,1] of A to the register pair HL.
-
- tndx: mov e,a
- add a
- add e
- jmp indx
- qndx: add a
- bndx: add a
- indx: add l
- mov l,a
- mov a,h
- aci 00H
- mov h,a
- ret
-
- ; -------------------------------------------------------
- ; Quadrant 0 contains accumulator operations, increments,
- ; decrements, loads, stores and immediate moves, all of
- ; which must be detailled further.
- ; -------------------------------------------------------
-
- DQ0: mov a,c
- lxi h,ja
- jmp jump
-
- ; Column 0 contains NOP together with seven unused codes
-
- DA0: mov a,b
- ora a
- jnz node
- noop: lxi h,tc
- jmp trey
-
- ; Column 1 alternates lxi to a register pair with dad
- ; from a register pair. The lxi's require data words,
- ; but not the dad's.
-
- DA1: mov a,b
- ani 01H
- call aa
- mov a,b
- ani 01H
- rnz
- call sngl
- jmp daddr
-
- ; Column 2 alternates storing and loading instructions.
- ; The first six refer to register pairs, the last two to
- ; the accumulator; the last four require addresses.
-
- DA2: mov a,b
- lxi h,DT5
- call vier
- mov a,b
- ani 04H
- jz putp
- jmp daddr
-
- ; Column 3 alternates inx of a register pair with dcx of
- ; the same pair.
-
- DA3: mov a,b
- ani 01H
- adi 02H
- aa: lxi h,DT4
- call drei
- jmp putp
-
- ; Column 4 contains inr, 5 containd dcr, both modified
- ; by the register list.
-
- DA4: mov a,c
- lxi h,DT4
- call drei
- mov a,b
- lxi h,dtr
- jmp ein
-
- ; Column 6 contains the mvi's, which require a data byte.
-
- DA6: call DA4
- call sngl
- jmp ddata
-
- ; Column 7 contains the accumulator operations.
-
- DA7: mov a,b
- lxi h,AT2
- call tndx
- jmp trey
-
- ; ----------------------------------------------------------
- ; Quadrant 1 consists of interregister movements.
- ; ----------------------------------------------------------
-
- DQ1: lxi h,tb
- call three
- mov a,b
- lxi h,dtr
- call ein
- call sngl
- mov a,c
- lxi h,dtr
- jmp ein
-
- ; ----------------------------------------------------------
- ; Quadrant 2 consists of arithmetic operations
- ; ----------------------------------------------------------
-
- DQ2: mov a,b
- lxi h,AT0
- call drei
- mov a,c
- lxi h,dtr
- jmp ein
-
- ; ---------------------------------------------------------
- ; Quadrant 3 has returns, calls, jumps, pushes, pops,
- ; and a variety of miscellania needing a detailed study.
- ; ---------------------------------------------------------
-
- DQ3: mov a,c
- lxi h,jb
- jmp jump
-
- ; Column 0 contains all the conditional returns
-
- DB0: mvi a,'r'
- bb: call aout ;A to console
- mov a,b
- lxi h,AT5
- call tndx
- inx h
- jmp two
-
- ; Column 1 contains the pops, together with the unconditional
- ; return, pchl, sphl, and an undefined code.
-
- DB1: mov a,b
- lxi h,DT7
- call vier
- mov a,b
- cpi 03H
- jz dopco
- ani 01H
- rnz
- jmp putq
-
- ; Column 2 contains all the conditional jumps.
-
- DB2: mvi a,'j'
- call bb
- jmp daddr
-
- ; Columnn 3 is an assortment, requiring many distinctions.
-
- DB3: mov a,b
- lxi h,DT8
- call vier
- mov a,b
- cpi 04H
- rnc
- cpi 01H
- jz dopco
- jc daddr
- jmp ddata
-
- ; Column 4 contains all the conditional calls.
-
- DB4: mvi a,'c'
- call bb
- jmp daddr
-
- ; Column 5 contains the pushes, simple call, 3 undefined.
-
- DB5: mov a,b
- ani 01H
- jnz xx
- lxi h,tf
- call four
- jmp putq
- xx: mov a,b
- cpi 01H
- jnz node
- lxi h,te
- call four
- jmp daddr
-
- ; Column 6 holds all the arithmetic immediates.
-
- DB6: mov a,b
- lxi h,AT1
- call drei
- jmp ddata
-
- ; Column 7 contains all the restarts.
-
- DB7: lxi h,DT4+21
- call three
- mov a,b
- adi '0'
- jmp aout ;A to console
-
- ; ------------------------------------------------------
- ; a collection of copying and spacing routines.
- ; ------------------------------------------------------
-
- vier: call qndx
- jmp four
- drei: call tndx
- jmp three
- ein: call indx
- jmp one
-
- four: call quad
- jmp sngl
- three: call trey
- jmp dubl
- two: call dpair
- jmp dubl
-
- quad: mov a,m
- call aout ;A to console
- inx h
- trey: mov a,m
- call aout ;A to console
- inx h
- dpair: mov a,m
- call aout ;A to console
- inx h
- one: mov a,m
- jmp aout ;A to console
-
- ; -------------------------------------------------------
- ; Commonly used transferrence and conversion routines.
- ; -------------------------------------------------------
-
- putp: mov a,b
- ani 06H
- lxi h,dtp
- call indx
- jmp dpair
-
- putq: mov a,b
- ani 06H
- rrc
- lxi h,tq
- call tndx
- jmp trey
-
- done: pop h
- inx h
- ret
-
- daddr: inx sp
- inx sp
- pop h
- inx h
- mov e,m
- inx h
- mov d,m
- push h
- call word
- jmp done
-
- node: lxi h,ta
- call three
- dopco: inx sp
- inx sp
- pop h
- jmp goby
-
- ddata: inx sp
- inx sp
- pop h
- inx h
- goby: mov a,m
- push h
- call byte
- jmp done
-
- ; --------------------------------------------------------
- ; Jump tables
- ; --------------------------------------------------------
-
- jq: dw DQ0,DQ1,DQ2,DQ3
-
- ja: dw DA0,DA1,DA2,DA3,DA4,DA4,DA6,DA7
-
- jb: dw DB0,DB1,DB2,DB3,DB4,DB5,DB6,DB7
-
- ; --------------------------------------------------------
- ; Tables of mnemonics for the 8080 instructions
- ; --------------------------------------------------------
-
- ta: db 'db '
- tb: db 'mov'
- tc: db 'nop'
- td: db 'hlt'
- te: db 'call'
- tf: db 'push'
-
- dtp: db 'b d h sp'
-
- tq: db 'b '
- db 'd '
- db 'h '
- db 'psw'
-
- DT4: db 'lxi','dad','inx','dcx'
- db 'inr','dcr','mvi','rst'
-
- DT5: db 'stax','ldax','stax','ldax'
- db 'shld','lhld','sta ','lda '
-
- DT7: db 'pop ','ret ','pop ','db '
- db 'pop ','pchl','pop ','sphl'
-
- DT8: db 'jmp ','db ','out ','in '
- db 'xthl','xchg','di ','ei '
-
- ; -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- DP equ 16 ;paragraph length for D
- NL equ 12 ;default lines in L
- NR equ 12 ;number of registers to examine in X
- WW equ 5 ;window halfwidth in register display
-
- BDOS equ 0005H ;jump to BDOS
- RST7 equ 0038H ;DDT breakpoint handler
- TFCB equ 005CH ;DDT's file control block
- TBUF equ 0080H ;DDT's sector buffer
- TORG equ 0100H ;program origin
-
- bsiz equ 2000H ;8K = size of bitmap
-
- XDOS: xthl ;<<DDT analogue of 0005>>
- shld sica ;site of call to BDOS
- xthl
- GDOS: jmp 0000 ;BDOS address
-
- ; Initialize DDT
-
- init: lhld BDOS+1
- shld GDOS+1 ;BDOS address
- lxi h,XDOS ;DDT analogue of 0005
- shld begn+1
- lxi h,begn
- shld BDOS+1
- xra a
- sta bkpt ;breakpoint data
- lxi h,TORG ;CP/M transient origin
- shld lorg ;origin for L
- shld dorg ;origin for D
- shld pmax ;program high limit
- shld savpc ;PC at breakpoint
- shld savmr ;memory reference
- lxi sp,savhl ;breakpoint
- push h
- lxi h,0002
- push h
- dcx h
- dcx h
- shld savhl ;HL at breakpoint
- push h
- push h
- mvi a,0C3H ;(jmp)
- sta RST7 ;RST 7 destination
- lxi h,rtbk ;return from breakpoint
- shld RST7+1
- lxi b,begn ;top of memory
- lxi h,TORG ;bottom of memory
- mov a,c
- sub l
- mov c,a
- mov a,b
- sbb h
- mov b,a
- zero: mov a,c
- ora b
- jz zerd
- mvi m,00
- inx h
- dcx b
- jmp zero
- zerd: lxi h,logo ;"DDT/UAP"
- call mssg
- mvi c,25 ;(19) read logged in disk
- call XDOS
- sta ldsk ;logged disk
- mvi b,80H
- lxi d,TBUF
- lxi h,ctex
- shld cptr ;pointer to command buffer
- lxi h,clen
- muve: ldax d
- mov m,a
- inx h
- inx d
- dcr b
- jnz muve
- mov m,b
- lxi h,loop ;DDT loop
- push h
- lda TFCB+1 ;file name
- cpi ' '
- rz
- lxi h,TFCB+9 ;extension
- mov a,m
- cpi ' '
- jnz scom
- mvi m,'C'
- inx h
- mvi m,'O'
- inx h
- mvi m,'M'
- scom: lxi h,0000 ;zero offset
- call opra ;R with implicit argument
- jmp opia ;I after discarding program name
-
- ; ----------------------------------------------
- ; DDT loop: waits for commands and executes them
- ; ----------------------------------------------
-
- loop: lxi sp,savde ;DDT's private stack
- lxi h,loop ;DDT loop
- push h
- call past ;check limit transgression
- jc looq
- lxi h,XDOS ;link to BDOS
- shld 0006H
- looq: call crlf ;type CR,LF
- mvi a,'-'
- call aout ;A to console
- call incl ;fetch a command line
- call decf ;read decimal field
- cpi CR
- rz
- shld rept
- call alta ;alternate table
- db 14
- db 'A'
- dw opta ;A = assemble
- db 'B'
- dw bmap ;B = bitmap
- db 'D'
- dw optd ;D = display
- db 'F'
- dw optf ;F = fill
- db 'G'
- dw optg ;G = go
- db 'H'
- dw opth ;H = hex sum, difference
- db 'I'
- dw opti ;I = initialize CCP command line
- db 'L'
- dw optl ;L = list program
- db 'M'
- dw optm ;M = move
- db 'R'
- dw optr ;R = read file
- db 'S'
- dw opts ;S = store
- db 'T'
- dw optt ;T = type registers
- db 'V'
- dw optv ;V = single step w/ call as 1 step
- db 'X'
- dw optx ;X = examine registers
-
- ; (A) Assemble 8080 code. <nAx> will assemble n lines
- ; of code beginning at address x. Defaults are x=lorg,
- ; while no limit is set if n is missing or zero.
-
- opta: call past ;check limit transgression
- jnc error ;<A has been overwritten>
- lhld lorg ;origin for L
- call hef
- opaa: shld lorg ;origin for L
- call dubl
- call tyhl ;type HL as four nibbles
- call dubl
- call incl ;fetch a command line
- jz opac
- call assm
- inr a ;FF means done
- rz
- inr a ;FE means new origin
- jnz opab
- call crlf
- jmp opaa
- opab: call ctlx
- lhld lorg ;origin for L
- inr a ;FD means error - retry
- jz opaa
- opac: call dubl ;otherwise confirm & advance
- call tyhl ;type HL as four nibbles
- call dubl
- call dism
- call crlf
- call drnz ;decrement retn if nonzero
- jnz opaa
- shld lorg ;origin for L
- ret
-
- ; (B) Generate a bitmap of all bytes in the range
- ; 100H - (pmax) which could possibly be the address
- ; of an instruction.
-
- bmap: lhld pmax
- xchg
- lxi h,begn
- lxi b,-bsiz
- dad b
- mov a,l
- sub e
- mov a,h
- sbb d
- jc error ;<bitmap would overlap program>
- lxi b,bsiz
- bzer: mvi m,00H
- inx h
- dcx b
- mov a,c
- ora b
- jnz bzer
- lhld pmax ;program high limit
- xchg
- lxi h,TORG ;CP/M transient origin
- mov a,e
- sub l
- mov c,a
- mov a,d
- sbb h
- mov b,a
- bbit: push b
- mov a,m
- call twob
- jnc bbjt
- push h
- inx h
- mov e,m
- inx h
- mov d,m
- xchg
- call wrib
- pop h
- bbjt: inx h
- pop b
- dcx b
- mov a,c
- ora b
- jnz bbit
- ret
-
- ; Decide if opcode has one-byte sequel.
-
- oneb: cpi 0D3H
- jz oney
- cpi 0DBH
- jz oney
- ani 0C7H
- cpi 006H
- jz oney
- cpi 0C6H
- jz oney
- stc
- cmc
- ret
- oney: stc
- ret
-
- ; decide if opcode has two-byte address
-
- twob: push b
- cpi 0C3H
- jz twoy
- cpi 0CDH
- jz twoy
- mov b,a
- ani 0C7H
- cpi 0C2H
- jz twoy
- cpi 0C4H
- jz twoy
- mov a,b
- ani 0CFH
- cpi 001H
- jz twoy
- mov a,b
- ani 0E7H
- cpi 022H
- jz twoy
- stc
- cmc
- pop b
- ret
- twoy: stc
- pop b
- ret
-
- ; read bit corresponding to address HL
-
- reab: push h
- call biby ;addr = byte + bit
- mov a,m
- rea: rrc
- dcr c
- jnz rea
- pop h
- ret
-
- ; define bit corresponding to address HL
-
- wrib: push psw
- call biby ;addr = byte + bit
- push b
- mov a,m
- wra: rrc
- dcr c
- jnz wra
- mov m,a
- pop b
- pop psw
- mov a,m
- ral
- rrc
- wrb: rlc
- dcr c
- jnz wrb
- mov m,a
- ret
-
- ; reduce an address to byte (HL), bit (C).
-
- biby: mov a,l
- ani 07H
- inr a
- mov c,a
- mvi b,3
- bib: mov a,h
- rar
- mov h,a
- mov a,l
- rar
- mov l,a
- dcr b
- jnz bib
- mov a,h
- ani 1FH
- mov h,a
- lxi d,begn
- dad d
- lxi d,-bsiz
- dad d
- ret
-
- ; (D) Display the memory in groups of 16 bytes, both as
- ; pairs of hexadecimal nibbles and as ASCII characters,
- ; when the latter is appropriate. The command <nDa,b>
- ; will display n lines, or else the interval between
- ; hexadecimal addresses a and b; the interval takes
- ; precedence but if a or b or both are null, the line
- ; count helps determine the interval. When a is null the
- ; display will usually continue from where it last ended,
- ; but nD,b will display b-n up to b. In general:
- ; nDa,b a through b-1, n lines of 16 bytes
- ; Da,b a through b-1, DP lines of 16 bytes
- ; nDa, a through a+n
- ; nD,b b-n through b
- ; nD, PC through PC+n
- ; Da, a to the end
- ; Da just line containing a
- ; D,b PC through b
- ; D, PC to the end
- ; D just line beginning at PC
-
- optd: lxi h,pinc ;paragraph length
- mvi m,DP
- lhld rept
- mov a,l
- ora h
- sui 1
- sbb a
- ani 01H
- mov b,a ;1 means n=0
- dad h
- dad h
- dad h
- dad h
- shld rept ;1 line is worth 16 bytes
- lhld dorg ;default <a> is dorg
- call hef ;read <a>
- mov c,a
- mov a,b
- ral
- mov b,a ;0 means null <a>
- xchg
- lhld rept
- dad d ;<a+n> is default <b>
- mov a,c
- sui CR
- jz opda
- lxi h,0FFF0H
- opda: sui 1
- mov c,a ;FF means CR
- mov a,b
- ral
- mov b,a ;1 means CR
- call hef ;read <b>
- mov a,b
- ral
- mov b,a
- inr c
- jnz opdb ;z means CR
- lhld rept
- dad d
- opdb: shld dorg
-
- ; At this point, DE=<a>, HL=<b>, B defines case,
- ; but a few anomalies still have to be resolved.
-
- mov a,b
- cpi 01H
- jnz opdc
- lhld dorg
- xchg
- lhld rept
- mov a,e
- sub l
- mov l,a
- mov a,d
- sbb h
- mov h,a
- xchg ;else a=b-n
- opdc: cpi 05H
- jz opdd
- cpi 04H
- jz opdd
- cpi 00H
- jnz opde
- opdd: lhld rept
- dad h
- dad h
- dad h
- dad h
- mov a,h
- sta pinc ;paragraph length
-
- ; The parameters are now ready to start typing.
-
- opde: lhld dorg
- xchg
- mov a,e
- sub l
- mov a,d
- sbb h
- jc error ;<inverted interval>
- lda pinc ;paragraph length
- mov b,a
- opdf: call crlf ;type CR,LF
- call inst ;read console status
- jz opdg
- shld dorg ;mark stopping point
- ret
- opdg: call tyhl ;type HL as four nibbles
- push h
- call dubl
- call hebl
- call sngl ;type space
- pop h
- mvi c,10H
- call ascl
- dcr b
- jnz opdh
- lda pinc ;paragraph length
- mov b,a
- call crlf
- opdh: mov a,l
- sub e
- mov a,h
- sbb d
- jc opdf
- ret
-
- hebl: call oobl
- oobl: call fobl
- fobl: call tetr
- jmp sngl
-
- tetr: call duce
- duce: call once
- once: mov a,m
- call byte
- inx h
- jmp sngl
-
- ; (F) Fill an interval. <Fx,y,a> will fill the interval
- ; from x to y with the hexadecimal value a.
-
- optf: call onar
- push h
- call onar
- xchg
- call hxar
- jnz error ;<nonstandard argument>
- mov b,a
- pop h
- opfa: mov a,l ;cmp(HL,DE)
- sub e
- mov a,h
- sbb d
- rnc
- mov m,b
- inx h
- jmp opfa
-
- ; (G) Go to the program for execution. The form <nG,a,b,c>
- ; allows the insertion of up to two breakpoints, b and c,
- ; before jumping to the address a. If a count n is also
- ; included, the breakpoints will be traversed n times
- ; before control is t returned to DDT. If the field a is
- ; null, the program will continue from the point where
- ; control was surrendered to DDT (or 100H if it is an
- ; initial call.
-
- optg: call crlf ;type CR,LF
- xra a
- sta swtv ;T/V = z/nz
- sta swgt ;G/T = z/nz
- lhld rept
- dad h
- shld rept
- lhld savpc ;PC at breakpoint
- call hef ;fetch a
- shld savpc
- push h
- cpi CR
- mvi a,1
- jz opga
- call hexf ;fetch b
- jnc gnex
- shld gbrk ;nG's breakpoint
- xchg
- call hexf ;fetch c
- mvi a,2
- jnc opga
- shld gbrl
- inr a
- mov b,h
- mov c,l
- opga: pop h
- sta gbrn
- ora a
- jmp gprg ;G without arguments
-
- ; G without arguments
- ; z unconditional go (savsp)
- ; c ignore HL, but set breakpoints
- ; A number of arguments - 0,1,2,3
- ; HL explicit destination
- ; DE first breakpoint
- ; BC second breakpoint
-
- gnex: call step
- gprg: di
- jz gnez ;no arg, unconditional go
- jc gney ;comma, set breakpoint & go
- shld savpc ;PC at breakpoint
- gney: dcr a
- sta bkpt
- jz gnez ;one arg already noted
- xchg
- mov e,a
- mov a,m
- sta brkx
- mvi m,0FFH ;RST 7
- shld brkp
- dcr e
- jz gnez ;unless 2nd breakpoint
- mov l,c
- mov h,b
- mov a,m
- sta brky
- mvi m,0FFH ;RST 7
- shld brkq
-
- ; Restore registers and return to program.
-
- gnez: lxi sp,savde ;DDT's private stack
- pop d
- pop b
- pop psw
- pop h
- sphl
- lhld savpc ;PC at breakpoint
- push h
- lhld savhl ;HL at breakpoint
- NOP
- ret
-
- ; (H) Display a hexadecimal sum and difference. <Hx,y>
- ; will result in typing '+'x+y '-'x-y. Mainly used to
- ; help patch CP/M during system generation.
-
- opth: call onar
- xchg
- call onar
- xra a
- sub l
- mov c,a
- sbb h
- sub c
- mov b,a
- call crlf ;type CR,LF
- dad d
- mvi a,'s' ;"sum"
- call aout
- call tyhl ;type HL as four nibbles
- call sngl ;type space
- xchg
- dad b
- mvi a,'d' ;"difference"
- call aout
- jmp tyhl ;type HL as four nibbles
-
- ; (I) Input a command line, according to the same
- ; criteria used by CCP; in other words a parameter
- ; list can follow the file name.
-
- opia: call fico
- opti: lxi d,TBUF
- lhld cptr ;pointer to command buffer
- lda clen
- mov b,a
- inr b
- moov: stax d
- mov a,m
- call lcfo
- inx d
- inx h
- dcr b
- jnz moov
- mvi a,00
- stax d
- lxi h,TBUF+1
- shld cptr ;pointer to command buffer
- call fico
- lxi h,adsk ;active disk
- push h
- mov a,m
- sta TFCB ;CP/M default FCB
- mvi a,10H
- call fica
- pop h
- mov a,m
- sta TFCB+16
- xra a
- sta TFCB+32
- jmp crlf
-
- zsep: ora a
- rz
- cpi CR
- rz
- cpi ' '
- jc error ;<control chars in command line>
- rz
- cpi '='
- rz
- cpi '_'
- rz
- cpi '.'
- rz
- cpi ':'
- rz
- cpi ';'
- rz
- cpi '<'
- rz
- cpi '>'
- ret
-
- fsep: call zsep
- rz
- call rech ;read one character
- jmp fsep
- ret
-
- ; Advance to a non blank character in the console
- ; buffer unless there is none, indicated by a 00.
-
- zonb: call rech ;read one character
- ora a
- rz
- cpi ' '
- jz zonb ;zero or non-blank
- ret
-
- ; Generate a file control block in the manner of CCP.
-
- fico: mvi a,00
- fica: lxi h,TFCB
- add l
- mov l,a
- mov a,h
- aci 00
- mov h,a
- xra a
- sta adsk ;active disk
- call zonb ;zero or non-blank
- push psw
- jz ficb
- sbi '@'
- mov b,a
- push h
- lhld cptr ;pointer to command buffer
- mov a,m
- pop h
- cpi ':'
- jz ficc
- ficb: lda ldsk ;logged disk
- jmp ficd
- ficc: call rech ;read one character
- pop psw
- call rech ;read one character
- push psw
- mov a,b
- sta adsk ;active disk
- ficd: mov m,a
- inx h
- mvi b,08
- pop psw
- call ffil
- call fsep
- mvi b,03
- cpi '.'
- jnz ficp
- call rech ;read one character
- call ffil
- call fsep
- jmp ficq
- ficp: call bfil
- ficq: mvi b,03
- mvi c,00
- jmp kfil
-
- ; Fill a field
-
- ffil: call zsep
- jz bfil
- cpi '*'
- jz qfil
- mov m,a
- inx h
- dcr b
- rz
- call rech ;read one character
- jmp ffil
-
- ; Block fill
-
- qfil: mvi c,'?'
- jmp kfil
- bfil: mvi c,' '
- kfil: mov m,c
- inx h
- dcr b
- jnz kfil
- ret
-
- ; (L) List the memory as 8080 operation codes. The
- ; command <nLa,b> will list n lines of code between
- ; the hexadecimal addresses a and b, with the interval
- ; taking precedence over the number of lines, unless
- ; either a or b is missing.
-
- optl: call past ;check limit transgression
- jnc error ;<L may have been overwritten>
- lhld rept
- mov a,l
- sta pinc ;paragraph length
- ora h
- jnz opla
- lxi h,NL ;default length
- opla: inx h
- shld rept ;line counter for L
- xra a
- sta pctr ;paragraph counter
- lhld lorg ;origin for L
- call hef ;read <a>
- shld lorg ;origin for L
- mov b,a
- xchg
- lxi h,begn ;bottom DDT = top memory
- call hef ;read <b>
- shld llim ;limit for L
- jc oplc ;c means <b> not null
- mov a,b
- cpi CR
- jz opld
- oplc: lxi h,0000H
- shld rept ;line counter for L
- lda pinc ;paragraph length
- sta pctr ;paragraph counter
-
- ; The parameters have been established, start typing.
-
- opld: call inst ;read console status
- rnz
- lhld rept ;line counter for L
- mov a,l
- ora h
- jnz oplf ;nz means counter working
- lda pctr ;paragraph counter
- ora a
- jz oplg ;z means no paragraphing
- dcr a
- jnz ople
- call crlf
- lda pinc ;paragraph length
- ople: sta pctr ;paragraph counter
- jmp oplg
- oplf: dcx h
- mov a,l
- ora h
- rz
- shld rept ;line counter for L
- oplg: call dubl
- lhld lorg ;origin for L
- call reab
- jnc nox
- mvi a,'X'
- call aout ;A to console
- nox: call tyhl ;type HL as four nibbles
- call dubl
- lhld llim ;upper limit for "L"
- xchg
- lhld lorg ;origin for L
- mov a,e ;cmp(DE,HL)
- sub l
- mov a,d
- sbb h
- rc
- call dism
- shld lorg ;origin for L
- call crlf
- jmp opld
-
- ; (M) Move part of the memory from one place to another.
- ; <Mx,y,z> will move the interval x,y to begin at z. The
- ; direction of movement compensates for possible overlap.
-
- optm: call onar
- mov c,l
- mov b,h
- call onar
- xchg
- call onar
- mov a,e ;cmp(DE,BC)
- sub c
- mov a,d
- sbb b
- jc error ;<interval inverted>
- mov a,e ;cmp(DE,HL)
- sub l
- mov a,d
- sbb h
- jc opmb
- mov a,c ;cmp(BC,HL)
- sub l
- mov a,b
- sbb h
- jnc opmb
- mov a,e ;BC=DE-BC
- sub c
- mov c,a
- mov a,d
- sbb b
- mov b,a
- dad b ;HL=HL+(DE-BC)
- opma: mov a,c
- ora b
- rz
- ldax d
- mov m,a
- dcx h
- dcx d
- dcx b
- jmp opma
- opmb: mov a,e ;cmp(DE,BC)
- sub c
- mov a,d
- sbb b
- rc
- ldax b
- mov m,a
- inx b
- inx h
- jmp opmb
-
- ; (R) Read into memory the file specified by TFCB.
- ; It was probably defined by a preceding I command,
- ; but might still be the program defined in the DDT
- ; command line. <Rx> will start loading at TORG+x.
-
- optr: call hexf ;with zero default
- opra: push h
- call openf ;open file
- cpi 0FFH
- jz error ;<failure to open file>
- call chex ;check for .HEX
- jz ihex ;load INTEL HEX file
- pop h
- lxi d,TORG ;CP/M transient origin
- dad d
- shld savpc ;PC at breakpoint
- oprb: push h
- lxi d,TFCB ;CP/M default FCB
- mvi c,20 ;(14) read one record
- call XDOS ;DDT analogue of 0005
- pop h
- ora a
- jnz efil ;EOF
- lxi d,TBUF ;CP/M default FCB
- mvi c,80H ;size of one record
- oprc: ldax d
- inx d
- mov m,a
- inx h
- dcr c
- jnz oprc ;move to memory
- call rmax ;record upper limit
- jmp oprb ;read another record
-
- ; Test whether HL beyond previous maximum.
-
- tmax: xchg
- lhld pmax ;program high limit
- mov a,l ;cmp(HL,DE)
- sub e
- mov a,h
- sbb d
- xchg
- ret
-
- ; Record maximum program length.
-
- rmax: call tmax
- rnc
- shld pmax ;program high limit
- ret
-
- ; Test for limit transgression.
-
- past: push h
- lxi h,begn ;lower DDT limit
- call tmax
- pop h
- ret
-
- ; Check for the extension 'HEX'
-
- chex: lxi h,TFCB+9 ;extension
- mov a,m
- ani 07FH
- cpi 'H'
- rnz
- inx h
- mov a,m
- ani 07FH
- cpi 'E'
- rnz
- inx h
- mov a,m
- ani 07FH
- cpi 'X'
- ret
-
- ; Load INTEL HEX file, whose records have the form:
- ; :NNAAAA00DDDDDDDDDD....DDXX
- ; : start of line
- ; NN number of bytes in line
- ; AAAA first address of line
- ; 00 class of line (zero in CP/M)
- ; DD byte of data - NNH altogether
- ; XX checksum - full bytesum w/XX = 00
- ; :00AAAA - end of file, start address AAAA.
-
- ihex: call renb ;next byte from CP/M buffer
- cpi 01AH ;^Z
- jz error ;<no EOF in legal text>
- sbi ':' ;line begins with colon
- jnz ihex ;load INTEL HEX file
- mov d,a ;start checksum w/zero
- pop h
- push h
- call nbyt ;next byte w/checksum
- mov e,a
- call nbyt ;next byte w/checksum
- push psw
- call nbyt ;next byte w/checksum
- pop b
- mov c,a
- dad b
- mov a,e
- ora a
- jnz ihxx ;read non-null line
- mov h,b
- mov l,c
- shld savpc ;PC at breakpoint
- pop h ;displacement not added to AAAA <<---
- jmp efil ;EOF
-
- ihxx: call nbyt ;next byte w/checksum
- hlin: call nbyt ;next byte w/checksum
- mov m,a
- inx h
- dcr e
- jnz hlin ;read the full line
- call nbyt ;next byte w/checksum
- push psw
- call rmax ;record upper limit
- pop psw
- jnz error ;<checksum failed>
- jmp ihex ;load INTEL HEX file
-
- ; Form next byte, add to checksum
-
- nbyt: push b
- push h
- push d
- call renb ;next byte from CP/M buffer
- call cnh
- jc error ;<not hex digit>
- add a
- add a
- add a
- add a
- push psw
- call renb ;next byte from CP/M buffer
- call cnh
- jc error ;<not hex digit>
- pop b
- ora b
- mov b,a
- pop d
- add d
- mov d,a
- mov a,b
- pop h
- pop b
- ret
-
- ; EOF after reading file
-
- efil: mvi c,12 ;(0C) lift disk head
- call XDOS ;DDT analogue of 0005
- lxi h,rmsg ;header: 'NEXT PC'
- call mssg
- call crlf ;type CR,LF
- lhld pmax ;program high limit
- call tyhl ;type HL as four nibbles
- call sngl ;type space
- lhld savpc ;PC at breakpoint
- shld dorg ;origin for D
- shld lorg ;origin for L
- jmp tyhl ;type HL as four nibbles
-
- rmsg: db CR,LF,'NEXT PC',00
-
- ; (S) Store hexadecimal bytes. <nSx> will store
- ; n bytes starting at address x, read one by one
- ; from the console. Missing n means indefinite
- ; repetition, missing x means TORG. Confirmation
- ; and progression is automatic while hexadecimal
- ; bytes are being received; however, for
- ; - go back one byte,
- ; 'x deposit ASCII x,
- ; ^x deposit ctl x,
- ; CR go on to next byte.
- ; Any other input terminates the cycle.
-
- opts: lxi h,TORG
- call hef ;read hex field
- xchg
- opsa: call crlf ;type CR,LF
- call typs ;verify the line
- call incl ;fetch a command line
- jz opsc ;null buffer, go next line
- call hxar ;read one-byte arg
- jz opsb ;<standard field>
- cpi '-' ;go back
- rnz ;leave the cycle
- dcx d
- jmp opsa
- opsb: stax d
- call ctlx
- call typs ;verify the line
- opsc: inx d
- call drnz
- jnz opsa
- ret
-
- ; Type the format line for S.
-
- typs: ldax d
- call prip ;type printable or .
- call sngl
- call word ;type DE as four nibbles
- call sngl ;type space
- ldax d
- call byte ;type A as two nibbles
- jmp sngl ;type space
-
- ; (T) Type the register status line while single-stepping
- ; through the program. <nT> runs through n steps typing
- ; each one, while <nT/> executes without typing. The option
- ; V, with the same alternatives <nV> and <nV/> treats a
- ; call or a conditional call as a single step, avoiding a
- ; detailled examination of the interior contents of each
- ; subroutine.
-
-
- optt: xra a
- oooa: sta swtv ;T/V = z/nz
- mvi a,0FFH
- sta swgt ;G/T = z/nz
- call reuc
- cpi '/'
- jnz ooob
- xra a
- ooob: sta swtu ;T/U = nz/z
- lhld rept
- mov a,l
- ora h
- jz oooc
- dcx h
- oooc: shld rept ;repetition counter
- call line ;type display line
- jmp gnex
-
- ; (V) A variant of T.
-
- optv: mvi a,0FFH
- jmp oooa
-
- ; (X) Examine registers. Any one of the registers or
- ; register pairs A, BC, HL, DE, SP, PC may be examined,
- ; or one of the five flag bits C, Z, M, E, I, by typing
- ; Xr, with r = czmeiabhdsp*, or =xxxx with a hexadecimal
- ; address xxxx. The latter defines the register * at
- ; first. A display line is typed, of the form
- ; r=xxxx xx ... xx ... xx +++++ + +++++ ooo ooooo
- ; where xxxx is the contents of register r, xx etc is
- ; a window of hexadecimal bytes centered on xxxx, ++ etc
- ; is a similar window of ASCII characters, and finally
- ; ooo ooooo is the instruction, if meaningful, at xxxx.
- ;
- ; Once an examination is underway, the window may be
- ; moved by various operators:
- ; * indirect from window
- ; ^ indirect from instruction address
- ; excl save value
- ; ? recover value
- ; / next instruction
- ; + 1 byte forward
- ; - 1 byte backward
- ; # forward, stop at nonzero
- ; @ backward, stop at nonzero
- ; =xx search for byte xx ('x or ^x also)
- ; |xxxx search for pair xxxx
- ; > forward half-window
- ; < backward half-window
- ; . type crlf - make new line
-
- optx: call relc ;char to A from buffer
- cpi CR
- jz ljne ;type display line
- cpi '='
- jnz opxa
- call hexf
- shld savmr ;save memory reference
- mvi a,'*'
- opxa: lxi b,NR ;B=0, C=# registers
- lxi h,regs ;register list
- opxb: cmp m
- jz opxc ;modify given register
- inx h
- inr b
- dcr c
- jnz opxb ;repeat for all
- jmp error ;<no such register>
-
- opxc: push h
- mov a,b
- call gesr ;fetch saved register
- shld savxx ;?/! cell
- call reuc ;char to A from buffer
- cpi CR
- jnz error ;<null field>
- push b
- opxd: pop b
- pop h
- push h
- push b
- call ctlx ;type ^X
- call tyfr ;type flag or register
- call sngl ;type space
- call incl ;fetch a command line
- call hexf
- pop b
- jnc opxg ;nc means null hex field
- push b
- opxe: mov a,b
- cpi 05
- jnc uacc ;update register
- mov a,h
- ora a
- jnz error ;<only one byte admitted>
- mov a,l
- cpi 02
- jnc error ;<only 1 bit (0,1) allowed>
- call fmaf ;fetch mask & flags
- mov h,a
- mov b,c
- mvi a,0FEH ;-2
- call shla ;shl(A,B)
- ana h
- mov b,c
- mov h,a
- mov a,l
- call shla ;shl(A,B)
- ora h
- stax d
- jmp opxd
-
- ; Window modifiers are possible with a null hex field.
-
- opxg: push psw
- mov a,b
- call gesr ;fetch saved register
- pop psw
- cpi CR
- jnz opxh
- shld dorg
- shld lorg
- pop h
- ret
- opxh: push b
- lxi d,opxe
- push d
- call alta
- db 14
- db '*' ;indirect address from window
- dw opxv
- db '^' ;indirect address from instruction
- dw opxu
- db '!' ;save address
- dw opxw
- db '?' ;restore address
- dw opxx
- db '/' ;next instruction
- dw opxy
- db '+' ;advance 1 byte
- dw opxz
- db '-' ;return 1 byte
- dw opxt
- db '#' ;advance to nonzero byte
- dw opxs
- db '.' ;type crlf
- dw crlf
- db '=' ;=x: search for xx, 'x, ^x
- dw opxr
- db '|' ;|xxxx: search for pair xxxx
- dw opxm
- db '>' ;advance halfwindow
- dw opxp
- db '<' ;return halfwindow
- dw opxo
- db '@' ;return to nonzero
- dw opxn
-
- opxu: inx h ;^
- opxv: mov e,m ;*
- inx h
- mov d,m
- xchg
- ret
-
- opxw: shld savxx ;excl
- ret
-
- opxx: lhld savxx ;?
- ret
-
- opxy: mov a,m ;/
- inx h
- inx h
- inx h
- call twob
- rc
- dcx h
- call oneb
- rc
- opxt: dcx h ;- (beware - it's part of opxy)
- ret
-
- opxz: inx h ;+
- ret
-
- opxs: xra a ;#
- oxs: inx h
- cmp m
- jz oxs
- ret
-
- opxr: xchg ;=
- lhld rept
- call hxr ;hex argument w/default
- shld rept ;be sure to find it again
- mov a,l
- xchg
- oxr: inx h
- cmp m
- jnz oxr
- ret
-
- opxp: lxi d,WW+1 ;>
- dad d
- ret
-
- opxo: lxi d,-WW-1 ;<
- dad d
- ret
-
- opxn: xra a ;@
- oxn: dcx h
- cmp m
- jz oxn
- ret
-
- opxm: xchg ;|
- lhld rept
- call hef
- shld rept ;be sure we'll find the pair
- xchg
- inx h
- oxm: mov a,e
- call oxr
- inx h
- mov a,d
- cmp m
- dcx h
- jnz oxm
- dcx h
- ret
-
- ; shl(A,B)
-
- shla: dcr b
- rz
- rlc
- jmp shla ;shl(A,B)
-
- ; Decrement REPT if it is non-zero.
-
- drnz: push h
- lhld rept
- mov a,h
- ora l
- sui 1
- sbb a
- jnz dnz
- dcx h
- shld rept
- mov a,h
- ora l
- dnz: pop h
- ret
-
- ; Update register
-
- uacc: jnz ureg
- mov a,h
- ora a
- jnz error ;<only one byte allowed>
- mov a,l
- sta sava ;save A
- jmp opxd
-
- ureg: push h
- call gasr ;get address of saved register
- pop d
- mov m,e
- inx h
- mov m,d
- jmp opxd
-
- ; Open file
-
- openf: push h
- push d
- push b
- xra a
- sta TFCB-1
- sta TFCB+32
- mvi c,15 ;(0F) open file
- lxi d,TFCB ;CP/M default FCB
- call XDOS ;DDT analogue of 0005
- pop b
- pop d
- pop h
- ret
-
- ; Read next byte from CP/M buffer,
- ; replenish when exhausted.
-
- renb: push h
- push d
- push b
- lda TFCB-1
- ani 07FH
- jz ror ;read one record
- rnb: mvi d,00
- mov e,a
- lxi h,TBUF ;CP/M default FCB
- dad d
- mov a,m
- cpi 01AH ;^Z
- jz reen ;end of record
- lxi h,TFCB-1
- inr m
- ora a
- jmp reex ;return
-
- ror: mvi c,20 ;(14) read one record
- lxi d,TFCB ;CP/M default FCB
- call XDOS ;DDT analogue of 0005
- ora a
- jnz reen ;end of record
- sta TFCB-1
- jmp rnb
-
- reen: stc ;end of record
- reex: pop b ;return
- pop d
- pop h
- ret
-
- ; Error
-
- error: mvi a,'?'
- call aout ;A to console
- jmp loop ;clear out the stack
-
- ; Read console status.
-
- inst: push b
- push d
- push h
- mvi c,11 ;(0B) console status
- call XDOS ;DDT analogue of 0005
- ani 01
- pop h
- pop d
- pop b
- ret
-
- ; Fill command line buffer from console. The z flag
- ; on return indicates whether a null line was read.
-
- incl: push h
- push d
- push b
- mvi c,10 ;(0A) read buffer
- lxi d,cbuf ;command buffer
- call XDOS ;DDT analogue of 0005
- lxi h,ctex ;command text
- shld cptr ;pointer to command buffer
- lda clen
- pop b
- pop d
- pop h
- ora a
- ret
-
- ; Read a one-byte argument, which may be hexadecimal,
- ; 'x or ^x. Blatant errors are rejected, but nz at
- ; return means null field not terminated by CR, ', or^.
-
- hxar: lxi h,0000
- hxr: call hef
- jnc har
- mov a,h
- ora a
- jnz error ;<not one byte>
- mov a,l
- ret
- har: cpi ''''
- jnz has
- call rech
- cpi ' '
- jc error ;<quoted ctrl char>
- jmp hat
- has: cpi '^'
- rnz
- call rech
- sui '@'
- jc error ;<number, symbol, &c>
- cpi ' '
- jc hat
- sui ' '
- cpi ' '
- jnc error ;<beyond ASCII range>
- hat: mov l,a
- call rech
- cpi CR
- jnz error ;<not single character>
- mov a,l
- ret
-
- ; Read a hexadecimal field; error if null.
-
- onar: call hexf
- jnc error ;<insufficient arguments>
- ret
-
- ; Type CR,LF.
-
- crlf: mvi a,CR
- call aout ;A to console
- mvi a,LF
- jmp aout ;A to console
-
- ; Type ^X [erase line]
-
- ctlx: mvi a,18H ;^X
- jmp aout ;A to console
-
- ; Type one or two spaces.
-
- dubl: call sngl
- sngl: mvi a,' '
-
- ; A to console
-
- aout: push h
- push d
- push b
- mov e,a
- mvi c,02
- call XDOS ;DDT analogue of 0005
- pop b
- pop d
- pop h
- ret
-
- ; Lower case fold excepting rubout
-
- reuc: call rech ;read one character
- lcfo: cpi 'a'
- rc
- cpi '{'
- rnc
- ani 5FH
- ret
-
- ; Upper case fold
-
- relc: call rech ;read one character
- ucfo: cpi '['
- rnc
- cpi 'A'
- rc
- ori 20H
- ret
-
- ; Fetch a character into A from command line
-
- rech: push h
- lxi h,clen ;command string length
- mov a,m
- ora a
- mvi a,CR ;fake CR from empty buffer
- jz recx
- dcr m
- lhld cptr ;pointer to command buffer
- mov a,m
- inx h
- shld cptr ;pointer to command buffer
- recx: pop h
- ret
-
- ; Type A as two nibbles
-
- word: mov a,d
- call byte
- mov a,e
- byte: push psw
- rar
- rar
- rar
- rar
- call nybl
- pop psw
- nybl: ani 0FH
- adi 90H
- daa
- aci 40H
- daa
- jmp aout ;A to console
-
- ; Type HL as four nibbles
-
- tyhl: xchg
- call word
- xchg
- ret
-
- ; Message terminated by zero to console
-
- mssg: mov a,m
- ora a
- rz
- call aout ;A to console
- inx h
- jmp mssg
-
- ; Print printables, put dot for the rest
-
- prip: cpi RO
- jnc priq
- cpi ' '
- jnc aout ;A to console
- priq: mvi a,'.'
- jmp aout ;A to console
-
- ; Type minus or B, according to sign.
-
- morb: rlc
- push psw
- mvi a,'-'
- jnc morc
- mov a,b
- morc: call aout
- pop psw
- ret
-
- ; Type 5 flags as letter (1) or minus (0).
-
- feql: lda savf
- mvi b,'s'
- call morb
- mvi b,'z'
- call morb
- rlc
- mvi b,'i'
- call morb
- rlc
- mvi b,'p'
- call morb
- rlc
- mvi b,'c'
- call morb
- jmp sngl
-
- ; Type <R=XX x > to display a register.
-
- reql: push psw
- mov a,b
- call aout
- mvi a,'='
- call aout
- pop psw
- push psw
- call byte
- call sngl
- pop psw
- call prip
- jmp sngl
-
- ; Type <P=XXXX > to display a register pair.
-
- peql: mov a,b
- call aout
- mvi a,'='
- call aout
- call tyhl
- jmp sngl
-
- ; Test for separators, which are characters which can
- ; be passed over at the beginning of a field, but which
- ; terminate it when found at the end. The character to
- ; be tested is in the accumulator, where it remains.
-
- sepa: cpi ' '
- rz
- cpi HT
- ret
-
- ; Test for terminators, which mean that a field must
- ; end, even if it is null.
-
- term: cpi ','
- rz
- cpi CR
- ret
-
- ; Test whether the character in the accumulator is a
- ; decimal digit. If so, it is replaced by its binary
- ; value, otherwise remaining unchanged. The carry
- ; flag distinguishes the cases - carry if not decimal.
-
- cnd: cpi '0'
- rc
- cpi ':'
- cmc
- rc
- sui '0'
- ret
-
- ; Read a decimal field, leaving the last four
- ; digits read in HL, with leading zeros for fewer
- ; digits. BC, DE remain unchanged. A null field
- ; is zero. Leading separators are passed by, but
- ; trailing separators terminate. A null field is
- ; marked by the carry flag, which is 0 for a null
- ; field delimited by a terminator, 1 otherwise.
- ; A non-zero default value can be given to a null
- ; field using <call def> rather than <call decf>.
-
- decf: lxi h,0000
- def: call reuc
- call sepa
- jz def
- call cnd
- cmc
- rnc
- lxi h,0000
- push d
- dec: mov e,l
- mov d,h
- dad h
- dad h
- dad d
- dad h
- mov e,a
- mvi d,0
- dad d
- call reuc
- call cnd
- jnc dec
- pop d
- ret
-
- ; Test whether the character in the accumulator is a
- ; hexadecimal digit. If so, it is replaced by its
- ; binary value, otherwise remaining unchanged. The
- ; carry flag distinguishes the cases - carry if not
- ; hexadecimal.
-
- cnh: cpi '0'
- rc
- cpi ':'
- jc cni
- cpi 'A'
- rc
- cpi 'G'
- jnc cnj
- sui 07
- cni: sui '0'
- stc
- cnj: cmc
- ret
-
- ; Read a hexadecimal field, leaving the last four
- ; digits read in HL, with leading zeros for fewer
- ; digits. BC, DE remain unchanged. A null field
- ; is zero. Leading separators are passed by, but
- ; trailing separators terminate. A null field is
- ; marked by the carry flag, which is 0 for a null
- ; field delimited by a terminator, 1 otherwise.
- ; A non-zero default value can be given to a null
- ; field using <call hef> rather than <call hexf>.
-
- hexf: lxi h,0000
- hef: call reuc
- call sepa
- jz hef
- call cnh
- cmc
- rnc
- lxi h,0000
- hex: dad h
- dad h
- dad h
- dad h
- ora l
- mov l,a
- call reuc
- call cnh
- jnc hex
- ret
-
- ; Fetch mask and saved flags
-
- fmaf: push h
- lxi h,fmsk ;flag masks
- mov e,b
- mvi d,00
- dad d
- mov c,m
- lxi h,savf ;save AF
- mov a,m
- xchg
- pop h
- ret
-
- ; Get value of saved flag
-
- fval: call fmaf ;fetch mask & flags
- val: dcr c
- jz vam ;ani a,01
- rar
- jmp val
- vam: ani 01
- ret
-
- ; Get address of saved register
-
- gasr: sui 06
- lxi h,rdsp ;list of displacements
- mov e,a
- mvi d,00
- dad d
- dad d
- mov e,m
- inx h
- mov d,m
- lxi h,savmr ;save memory reference
- dad d
- ret
-
- ; Fetch saved register
-
- gesr: call gasr ;get address of saved register
- mov e,m
- inx h
- mov d,m
- xchg
- ret
-
- ; Type flag or register
-
- tyfr: mov a,b
- cpi 05
- jnc tyra
- mov a,m
- call aout ;A to console
- call fval ;get saved flag
- jmp nybl ;type A as DEC or HEX
-
- tyra: mov b,m
- jnz tyre ;type saved register
- lda sava ;save A
- jmp reql
-
- ; Type register and the memory pointed to in the format:
- ; r=value, window, ASCII window, dism
-
- tyre: call gesr ;get saved register
- call peql
- call sngl
- push h
- lxi d,-WW ;go back window halfwidth
- dad d
- push h
- call tyrg
- call sngl
- pop h
- call tyrj
- call dubl
- pop h
- jmp dism
-
- ; Type 2*WW+1 bytes centered on pointer, as nibble pairs.
-
- tyrg: call tyrh
- call sngl
- mov a,m
- call byte
- call dubl
- inx h
- tyrh: mvi c,WW
- tyri: mov a,m
- call byte
- call sngl
- inx h
- dcr c
- jnz tyri
- ret
-
- ; Then type the same window using ASCII characters or points.
-
- tyrj: call tyrk
- call sngl
- mov a,m
- call prip ;type printable or .
- inx h
- call sngl
- tyrk: mvi c,WW
- ascl: mov a,m
- call prip ;type printable or .
- inx h
- dcr c
- jnz ascl
- ret
-
- ; Type display line.
-
- line: call ljne
- jmp crlf
- ljne: mvi b,'b'
- lhld savbc
- call peql
- mvi b,'d'
- lhld savde
- call peql
- mvi b,'h'
- lhld savhl
- push h
- call peql
- pop h
- mvi b,'m'
- mov a,m
- call reql
- mvi b,'a'
- lda sava
- call reql
- call feql
- mvi b,'s'
- lhld savsp
- call peql
- mvi b,'p'
- lhld savpc
- call peql
- call sngl
- jmp dism
-
- regs: db 'czmeiabdhsp*'
-
- rdsp: dw -10,-12,-4,-6,-2,0
-
- fmsk: db 1,7,8,3,5
-
- ; Jump guided by a table of alternatves. The table
- ; should have the form:
- ; call alta
- ; db n
- ; db 'x'
- ; dw xxxx
- ; The last two lines are to be repeated n times, for
- ; each of which xxxx is the jump address corresponding
- ; to the alternative x. The table is used by jumping
- ; to its heading with the alternative in A. Registers
- ; C, D, and E are lost in the process.
-
- alta: xthl
- mov c,m
- alt: inx h
- cmp m
- inx h
- jnz alu
- mov e,m
- inx h
- mov d,m
- xchg
- xthl
- ret
- alu: dcr c
- inx h
- jnz alt
- jmp error ;<alternative not present>
-
- ; Indexed jump through a table.
-
- juta: pop h
- mov e,a
- mvi d,00
- dad d
- dad d
- mov e,m
- inx h
- mov d,m
- xchg
- pchl
-
- ; Return from breakpoint
-
- rtbk: di
- shld savhl; HL at breakpoint
- pop h
- dcx h
- shld savpc ;PC at breakpoint
- push psw
- lxi h,0002
- dad sp
- pop psw
- lxi sp,savhl ;HL at breakpoint
- push h
- push psw
- push b
- push d
- lhld savpc ;PC at breakpoint
- mov a,m
- cpi 0FFH ;RST 7
- push psw
- push h
- lxi h,bkpt ;breakpoint data
- mov a,m
- mvi m,00
- ora a
- jz rtbb
- dcr a
- jz rtba
- lda brky
- lhld brkq
- mov m,a
- rtba: lda brkx
- lhld brkp
- mov m,a
- rtbb: pop h
- pop psw
- jz rtbc ;if RST 7
- inx h
- shld savpc ;PC at breakpoint
- xchg
- lxi h,GDOS+1 ;BDOS address
- mov c,m
- inx h
- mov b,m
- mov a,e ;cmp(DE,BC)
- sub c
- mov a,d
- sbb b
- jc rtbc ;if RST 7
- lxi h,0000
- shld rept
- lhld sica ;site of call to BDOS
- xchg
- mvi a,02H
- ora a
- stc
- jmp gprg ;G without arguments
-
-
- ; If RST 7 brought us to the breakpoint.
-
- rtbc: NOP
- lhld rept ;repetition counter
- mov a,h
- ora l
- jz rtbd ;we won't continue
- dcx h
- shld rept ;repetition counter
- lda swgt ;G/T = z/nz
- ora a
- jz rtbf
- call inst ;read console status
- jnz rtbd ;we won't continue
- lda swtu ;T/U = nz/z
- ora a
- cnz line ;type display line
- jmp gnex
-
- ; Return to DDT rather than program.
-
- rtbd: mvi a,'*'
- call aout ;A to console
- lhld savpc ;PC at breakpoint
- shld dorg ;origin for D
- call past ;check limit transgression
- jnc rtbe ;can't count on using L
- shld lorg ;origin for L
- rtbe: call tyhl ;type HL as four nibbles
- jmp loop ;DDT loop - cannot be <ret>
-
- rtbf: mov a,l
- ani 01H
- jnz gnex
- lhld gbrl
- mov c,l
- mov b,h
- lhld gbrk
- xchg
- lda gbrn
- ora a
- stc
- jmp gprg ;G without arguments
-
- ; Surround instruction by breakpoints for single-step.
-
- type: lxi d,000DH
- lxi h,mtbl ;table of type codes
- tyqe: mov a,m
- ana b
- inx h
- cmp m
- inx h
- jz tyse
- inr d
- dcr e
- jnz tyqe
- tyse: mov a,d
- ret
-
- step: lhld savpc ;PC at breakpoint
- mov b,m
- inx h
- push h
- call type
- call juta
- dw xjmp ;jump
- dw xcju ;conditional jump
- dw ding ;call
- dw dong ;conditional call
- dw xret ;return
- dw xrst ;restart
- dw xpch ;pchl
- dw xmvi ;immediate move
- dw xmvi ;immediate arithmetic
- dw xlxi ;lxi
- dw xlxi ;lhld
- dw xcrt ;conditional return
- dw xmvi ;in, out
- dw xoth ;others
-
- ding: lda swtv ;T/V = z/nz
- inr a
- jz xlxi ;lxi, lhld
- jmp xjmp ;jump, call
-
- dong: lda swtv ;T/V = z/nz
- inr a
- jz xlxi ;lxi, lhld
- jmp xcju ;cndl jmp, cndl call
-
- ; Jump or call
-
- xjmp: call idos
- jnz xtwo
-
- ; Return
-
- xret: call xrtn
- jmp xtwo
-
- ; qdos - check whether DE = BDOS
- ; idos - check whether (DE) = BDOS
-
- idos: pop b
- pop h
- mov e,m
- inx h
- mov d,m
- inx h
- push h
- push b
- qdos: lda GDOS+1 ;BDOS address
- cmp e
- rnz
- lda GDOS+2 ;BDOS address
- cmp d
- ret
-
- xrtn: lhld savsp ;SP at breakpoint
- mov e,m
- inx h
- mov d,m
- ret
-
- ; Conditional jump or call
-
- xcju: call idos
- jz zdos
- pop b
- push b
- mvi a,02
- jmp xone
-
- zdos: pop d
- push d
- jmp xtwo
-
- ; Restart
-
- xrst: mov a,b
- cpi 0FFH
- jnz xsvn
- xra a
- jmp xzer
-
- xsvn: ani 38H
- mov e,a
- mvi d,00
- jmp xtwo
-
- ; PCHL
-
- xpch: lhld savhl ;HL at breakpoint
- xchg
- call qdos ;does DE = BDOS?
- jnz xtwo
- jmp xret
-
- jtwo: jmp xtwo
-
- ; Other.
-
- xoth: pop d
- push d
- jmp xtwo
-
- ; Conditional return.
-
- xcrt: call xrtn
- pop b
- push b
- mvi a,02
- jmp xone
-
- ; LXI, LHLD
-
- xlxi: pop d
- inx d
- push d
-
- ; Immediate move or arithmetic, in, out.
-
- xmvi: pop d
- inx d
- push d
- xtwo: mvi a,01
- xone: inr a
- stc
- xzer: pop h
- ret
-
- mtbl: db 0FFH,0C3H,0C7H,0C2H ;jump, conditional jump
- db 0FFH,0CDH,0C7H,0C4H ;call, conditional call
- db 0FFH,0C9H,0C7H,0C7H ;return, restart
- db 0FFH,0E9H,0C7H,006H ;pchl, immediate moves
- db 0C7H,0C6H,0CFH,001H ;immediate arithmetc, lxi
- db 0E7H,022H,0C7H,0C0H ;lhlf, conditional return
- db 0F7H,0D3H ;in, out
-
- ; ---------------------------------------------------------
-
- logo: db ' DDT(8080)/ICUAP',CR,LF
- db 'Universidad Autonoma de Puebla',CR,LF
- db ' November 20, 1983',00
- dw 00,00,00,00,00,00,00;can't overwrite logo yet
- savde: dw 0000 ;save DE, tail of DDT stack 1
- savbc: dw 0000 ;save BC 2
- savf: db 00 ;save F 3
- sava: db 00 ;save A 4
- savsp: dw 0000 ;SP at breakpoint 5
- savhl: dw 0000 ;HL at breakpoint 6
- savpc: dw 0000 ;PC at breakpoint 7
- savmr: dw 0000 ;save memory reference 8
- savxx: dw 0000 ;storage for optx 9
- sica: dw 0000 ;site of call to BDOS
- swtv: db 00 ;T/V = z/nz
- swtu: db 00 ;T/U = nz/z
- swgt: db 00 ;G/T = z/nz
- rept: dw 0000 ;counter for commands
- gbrk: dw 0000 ;nG's breakpoint
- gbrl: dw 0000 ;nG's second breakpoint
- gbrn: db 00 ;nG's # of breakpoints
- bkpt: db 00 ;number of breakpoints
- brkp: dw 0000 ;first breakpoint
- brkx: db 00 ;first opcode
- brkq: dw 0000 ;second breakpoint
- brky: db 00 ;second opcode
- pinc: db 00 ;paragraph length
- pctr: db 00 ;paragraph counter
- dorg: dw 0000 ;origin for D
- lorg: dw 0000 ;origin for L
- llim: dw 0000 ;upper limit for "L"
- pmax: dw 0000 ;program high limit
- ldsk: db 00 ;logged disk
- adsk: db 00 ;active disk
- cptr: dw 0000 ;pointer to command buffer
- cbuf: db 80H ;command buffer
- clen: db 00 ;command string length
- ctex: ds 80H ;command text
- enddt: ds 0
-
- ; .dephase
-
- end
-