home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol004
/
macros.lib
< prev
next >
Wrap
Text File
|
1984-04-29
|
15KB
|
797 lines
;FILE MACROS.LIB
;
; . . . . . . . . . . . . . . . . . . . . . . . . .
;
; ADDHA MACRO ADD A TO HL
;
ADDHA MACRO
ADD L ;;ADD LOW ORDER BYTE.
MOV L,A
MOV A,H ;;OVERFLOW TO HIGH ORDER BYTE.
ACI 0
MOV H,A
ENDM
;
;
; . . . . . . . . . . . . . . . . . . . . . . . . .
;
; DCMP MACRO COMPARE DE TO HL
;
DCMP MACRO
MOV A,H ;;HIGH ORDER BYTE
CMP D
JNZ $+5
MOV A,L ;;LOW ORDER BYTE
CMP E
ENDM
;
;
; . . . . . . . . . . . . . . . . . . . . . . . . .
;
; DSUB MACRO SUBTRACT DE FROM HL
;
DSUB MACRO
MOV A,L ;;LOW ORDER BYTE
SUB E
MOV L,A
MOV A,H ;;HIGH ORDER BYTE
SUB D
MOV H,A
ENDM
;
;
; . . . . . . . . . . . . . . . . . . . . . . . . .
;
; INDEX MACRO INDEX AN ADDRESS BY AMT
;
INDEX MACRO ADDR,AMT
IF NUL AMT
LHLD ADDR
INX HL
SHLD ADDR
ELSE
LHLD ADDR
PUSH DE
LXI DE,AMT
DAD DE
POP DE
SHLD ADDR
ENDIF
ENDM
;
;
; . . . . . . . . . . . . . . . . . . . . . . . . .
;
; BUMP MACRO BUMP A BYTE COUNTER
;
BUMP MACRO BYTE,AMT
IF NUL AMT
LDA BYTE ;;BUMP BY ONE.
INR A
STA BYTE
ELSE
LDA BYTE ;;BUMP BY AMT.
ADI AMT
STA BYTE
ENDIF
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . .
;
; CPM MACRO CP/M REQUEST CALLS
;
; CPM FUNC,ADDR,TYPE
;
; CPM FUNC,ADDR (CALL BDOS WITH DE>=ADDR)
; CPM FUNC,,?? (CALL BDOS WITH E=A)
; CPM FUNC (CALL BDOS FUNC)
;
CPM MACRO FUNC,ADDR,TYPE
PUSH HL ;;SAVE REGS.
IF NOT NUL ADDR
LXI D,ADDR ;;POINT TO FCB, ETC.
ENDIF
IF NOT NUL TYPE
IRPC ?Y,TYPE
TDIG? SET '&?Y'-'?'
EXITM
ENDM
IF TDIG? = 0 ;;IF ?? THEN,
MOV E,A ;; MOV E,A.
ELSE
LSR E,TYPE ;;PUT VALUE IN E.
ENDIF
MVI D,0
ENDIF
MVI C,FUNC ;;INDICATE FUNCTION.
CALL BDOS ;;REQUEST THE FUNCTION FROM CP/M.
POP HL ;;RESTORE REGS.
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; LSR MACRO LOAD SINGLE REGISTER
;
;
; REG IS A,B,C,D,E,H,L WHICH IS THE REGISTER TO
; BE LOADED.
; VAL IS A NUMERIC VALUE OR A LABEL. IF IT IS
; A NUMERIC VALUE, IT MUST BE 0-255. IF IT IS
; A LABEL, IT WILL BE LOADED FROM UNLESS THE
; FIRST CHARACTER IS @. THE @ SIGN CAUSES THE
; VALUE TO BE LOADED AS AN IMMEDIATE (IE - FOR
; LENGTHS OF FIELDS).
;
; LSR A,10 (MVI A,10)
; LSR A,BBD (LDA BBD)
; LSR C,BBD (LDA BBD : MOV C,A)
; LSR C,@LEN (MVI A,@LEN : MOV C,A)
;
LSR MACRO REG,VAL
IF NUL REG
ERROR REG OPERAND MUST BE GIVEN!
EXITM
ENDIF
IF NOT NUL VAL
IRPC ?Y,VAL
TDIG? SET '&?Y'-'0'
EXITM
ENDM
IF TDIG? <= 16 ;;0-9 AND ? @
MVI A,VAL ;;PUT CONSTANT IN A.
ELSE
LDA VAL ;;PUT VALUE IN A.
ENDIF
TDIG? SET '®'-'A'
IF TDIG? = 0
EXITM
ELSE
MOV REG,A ;;PUT VALUE IN REG.
ENDIF
ENDM
;
;
; . . . . . . . . . . . . . . . . . . .. . . . . . . . . . .
;
; SAVE MACRO SAVE SPECIFIED REGISTERS
;
; SAVE R1,R2,R3,R4
;
; R1-R4 MAY BE B,D,H OR PSW SAVED IN ORDER SPECIFIED
; IF REGS ARE OMITTED SAVE B,D AND H
;
SAVE MACRO R1,R2,R3,R4
IF NOT NUL R1&R2&R3&R4
IRP R,<<R1>,<R2>,<R3>,<R4>>
IF NUL R
EXITM
ENDIF
PUSH R
ENDM
ELSE
IRPC REG,BDH
PUSH REG
ENDM
ENDIF
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; RESTORE MACRO RESTORE REGISTERS (INVERSE OF SAVE)
;
; RESTORE R1,R2,R3,R4
;
; R1-R4 MAY BE B,D,H OR PSW RESTORED IN ORDER SPECIFIED
; IF REGS OMITTED RESTORE H,D AND B
;
RESTORE MACRO R1,R2,R3,R4
IF NOT NUL R1&R2&R3&R4
IRP R,<<R1>,<R2>,<R3>,<R4>>
IF NUL R
EXITM
ENDIF
POP R
ENDM
ELSE
IRPC REG,HDB
POP REG
ENDM
ENDIF
ENDM
;
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; INPUT MACRO INPUT CHARACTER STRING FROM CONSOLE
;
; INPUT ADDR,BUFLEN
;
; ADDR START OF TEXT BUFFER
; BUFLEN LENGTH OF BUFFER (DEFAULT IS 127)
;
INPUT MACRO ?STRING,ADDR,BUFLEN
;;
IF NOT NUL ?STRING
PRINT ?STRING ;;PRINT STRING.
ENDIF
IF NOT NUL ADDR
LXI D,ADDR ;;SET BUFFER ADDRESS
ENDIF
IF NOT NUL BUFLEN
MVI A,BUFLEN ;;SET BUFFER LENGTH
STAX D
ELSE
MVI A,127
STAX D ;;SET BUFFER DEFAULT MAXIMUM
ENDIF
CPM CRB ;;ISSUE READ BUFFER.
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; PRINT MACRO PRINT A STRING ON CONSOLE
;
; PRINT (CARRIAGE RETURN, LINE FEED)
; PRINT 'LITERAL'
; PRINT <'LITERAL',CR,LF,'SECOND LITERAL'>
;
; PRINT ADDR,$ (ASCII OUTPUT UNTIL $)
; PRINT ADDR,L,H (HEX OUTPUT L CHARACTERS)
; PRINT ADDR,L,A (ASCII OUTPUT L CHARACTERS)
;
; LITERALS MUST BE IN SINGLE QUOTES 'LIT'
; IF LITERAL CONTAINS CONTROL CODES ENTIRE STRING IN <> BRACKETS
; MACRO ALSO ASSEMBLES
; CR = CARRIAGE RETURN
; LF = LINE FEED
; BEL = BELL CODE
;
; MACRO ASSUMES ADDR ALREADY LOADED TO HL IF ARGUMENT OMITTED
;
PRINT MACRO ?STRING,LEN,TC
LOCAL @OVER,@MESS,PLOOP,PASTCR,@CRLF
CR SET 0DH
LF SET 0AH
BEL SET 07H
IF NUL ?STRING&LEN&TC
JMP PASTCR
@CRLF: DB CR
DB LF
DB '$'
PASTCR:
CPM CPB,@CRLF ;;ISSUE CR,LF.
ELSE
IF NUL LEN&TC
JMP @OVER
@MESS: DB ?STRING
DB '$'
@OVER:
CPM CPB,@MESS ;;ISSUE MSG.
ELSE
IF NUL TC
CPM CPB,?STRING ;;ISSUE MSG.
ELSE
IF NOT NUL ?STRING
LXI H,?STRING ;;POINTER TO STRING
ENDIF
MVI C,LEN ;;LENGTH OF STRING
PLOOP: PUSH B
PUSH H
IF TC=H
MOV A,M ;;GET A BYTE
HEXOUT ;;CONV TO HEX & OUTPUT
ELSE
MOV E,M ;;OUTPUT A BYTE.
CPM CWRITE
ENDIF
POP H
POP B
INX H
DCR C ;;DECR LENGTH
JNZ PLOOP ;;CONTINUE TILL LEN 0
ENDIF
ENDIF
ENDIF
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; HEXOUT MACRO CONVERT BINARY NO AND OUTPUT TO CONSOLE
;
; HEXOUT ADDR
;
; NUMBER ASSUMED IN A IF NO ARGUMENT
;
HEXOUT MACRO ADDR
LOCAL OUTCHR,HEXEND
JMP HEXEND
HEXPRN: SAVE PSW
RRC
RRC
RRC
RRC ;;SHIFT RIGHT 4
CALL OUTCHR
RESTORE PSW
OUTCHR: ANI 0FH ;;MASK 4 BITS
ADI 90H ;;ADD OFFSET
DAA ;;DEC ADJUST
ACI 40H ;;ADD OFFSET
DAA ;;DEC ADJUST
CPM CWRITE,,A ;;OUTPUT (A) TO CONSOLE.
RET
HEXEND:
HEXOUT MACRO ?ADDR
IF NOT NUL ?ADDR
LDA ?ADDR
ENDIF
CALL HEXPRN
ENDM
HEXOUT ADDR
ENDM
;
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; DECIN MACRO CONVERT A NUMBER IN MEMORY FROM ASCII TO BINARY
;
; DECIN ADDR
;
; INPUT:
; ADDR (HL) <= INPUT TEXT
; LEN (C) = LENGTH OF TEXT
; OUTPUT:
; HL <= INPUT TEXT + LEN + 1
; C = 0
; CY:ON = ERROR
;
;
DECIN MACRO ADDR,LEN
LOCAL DLOOP,OVERSUB
JMP OVERSUB
@DECIN: LXI D,0 ;;ZERO DE
XCHG ;;ADDR POINTER TO DE, ZERO TO HL
DLOOP: LDAX D ;;GET A ASCII DIGIT
SUI '0' ;;CONVERT TO BCD AND TEST
RC ;;CONVERSION ERROR
CPI 10 ;;CHECK LEGITIMATE DIGIT (0-9)
CMC ;;COMPLEMENT CARRY
RC ;;RET WITH CARRY SET IF ERROR
INX D ;;INCR ADDR POINTER
PUSH DE ;;SAVE DE.
DAD HL ;;2*HL
MOV D,H ;;DE = HL
MOV E,L
DAD HL ;;4*HL
DAD HL ;;8*HL
DAD DE ;;10*HL
POP DE ;;RESTORE DE.
ADD L ;;ADD A TO HL.
MOV L,A
MOV A,H
ACI 0
MOV H,A
DCR C ;;DECR CNT.
JNZ DLOOP ;;BACK FOR ANOTHER DIGIT
XCHG ;;DE=NUMBER, HL<=TEXT
RET
OVERSUB:
DECIN MACRO ?ADDR,?LEN
IF NOT NUL ?ADDR
LXI H,?ADDR
ENDIF
IF NOT NUL ?LEN
LSR C,?LEN ;;PUT LENGTH IN C.
ENDIF
CALL @DECIN ;;CALL THE SUBROUTINE
MOV A,E ;;LEAST SIGNIFICANT HALF OF NO TO A
ENDM
DECIN ADDR,LEN
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; BAU8 MACRO CONVERT A NUMBER FROM BINARY TO ASCII (8 BIT)
;
; BAU8 ADDR
; BAU8 ,NUMBER
; BAU8 ADDR,NUMBER
;
; INPUT:
; ADDR (HL) <= 3-BYTE OUTPUT AREA
; NUMBER (A) = BINARY NUMBER
; OUTPUT:
; HL <= 3-BYTE OUTPUT AREA
; A = BINARY NUMBER
;
;
BAU8 MACRO ADDR,NUMBER
LOCAL DVU8,OVERSUB
JMP OVERSUB
@BAU8: DS 0
SAVE
MVI C,100 ;;GET HUNDREDS.
CALL DVU8
MVI C,10 ;;GET TENS.
CALL DVU8
MVI C,1 ;;GET ONES.
CALL DVU8
RESTORE
RET
;
DVU8: MVI B,0
SUB C
INR B
JNC DVU8+2 ;;LOOP UNTIL WE GO NEGATIVE.
ADD C
DCR B
MOV C,A ;;SAVE REMAINDER.
MOV A,B ;;OUTPUT DIVIDEND.
ADI '0'
MOV M,A
INX HL
MOV A,C ;;RESTORE REMAINDER.
RET
OVERSUB:
BAU8 MACRO ?ADDR,?NUM
IF NOT NUL ?NUM
LDA ?NUM
ENDIF
IF NOT NUL ?ADDR
LXI H,?ADDR
ENDIF
CALL @BAU8 ;;CALL THE SUBROUTINE
ENDM
BAU8 ADDR,NUMBER
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; FILL MACRO - FILL A BLOCK OF MEMORY WITH A CONSTANT
;
; FILL START,BLKLEN,CONSTANT
;
; CONSTANT OMITTED, FILL WITH 0
; BLKLEN OMITTED, FILL ONE BYTE
;
FILL MACRO START,BLKLEN,CONST
LOCAL @FILL
IF NOT NUL START
LXI H,START ;;LOAD START ADDR
ENDIF
IF NOT NUL BLKLEN
IF BLKLEN > 255
LXI B,BLKLEN ;;LOAD BLOCK LENGTH
ELSE
MVI C,BLKLEN
ENDIF
IF NOT NUL CONST
MVI E,CONST ;;LOAD CONST IF NOT NULL
ELSE
MVI E,0
ENDIF
@FILL: MOV M,E ;;STORE A BYTE
INX H ;;INCR MEMORY POINTER
IF BLKLEN > 255
DCX B ;;DECR COUNT
MOV A,C ;;TEST LIMIT
ORA B
JNZ @FILL ;;CONTINUE
ELSE
DCR C
JNZ @FILL
ENDIF
ELSE
IF NUL CONST
MVI M,0 ;;STORE A ZERO
ELSE
MVI M,CONST ;;STORE SINGLE BYTE
ENDIF
ENDIF
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; CALLBIOS MACRO CALL BIOS ROUTINES DIRECTLY
;
; CALLBIOS FUNCTION,PARAM
;
CALLBIOS MACRO FUNCT,PARAM
LOCAL @CALL
;
DCOLD SET 00H
DWBOOT SET 03H
DSTAT SET 06H
DCONIN SET 09H
DCONOUT SET 0CH ;;CHAR IN C
DLIST SET 0FH ;;CHAR IN C
DPUNCH SET 12H
DREADER SET 15H
DHOME SET 18H
DSELDSK SET 1BH
DSETTRK SET 1EH
DSETSEC SET 21H ;;SECTOR NO IN C
DSETDMA SET 24H ;;DMA ADDR IN BC
DREAD SET 27H
DWRITE SET 2AH
;
?F SET FUNCT
PUSH HL ;;SAVE REGS.
IF NOT NUL PARAM
MVI C,PARAM
ENDIF
LXI HL,@CALL ;;GET RETURN POINTER.
PUSH HL
LHLD 1 ;;ADDR OF BIOS
PUSH B
LXI B,-3
DAD B
MVI B,0
MVI C,?F
DAD B
POP B
PUSH HL ;;SAVE ADR.
RET ;;GOTO IT.
@CALL: DS 0
POP HL
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; SETTRK MACRO SET AND TEST TRACK NUMBER
;
; CARRY SET IF > 76
;
SETTRK MACRO TRKNO
LOCAL ENDTRK
IF NOT NUL TRKNO
LDA TRKNO
ENDIF
CPI 77
CMC
JC ENDTRK
PUSH BC
MOV C,A ;;TRACK NO TO C
CALLBIOS DSETTRK
POP BC
ENDTRK: ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; SETSEC MACRO SET AND TEST SECTOR NUMBER
;
; RETURN WITH CARRY SET < 1 OR > 26
;
SETSEC MACRO SECNO
LOCAL ENDSEC
IF NOT NUL SECNO
LDA SECNO
ENDIF
ORA A ;CHECK ZERO
STC
JZ ENDSEC
CPI 27 ;CHECK > 26
CMC
JC ENDSEC
PUSH BC
MOV C,A ;MOVE TO C
CALLBIOS DSETSEC
POP BC
ENDSEC: ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; SELDSK MACRO SET AND TEST DISK NUMBER
;
; RETURN WITH CARRY SET > 3
;
SELDSK MACRO SELNO
LOCAL ENDSEL
IF NOT NUL SELNO
LDA SELNO
ENDIF
CPI 3+1 ;CHECK > 3
CMC
JC ENDSEL
PUSH BC
MOV C,A ;MOVE TO C
CALLBIOS DSELDSK
POP BC
ENDSEL: ENDM
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;
; CLC MACRO COMPARE 2 STRINGS OF SAME LENGTH SET CARRY IF EQUAL
;
; CLC STR1,'LITERAL STRING'
; CLC STR1,STR2,LENGTH
; CLC
;
; DE POINTS TO STR1 MACRO WILL LOAD REG IF ARG
; HL POINTS TO STR2 PRESENT
; C CONTAINS LENGTH
;
; SUBTRACT STR2 FROM STR1 AND SET FLAGS, ZERO INDICATES EQUAL.
; NORMALLY THE SECOND ARG IS A LITERAL STRING AND THE LENGTH
; IS OMITTED. IF THE LEN ARG IS PRESENT THE SECOND STRING
; ARG IS ASSUMED TO BE A MEMORY ADDR. IF ALL ARGUMENTS OMITTED
; REGISTERS ASSUMED ALREADY LOADED.
;
CLC MACRO STR1,STR2,LEN
LOCAL OVERSUB,M1
JMP OVERSUB
@CLC: INR C ;;PRE INCREMENT COUNT (IT MIGHT BE ZERO)
M1: DCR C ;;DECR LENGTH COUNT
RZ ;;RETURN IF CLC FOUND
LDAX D ;;GET A BYTE FROM ONE STRING
SUB M ;;COMPARE WITH OTHER
RNZ ;;RETURN
INX H
INX D ;;INCR STRING POINTERS
JMP M1 ;;TRY SOME MORE
OVERSUB:
CLC MACRO ?STR1,?STR2,?LEN
LOCAL LITSTR,ENDLIT
IF NUL ?STR1&?STR2&?LEN
CALL @CLC
ELSE
IF NOT NUL ?STR1
LXI D,?STR1 ;;LOAD STRING1 POINTER
ENDIF
IF NUL ?LEN ;;TEST FOR LITERAL
MVI C,ENDLIT-LITSTR ;;LENGTH OF LITERAL STRING
LXI H,LITSTR ;;POINTER TO LITERAL
CALL @CLC
JMP ENDLIT
LITSTR: DB ?STR2 ;;LITERAL STRING
ENDLIT: ;;END OF STRING
ELSE
IF NOT NUL ?STR2
LXI H,?STR2 ;;LOAD POINTER TO STRING2
ENDIF
LSR C,?LEN ;;PUT LENGTH IN C.
CALL @CLC ;;CALL CLC SUBROUTINE
ENDIF
ENDIF
ENDM
CLC STR1,STR2,LEN
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; INSTR MACRO SEARCH STRING FOR SUBSTRING AND SET CARRY IF FOUND
;
; INSTR STRING,LENGTH,SUBSTR
;
; HL POINTS TO STRING
; DE POINTS TO SUBSTRING
; B CONTAINS STRING LENGTH
; C CONTAINS SUBSTRING LENGTH
;
; MACRO RETURNS POINTER TO END OF SUBSTRING IN HL
;
INSTR MACRO STRING,LENGTH,SUBSTR
LOCAL OVERSUB,S1,SSX
JMP OVERSUB
@INSTR: MOV A,B ;;STRING LENGTH
SUB C ;;SUBTRACT SUBSTR LENGTH
CMC ;;COMP CARRY
RNC ;;ERROR RETURN SUBSTR > STRING
MOV B,A ;;NEW STRING LIMIT TO B
S1: SAVE
CLC
RESTORE
JZ SSX ;;CLC IF ZERO ON RET
ANA A ;;RESET CARRY
DCR B ;;BYTES LEFT
RM ;;FINISHED IF MINUS, NO MATCH
INX H ;;INCR STRING POINTER
JMP S1 ;;TRY AGAIN
SSX: MVI B,0 ;;SET D TO 0
DAD B
STC ;;SET CARRY
RET
OVERSUB:
INSTR MACRO ?STR,?LEN,?SUBSTR
LOCAL LITSTR,ENDLIT
IF NOT NUL ?STR
LXI H,?STR
ENDIF
MVI B,?LEN
MVI C,ENDLIT-LITSTR
LXI D,LITSTR
CALL @INSTR
JMP ENDLIT
LITSTR: DB ?SUBSTR
ENDLIT:
ENDM
INSTR STRING,LENGTH,SUBSTR
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; SCAN MACRO SCAN A STRING UNTIL A CHAR IS FOUND, SKIP BLANKS
; AND CONTROL CHARACTERS
;
; CARRY SET IF NUMERIC, CARRY OFF IF ALPHABETIC
;
;
SCAN MACRO ADDR
LOCAL OVERSUB
JMP OVERSUB
@SCAN: MOV A,M ;;GET A BYTE
CPI 21H ;;SPACE OR LESS?
RP
INX H ;;INCR POINTER
JMP @SCAN ;;KEEP SEARCHING
OVERSUB:
SCAN MACRO ?ADDR
IF NOT NUL ?ADDR
LXI H,?ADDR
ENDIF
CALL @SCAN ;;CALL SUBROUTINE
CPI 3AH ;;NUMBER OR ALPHA
ENDM
SCAN ADDR
ENDM
;
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;
; MVC MACRO MOVE FLD2 TO FLD1
;
; MVC STR1,'LITERAL STRING'
; MVC STR1,STR2,LENGTH
; MVC
;
; DE POINTS TO STR1 MACRO WILL LOAD REG IF ARG
; HL POINTS TO STR2 PRESENT
; C CONTAINS LENGTH
;
; NORMALLY THE SECOND ARG IS A LITERAL STRING AND THE LENGTH
; IS OMITTED. IF THE LEN ARG IS PRESENT THE SECOND STRING
; ARG IS ASSUMED TO BE A MEMORY ADDR. IF ALL ARGUMENTS OMITTED
; REGISTERS ASSUMED ALREADY LOADED.
;
MVC MACRO STR1,STR2,LEN
LOCAL OVERSUB,M1
JMP OVERSUB
@MVC: INR C ;;PRE INCREMENT COUNT (IT MIGHT BE ZERO)
M1: DCR C ;;DECR LENGTH COUNT
RZ ;;RETURN WHEN ALL MOVED
MOV A,M ;;GET BYTE OF STR2.
STAX D ;;PUT IT IN STR1.
INX H
INX D ;;INCR STRING POINTERS
JMP M1 ;;TRY SOME MORE
OVERSUB:
MVC MACRO ?STR1,?STR2,?LEN
LOCAL LITSTR,ENDLIT
IF NUL ?STR1&?STR2&?LEN
CALL @MVC
ELSE
IF NOT NUL ?STR1
LXI D,?STR1 ;;LOAD STRING1 POINTER
ENDIF
IF NUL ?LEN ;;TEST FOR LITERAL
MVI C,ENDLIT-LITSTR ;;LENGTH OF LITERAL STRING
LXI H,LITSTR ;;POINTER TO LITERAL
CALL @MVC
JMP ENDLIT
LITSTR: DB ?STR2 ;;LITERAL STRING
ENDLIT: ;;END OF STRING
ELSE
IF NOT NUL ?STR2
LXI H,?STR2 ;;LOAD POINTER TO STRING2
ENDIF
LSR C,?LEN ;;PUT LENGTH IN C.
CALL @MVC ;;CALL MVC SUBROUTINE
ENDIF
ENDIF
ENDM
MVC STR1,STR2,LEN
ENDM
;
;
;END MACROS.LIB