.bp
.op
.cs 5
.mt 5
.mb 6
.pl 66
.ll 65
.po 10
.hm 2
.fm 2
.ft                                3-%
.he CP/M Operating System Manual                 3.5  Operation Codes
.tc    3.5  Operation Codes
.sh
3.5  Operation Codes
.qs
.pp 5
Assembly-language operation codes form the principal part of 
assembly-language programs and form the operation field of the 
instruction.  In general, ASM accepts all the standard mnemonics 
for the Intel 8080 microcomputer, which are given in detail in the \c
.ul
Intel 8080 Assembly Language Programming Manual.  \c
.qu
Labels are optional on each input line.  The individual operators 
are listed briefly in the following sections for completeness, 
although the Intel manuals should be 
referenced for exact operator details.  In Tables 3-4 through 3-8,
bit values have the following meaning:
.sp 2
.in 5
.ti -2
o e3 represents a 3-bit value in the range 0-7 that can be 
one of the predefined registers A, B, C, D, E, H, L, M, SP, or 
PSW.
.sp
.ti -2
o e8 represents an 8-bit value in the range 0-255.
.sp
.ti -2
o e16 represents a 16-bit value in the range 0-65535.
.in 0
.sp
.pp
These expressions can be formed from an arbitrary combination of 
operands and operators.  In some cases, the operands are 
restricted to particular values within the allowable range, such 
as the PUSH instruction.  These cases are noted as they are 
encountered.
.pp
In the sections that follow, each operation code is listed in its 
most general form, along with a specific example, a short 
explanation, and special restrictions.
.sp 2
.tc         3.5.1  Jumps, Calls, and Returns
.sh
3.5.1  Jumps, Calls, and Returns
.qs
.pp
The Jump, Call, and Return instructions allow several different 
forms that test the condition flags set in the 8080 microcomputer 
CPU.  The forms are shown in Table 3-4.
.sp 2
.ce
.sh
Table 3-4.  Jumps, Calls, and Returns
.ll 63
.sp
.nf
  Form   Bit    Example                  Meaning
        Value

  JMP    e16    JMP L1      Jump unconditionally to label

  JNZ    e16    JNZ L2      Jump on nonzero condition to label

  JZ     e16    JZ 100H     Jump on zero condition to label

  JNC    e16    JNC L1+4    Jump no carry to label

  JC     e16    JC L3       Jump on carry to label

  JPO    e16    JPO $+8     Jump on parity odd to label
.bp
.ll 65
.fi
.ce
.sh
Table 3-4.  (continued)
.ll 63
.sp
.nf
  Form   Bit    Example                  Meaning
        Value

  JPE    e16    JPE L4      Jump on even parity to label

  JP     e16    JP GAMMA    Jump on positive result to label

  JM     e16    JM al       Jump on minus to label


  CALL   e16    CALL S1     Call subroutine unconditionally

  CNZ    e16    CNZ S2      Call subroutine on nonzero
                            condition

  CZ     e16    CZ 100H     Call subroutine on zero condition

  CNC    e16    CNC S1+4    Call subroutine if no carry set

  CC     e16    CC S3       Call subroutine if carry set

  CPO    e16    CPO $+8     Call subroutine if parity odd

  CPE    e16    CPE $4      Call subroutine if parity even

  CP     e16    CP GAMMA    Call subroutine if positive result

  CM     e16    CM b1$c2    Call subroutine if minus flag


  RST    e3     RST 0       Programmed restart, equivalent to
                            CALL 8*e3, except one byte call

  RET                       Return from subroutine

  RNZ                       Return if nonzero flag set

  RZ                        Return if zero flag set

  RNC                       Return if no carry

  RC                        Return if carry flag set

  RPO                       Return if parity is odd

  RPE                       Return if parity is even

  RP                        Return if positive result

  RM                        Return if minus flag is set
