;FILE 3740MACS.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 ; ; ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; ; DECOUT MACRO CONVERT A POSITIVE INTEGER TO DECIMAL AND OUTPUT ; TO THE CONSOLE. ; ; DECOUT ADDR ; ; IF ADDR OMITTED, NUMBER ASSUMED TO BE IN HL, ELSE LOADED TO HL ; LEADING ZEROS SUPRESSED. MAXIMUM NUMBER 65,767 ; DECOUT MACRO ADDR LOCAL ENDDEC,DX JMP ENDDEC @DECOUT: PUSH B ;PUSH STACK PUSH D PUSH H LXI B,-10 ;;RADIX FOR CONVERSION LXI D,-1 ;;THIS BECOMES NO DIVIDED BY RADIX DX: DAD B ;;SUBTRACT 10 INX D JC DX LXI B,10 DAD B ;;ADD RADIX BACK IN ONCE XCHG MOV A,H ORA L ;;TEST FOR ZERO CNZ @DECOUT ;;RECURSIVE CALL MOV A,E ADI '0' ;;CONVERT FROM BCD TO HEX CPM CWRITE,,?? ;;OUTPUT (A) TO CONSOLE. POP H ;;POP STACK POP D POP B RET ENDDEC: DECOUT MACRO ?ADDR IF NOT NUL ?ADDR LHLD ?ADDR ENDIF CALL @DECOUT ;;CALL THE SUBROUTINE ENDM DECOUT ADDR 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,<,,,> 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,<,,,> 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 DCR A ;;MAKE IT RELATIVE TO ZERO. 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 3740MACS.LIB