*DMOVE: DELIMITED MOVE SUBROUTINE * ON ENTRY, A=Maximum number of bytes to move * BC=Source address * DE=Destination address * HL=Delimiter string address. First byte of string is * the length of the string which follows. * Carry=0 to stop on delimiter (NORMAL mode) * 1 to stop on non-delimiter (REVERSED mode) * TO SCAN ONLY, make destination = source. * * ON RETURN, A is decremented by # of bytes moved * BC points to source byte after last one moved * DE points to destination byte after last one moved * HL points to byte in delimiter string which was * found, if in NORMAL mode and count didn't stop * the move. (Otherwise HL undefined.) * Flags undefined. * The delimiter is not moved, so if A is zero, the * last character moved was not the delimiter and * thus the count stopped the move. The next byte * in the source was not examined. * * USES FOUR BYTES OF CALLER'S STACK * DMOVE EQU $ STA DMOVC ;SAVE MAX COUNT SHLD DMOVD ;SAVE DELIMITER POINTER PUSH H PUSH D LHLD DMOV5 ;ADDRESS DMOV8 XCHG LHLD DMOV6 ;ADDRESS DMOV9 JNC DMOV0 ;JUMP IF NORMAL MODE XCHG ;REVERSED MODE DMOV0 SHLD DMOV4+1 XCHG SHLD DMOV3+1 POP D POP H LDA DMOVC DMOV1 ORA A JZ DMOV7 ;COUNT REACHED ZERO PUSH D ;SAVE DESTINATION LDAX B ;GET SOURCE BYTE MOV D,A ;D=SOURCE BYTE LHLD DMOVD ;GET DELIMITER POINTER MOV E,M ;E=DELIM SET LENGTH INX H ;HL=PTR TO DELIM BYTE DMOV2 MOV A,E ;A=CURRENT DELIM COUNT ORA A DMOV3 JZ DMOV8 ;WILL BE DMOV9 IN REVERSED MOV A,D CMP M ;COMPARE SOURCE AND DELIM DMOV4 JZ DMOV9 ;WILL BE DMOV8 IN REVERSED DCR E ;DECREMENT DELIM COUNT INX H ;POINT TO NEXT DELIM JMP DMOV2 ;AGAIN *MOVER DMOV8 MOV A,D ;GET SOURCE BYTE POP D ;RESTORE DEST STAX D ;MOVE IT INX B ;INCR SOURCE INX D ;INCR DEST LDA DMOVC ;GET MOVE COUNT DCR A ;DECR IT STA DMOVC ;SAVE IT JMP DMOV1 ;AGAIN *CLEANUP DMOV9 POP D ;FOUND DESIRED BYTE DMOV7 LDA DMOVC RET DMOV6 DW DMOV9 DMOV5 DW DMOV8 DMOVC DS 2 ;CURRENT MOVE COUNT DMOVD DS 2 ;DELIM POINTER END