.fi
.in 0
.ll 65
.sp 3
.tc         3.5.2  Immediate Operand Instructions
.sh
3.5.2  Immediate Operand Instructions
.qs
.pp 5
Several instructions are available that load single- or double-
precision registers or single-precision memory cells with 
constant values, along with instructions that perform immediate 
arithmetic or logical operations on the accumulator (register A).  
Table 3-5 describes the immediate operand instructions.
.sp 2
.ce
.sh
Table 3-5.  Immediate Operand Instructions
.sp
.ll 60
.in 5
.nf
Form with       Example                Meaning
Bit Values
.fi
.sp
.in 35
.ti -30
MVI e3,e8    MVI B,255        Move immediate data to register A, B, C, D,
E, H, L, or M (memory)
.sp
.ti -30
ADI e8       ADI 1            Add immediate operand to A without carry
.sp
.ti -30
ACI e8       ACI 0FFH         Add immediate operand to A with carry
.sp
.ti -30
SUI e8       SUI L + 3        Subtract from A without borrow (carry)
.sp
.ti -30
SBI e8       SBI L AND 11B    Subtract from A with borrow (carry)
.sp
.ti -30
ANI e8       ANI $ AND 7FH    Logical and A with immediate data
.sp
.ti -30
XRI e8       XRI 1111$0000B   Exclusive or A with immediate data
.sp
.ti -30
ORI e8       ORI L AND 1+1    Logical or A with immediate data
.sp
.ti -30
CPI e8       CPI 'a'          Compare A with immediate data, same
as SUI except register A not changed.
.sp
.ti -30
LXI e3,e16   LXI B,100H       Load extended immediate to register 
pair.  e3 must be equivalent to B, D, H, or SP.
.in 0
.ll 65
.sp 2
.tc         3.5.3  Increment and Decrement Instructions
.sh
3.5.3  Increment and Decrement Instructions
.qs
.pp
The 8080 provides instructions for incrementing or decrementing 
single- and double-precision registers.  The instructions are 
described in Table 3-6.
.sp 2
.ce
.sh
Table 3-6.  Increment and Decrement Instructions
.ll 60
.sp
.in 5
.nf
Form with         Example              Meaning
Bit Value
.fi
.sp
.in 35
.ti -28
INR e3          INR E       Single-precision increment 
register.  e3 produces one of A, B, C, D, E, H, L, M.
.sp
.ti -28
DCR e3          DCR A       Single-precision decrement 
register.  e3 produces one of A, B, C, D, E, H, L, M.
.sp
.ti -28
INX e3          INX SP      Double-precision increment register 
pair.  e3 must be equivalent to B, D, H, or SP.
.sp
.ti -28
DCX e3          DCX B       Double-precision decrement register 
pair.  e3 must be equivalent to B, D, H, or SP.
.in 0
.ll 65
.sp 3
.tc         3.5.4  Data Movement Instructions
.sh
3.5.4  Data Movement Instructions
.qs
.pp
Instructions that move data from memory to the CPU and from CPU to memory are
given in the following table.
.sp 2
.ce
.sh
Table 3-7.  Data Movement Instructions
.ll 60
.in 5
.sp
.nf
Form with      Example                 Meaning
Bit Value
.fi
.sp
.in 35
.ti -30
MOV e3,e3      MOV A,B        Move data to leftmost element from rightmost
element.  e3 produces on of A, B, C, D, E, H, L, or M.  MOV M,M is
disallowed.
.sp
.ti -30
LDAX e3        LDAX B         Load register A from computed address.  e3 must
produce either B or D.
.sp
.ti -30
STAX e3        STAX D         Store register A to computed
address.  e3 must produce either B or D.
.sp
.ti -30
LHLD e16       LHLD L1        Load HL direct from location
e16.  Double-precision load to H and L.
.fi
.bp
.ll 65
.in 0
.ce
.sh
Table 3-7.  (continued)
.ll 60
.in 5
.sp
.nf
Form with      Example                 Meaning
Bit Value
.fi
.sp
.in 35
.ti -30
SHLD e16       SHLD L5+x      Store  HL  direct  to location e16.
Double-precision store from H and L to memory.
.sp
.ti -30
LDA e16        LDA Gamma      Load register A from address e16.
.sp
.ti -30
STA e16        STA X3-5       Store register A into memory
at e16.
.sp
.ti -30
POP e3         POP PSW        Load register pair from stack, set SP.
e3 must produce one of B, D, H, or PSW.
.sp
.ti -30
PUSH e3        PUSH B         Store register pair into stack, set SP.  e3
must produce on of B, D, H, or PSW.
.sp
.ti -30
IN e8          IN 0           Load register A with data from port 
e8.
.sp
.ti -30
OUT e8         OUT 255        Send data from register A to port 
e8.
.sp
.ti -30
XTHL                          Exchange data from top of stack 
with HL.
.sp
.ti -30
PCHL                          Fill program counter with data from 
HL.
.sp
.ti -30
SPHL                          Fill stack pointer with data from 
HL.
.sp
.ti -30
XCHG                          Exchange DE pair with HL pair.
.in 0
.ll 65
.sp 3
.tc         3.5.5  Arithmetic Logic Unit Operations
.sh
3.5.5  Arithmetic Logic Unit Operations
.qs
.pp
Instructions that act upon the single-precision accumulator to 
perform arithmetic and logic operations are given in the 
following table.
.bp
.ce
.sh
Table 3-8.  Arithmetic Logic Unit Operations
.ll 60
.sp
.in 5
.nf
Form with       Example                Meaning
Bit Value
.fi
.sp
.in 35
.ti -29
ADD e3         ADD B         Add register given by e3 to 
accumulator without carry.  e3 must produce one of A, B, C, D, E, 
H, or L.
.sp
.ti -29
ADC e3         ADC L         Add register to A with carry, e3 as 
above.
.sp
.ti -29
SUB e3         SUB H         Subtract reg e3 from A without 
carry, e3 is defined as above.
.sp
.ti -29
SBB e3         SBB 2         Subtract register e3 from A with 
carry, e3 defined as above.
.sp
.ti -29
ANA e3         ANA 1+1       Logical and reg with A, e3 as 
above.
.sp
.ti -29
XRA e3         XRA A         Exclusive or with A, e3 as above.
.sp
.ti -29
ORA e3         ORA B         Logical or with A, e3 defined as 
above.
.sp
.ti -29
CMP e3         CMP H         Compare register with A, e3 as 
above.
.sp
.ti -29
DAA                          Decimal adjust register A based 
upon last arithmetic logic unit operation.
.sp
.ti -29
CMA                          Complement the bits in register A.
.sp
.ti -29
STC                          Set the carry flag to 1.
.sp
.ti -29
CMC                          Complement the carry flag.
.sp
.ti -29
RLC                          Rotate bits left, (re)set carry as a 
side effect.  High-order A bit becomes carry.
.sp
.ti -29
RRC                          Rotate bits right, (re)set carry as 
side effect.  Low-order A bit becomes carry.
.bp
.in 0
.ll 65
.ce
.sh
Table 3-8.  (continued)
.ll 60
.sp
.in 5
.nf
Form with       Example                Meaning
Bit Value
.fi
.sp
.in 35
.ti -29
RAL                          Rotate carry/A register to left.
Carry is involved in the rotate.
.sp
.ti -29
RAR                          Rotate carry/A register to right.  
Carry is involved in the rotate.
.sp
.ti -29
DAD e3         DAD B         Double-precision add register pair 
e3 to HL.  e3 must produce B, D, H, or SP.
.in 0
.ll 65
.sp 2
.tc         3.5.6  Control Instructions
.sh
3.5.6  Control Instructions
.qs
.pp
The four remaining instructions, categorized as control instructions, are
the following:
.sp
.nf
.in 3
o HLT halts the 8080 processor.
o DI disables the interrupt system.
o EI enables the interrupt system.
o NOP means no operation.
.in 0
.fi
.sp 2
.tc    3.6  Error Messages
.he CP/M Operating System Manual                  3.6  Error Messages
.sh
3.6  Error Messages
.qs
.pp
When errors occur within the assembly-language program, they are 
listed as single-character flags in the leftmost position of the 
source listing.  The line in error is also echoed at the console 
so that the source listing need not be examined to determine if 
errors are present.  The error codes are listed in the following 
table.
.sp 2
.ce
.sh
Table 3-9.  Error Codes
.sp
.ll 60
.in 3
.nf
Error Code                       Meaning
.fi
.sp
.in 16
.ti -13
D            Data error:  element in data statement cannot be placed in 
the specified data area.
.sp
.ti -13
E            Expression error:  expression is ill-formed and cannot be 
computed at assembly time.
.sp
.ti -13
L            Label error:  label cannot appear in this context; might be 
duplicate label.
.sp
.ti -13
N            Not implemented:  features that will appear in future ASM 
versions.  For example, macros are recognized, but flagged in this 
version.
.bp
.in 0
.ll 65
.ce
.sh
Table 3-9.  (continued)
.sp
.ll 60
.in 3
.nf
Error Code                       Meaning
.fi
.sp
.in 16
.ti -13
O            Overflow:  expression is too complicated (too many 
pending operators) to be computed and should be simplified.
.sp
.ti -13
P            Phase error:  label does not have the same value on two 
subsequent passes through the program.
.sp
.ti -13
R            Register error:  the value specified as a register is not 
compatible with the operation code.
.sp
.ti -13
S            Syntax error:  statement is not properly formed.
.sp
.ti -13
V            Value error:  operand encountered in expression is 
improperly formed.
.in 0
.ll 65
.sp
.pp
Table 3-10 lists the error messages that are due to terminal error 
conditions.
.sp 2
.ce
.sh
Table 3-10.  Error Messages
.sp
.ll 60
.in 5
.nf
Message       Meaning
.fi
.sp
NO SOURCE FILE PRESENT
.sp
.in 19
The file specified in the ASM command does not exist on disk.
.sp 2
.in 5
NO DIRECTORY SPACE
.sp
.in 19
The disk directory is full; erase files that are not needed and retry.
.sp 2
.in 5
SOURCE FILE NAME ERROR
.sp
.in 19
Improperly formed ASM filename, for example, it is specified with ? fields.
.sp 2
.in 5
SOURCE FILE READ ERROR
.sp
.in 19
Source file cannot be read properly by the assembler; execute a
TYPE to determine the point of error.
.bp
.in 0
.ll 65
.ce
.sh
Table 3-10.  (continued)
.sp
.ll 60
.in 5
.nf
Message       Meaning
.fi
.sp
OUTPUT FILE WRITE ERROR
.sp
.in 19
Output files cannot be written properly; most likely cause is a full
disk, erase and retry.
.sp 2
.in 5
CANNOT CLOSE FILE
.sp
.in 19
Output file cannot be closed; check to see if disk is write protected.
.in 0
.ll 65
.sp 3
.tc    3.7  A Sample Session
.he CP/M Operating System Manual                3.7  A Sample Session
.sh
3.7  A Sample Session
.qs
.pp
The following sample session shows interaction with the assembler and 
debugger in the development of a simple assembly-language 
program.  The arrow represents a carriage return keystroke.
.sp 2
.ll 90
.nf
A>\c
.sh
ASM SORT      \c
.qs
Assemble SORT.ASM
.sp
CP/M ASSEMBLER - VER 1.0
.sp
0015C    Next free address
003H USE FACTOR    Percent of table used 00 to ff (hexadecimal)
END OF ASSEMBLY
.sp
A>\c
.sh
DIR SORT.*
.qs
.sp
SORT  ASM    Source file
SORT  BAK    Back-up from last edit
SORT  PRN    Print file (contains tab characters)
SORT  HEX    Machine code file
.sp
A>\c
.sh
TYPE SORT.PRN
.qs
                    Source line
.sp
            ;       SORT PROGRAM IN CP/M ASSEMBLY LANGUAGE
            ;       START AT THE BEGINNING OF THE TRANSIENT
                    PROGRAM AREA
.sp
Machine code location
0100                ORG               100H
.sp
Generated machine code
0100 214601 SORT:   LXI H,SW  ;ADDRESS SWITCH TOGGLE
0103 3601           MVI M,1   ;SET TO 1 FOR FIRST ITERATION
0105 214701         LXI H,I   ;ADDRESS INDEX
0108 3600           MVI M,0   ;I=0
            ;
            ;       COMPARE I WITH ARRAY SIZE
010A 7E     COMPL:  MOV A,M   ;A REGISTER = I
010B FE09           CPI N-1   ;CY SET IF I<(N-1)
010D D21901         JNC CONT  ;CONTINUE IF I<=(N-2)
            ;
            ;       END OF ONE PASS THROUGH DATA
0110 214601         LXI H,SW  ;CHECK FOR ZERO SWITCHES
0113 7EB7C200001    MOV A, M! ORA A! JNZ SORT ;END OF SORT IF SW=0
            ;
0118 FF             RST 7     ;GO TO THE DEBUGGER INSTEAD OF REB
            ;
            ;       CONTINUE THIS PASS
Truncated   ;       ADDRESSING I, SO LOAD AV(I) INTO REGISTERS
0119
 5F16002148CONT:    MOV E, A! MVI D, 0! LXI H, AV! DAD D! DAD D
0121 4E792346       MOV C, M! MOV A, C! INX H! MOV B, M
            ;       LOW ORDER BYTE IN A AND C, HIGH ORDER BYTE IN B
            ;
            ;       MOV H AND L TO ADDRESS AV(I+1)
0125 23             INX H
            ;
            ;       COMPARE VALUE WITH REGS CONTAINING AV (I)
0126 965778239E     SUB M! MOV D, A! MOV A, B! INX H! SBB M  ;SUBTRACT
            ;
            ;       BORROW SET IF AV(I+1)>AV(I)
012B DA3F01         JC  INCI  ;SKIP IF IN PROPER ORDER
            ;
            ;       CHECK FOR EQUAL VALUES
012E B2CA3F01       ORA D! JZ INCI ;SKIP IF AV(I) = AV(I+1)
0132 56702B5E       MOV D, M! MOV M, B! DCX H! MOV E, M
0136 712B722B73     MOV M, C! DCX H! MOV M, D! DCX H! MOV M, E
            ;
            ;       INCREMENT SWITCH COUNT
013B 21460134       LXI H,SW! INR M
            ;
            ;       INCREMENT I
013F 21470134C3INCI:LXI H,I! INR M! JMP COMP
            ;
            ;       DATA DEFINITION SECTION
0146 00     SW:     DB 0      ;RESERVE SPACE FOR SWITCH COUNT
0147        I:      DS 1      ;SPACE FOR INDEX
0148 050064001EAV:  DW 5, 100, 30, 50, 20, 7, 1000, 300, 100, -32767
000A =      N       EQU($-AV)/2    ;COMPUTE N INSTEAD OF PRE
015C                END
A>\c
.sh
TYPE SORT.HEX     \c
.qs
Equate value

:10010000214601360121470136007EFE09D2190140
:100110002146017EB7C20001FF5F16002148011988    Machine code in
:10012000194E79234623965778239EDA3F01B2CAA7    HEX format
.mb 5
.fm 1

:100130003F0156702B5E712B722B732146013421C7
:07014000470134C30A01006E                      Machine code in
:10014800050064001E00320014000700E8032C01BB    HEX format
:0401580064000180BE
:0000000000
A>\c
.sh
DDT SORT.HEX        \c
.qs
Start debug run
.mb 6
.fm 2

16K DDT VER 1.0
NEXT PC
015C 0000     Default address (no address on END statement)
-XP

P=0000 100    Change PC to 100

-UFFFF    Untrace for 65535 steps
                                           Abort with rubout
C0Z0M0E0I0 A=00 B=0000 D=0000 H=0000 S=0100 P=0100 LXI H,0146*0100
-T10    Trace 10\d16\u steps

C0Z0M0E0I0 A=01 B=0000 D=0000 H=0146 S=0100 P=0100 LXI H, 0146
C0Z0M0E0I0 A=01 B=0000 D=0000 H=0146 S=0100 P=0103 MVI M, 01
C0Z0M0E0I0 A=01 B=0000 D=0000 H=0146 S=0100 P=0105 LXI H, 0147
C0Z0M0E0I0 A=01 B=0000 D=0000 H=0147 S=0100 P=0108 MVI M, 00
C0Z0M0E0I0 A=01 B=0000 D=0000 H=0147 S=0100 P=010A MOV A, M
C0Z0M0E0I0 A=00 B=0000 D=0000 H=0147 S=0100 P=010B CPI 09
C1Z0M1E0I0 A=00 B=0000 D=0000 H=0147 S=0100 P=010D JNC 0119
C1Z0M1E0I0 A=00 B=0000 D=0000 H=0147 S=0100 P=0110 LXI H, 0146
C1Z0M1E0I0 A=00 B=0000 D=0000 H=0146 S=0100 P=0113 MOV A, M
C1Z0M1E0I0 A=01 B=0000 D=0000 H=0146 S=0100 P=0114 ORA A
C0Z0M0E0I0 A=01 B=0000 D=0000 H=0146 S=0100 P=0115 JNZ 0100
C0Z0M0E0I0 A=01 B=0000 D=0000 H=0146 S=0100 P=0100 LXI H, 0146
C0Z0M0E0I0 A=01 B=0000 D=0000 H=0146 S=0100 P=0103 MVI M, 01
C0Z0M0E0I0 A=01 B=0000 D=0000 H=0146 S=0100 P=0105 LXI H, 0147
C0Z0M0E0I0 A=01 B=0000 D=0000 H=0147 S=0100 P=0108 MVI M, 00
C0Z0M0E0I0 A=01 B=0000 D=0000 H=0147 S=0100 P=010A MOV A, M*010B
-A10D                                       Stopped at 10BH

010D JC 119   Change to a jump on carry
0110

-XP

P=010B 100   Reset program counter back to beginning of program

-T10    Trace execution for 10H steps

                                              Altered instruction
C0Z0M0E0I0 A=00 B=0000 D=0000 H=0147 S=0100 P=0100 LXI H,0146
C0Z0M0E0I0 A=00 B=0000 D=0000 H=0146 S=0100 P=0103 MVI M,01
C0Z0M0E0I0 A=00 B=0000 D=0000 H=0146 S=0100 P=0105 LXI H,0147
C0Z0M0E0I0 A=00 B=0000 D=0000 H=0147 S=0100 P=0108 MVI M,00
C0Z0M0E0I0 A=00 B=0000 D=0000 H=0147 S=0100 P=010A MOV A,M
C0Z0M0E0I0 A=00 B=0000 D=0000 H=0147 S=0100 P=010B CPI 09
C1Z0M1E0I0 A=00 B=0000 D=0000 H=0147 S=0100 P=010D JC 0119
C1Z0M1E0I0 A=00 B=0000 D=0000 H=0147 S=0100 P=0119 MOV E,A
C1Z0M1E0I0 A=00 B=0000 D=0000 H=0147 S=0100 P=011A MVI D,00
C1Z0M1E0I0 A=00 B=0000 D=0000 H=0147 S=0100 P=011C LXI H,0148
C1Z0M1E0I0 A=00 B=0000 D=0000 H=0148 S=0100 P=011F DAD D
C0Z0M1E0I0 A=00 B=0000 D=0000 H=0148 S=0100 P=0120 DAD D
C0Z0M1E0I0 A=00 B=0000 D=0000 H=0148 S=0100 P=0121 MOV C,M
C0Z0M1E0I0 A=00 B=0005 D=0000 H=0148 S=0100 P=0122 MOV A,C
C0Z0M1E0I0 A=05 B=0005 D=0000 H=0148 S=0100 P=0123 INX H
C0Z0M1E0I0 A=05 B=0005 D=0000 H=0149 S=0100 P=0124 MOV B,M*0125
-L100                               Automatic breakpoint

 0100   LXI H,0146
 0103   MVI M,01
 0105   LXI H,0147
 0108   MVI M,00
 010A   MOV A,M        List some code
 010B   CPI 09         from 100H
 010D   JC  0119
 0110   LXI H,0146
 0113   MOV A,M
 0114   ORA A
 0115   JNZ 0100
 -L

 0118   RST 07
 0119   MOV E,A        List more
 011A   MVI D,00
 011C   LXI H,0148
-Abort list with rubout
-G,11B    Start program from current PC (0125H)
          and run in real time to 11BH



*0127   Stopped with an external interrupt 7 from front panel
-T4                        (program was looping indefinitely)
      Look at looping program in trace mode

C0Z0M0E0I0 A=38 B=0064 D=0006 H=0156 S=0100 P=0127 MOV D,A
C0Z0M0E0I0 A=38 B=0064 D=3806 H=0156 S=0100 P=0128 MOV A,B
C0Z0M0E0I0 A=00 B=0064 D=3806 H=0156 S=0100 P=0129 INX H
C0Z0M0E0I0 A=00 B=0064 D=3806 H=0157 S=0100 P=012A SBB M*012B
-D148
                        Data are sorted, but program does not stop.
0148 05 00 07 00 14 00 1E 00........
0150 32 00 64 00 64 00 2C 01 E8 03 01 80 00 00 00 00 2.D.D.,........

0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00................

-G0    Return to CP/M

A>\c
.sh
DDT SORT.HEX    \c
.qs
Reload the memory image

16K DDT VER 1.0
NEXT PC
015C 0000
-XP

P=0000 100    Set PC to beginning of program

-L10D   List bad OPCODE

 010D   JNC 0119
 0110   LXI H,0146
-Abort list with rubout
-A10D    Assemble new OPCODE

010D JC 119

0110

-L100   List starting section of program

 0100   LXI H,0146
 0103   MVI M,01
 0105   LXI H,0147
 0108   MVI M,00
-Abort list with rubout
-A103    Change switch initialization to 00

0103 MVI M,0

0105

-^C  Return to CP/M with CTRL-C (G0 works as well)

SAVE 1 SORT.COM     Save 1 page (256 bytes, from 100H to 1ffH) on
                    disk in case there is need to reload later
A>\c
.sh
DDT SORT.COM      \c
.qs
Restart DDT with saved memory image

16K DDT VER 1.0
NEXT PC
0200 0100    COM file always starts with address 100H
-G     Run the program from PC=100H

*0118    Programmed stop (RST 7) encountered
-D148

                              Data properly sorted
0148 05 00 07 00 14 00 1E 00........
0150 32 00 64 00 64 00 2C 01 E8 03 01 80 00 00 00 00 2.D.D.........

0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00................
0170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00................

-G0   Return to CP/M

A>\c
.sh
ED SORT.ASM     \c
.qs
Make changes to original program

*N,0^Z0TT     Find next ,0
     MVI        M,0        ;I = 0

*-   Up one line in text
     LXI            H,I    ;ADDRESS INDEX
.bp
*-   Up another line
     MVI            M,1    ;SET TO 1 FOR FIRST ITERATION

*KT  Kill line and type next line
     LXI            H,I    ;ADDRESS INDEX

*I   Insert new line
     MVI            M,0    ;ZERO SW

*T
     LXI            H,I    ;ADDRESS INDEX

*NJNC^Z0T
    JNC*T
    CONT            ;CONTINUE IF I<=(N-2)

*-2DIC^Z0LT
    JC              CONT   ;CONTINUE IF I<=(N-2)

*E                    Source from disk A
                      HEX to disk A
A>\c
.sh
ASM SORT.AAZ        \c
.qs
Skip PRN file

CP/M ASSEMBLER - VER 1.0

015C    Next address to assemble
003H USE FACTOR
END OF ASSEMBLY

A>\c
.sh
DDT SORT.HEX        \c
.qs
Test program changes

16K DDT VER 1.0
NEXT PC
015C 0000
-G100

*0118
-D148
                          Data sorted
0148 05 00 07 00 14 00 1E 00........
0150 32 00 64 00 64 00 2C 01 E8 03 01 80 00 00 00 00 2.D.D..........
0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00................

-Abort with rubout

-G0    Return to CP/M--program checks OK.
.in 0
.ll 65
.sp 2
.ce
End of Section 3
.nx foura
