;
; SYSLIB Module Name:  SMOVE
; Author:  Richard Conn
; SYSLIB Version Number:  2.0
; Module Version Number:  1.0
; Module Entry Points:
;       HMOVB           HMOVBC          MOVEB           MOVEBC
; Module External References:
;       None
;

;
;  SMOVEB.MAC -- SYSLIB MODULE
;
;  ENTRY POINTS --
;       EXT     MOVEB           -- MOVE BYTES PTED TO BY HL TO
;                                  LOCATION PTED TO BY DE FOR B BYTES
;       EXT     MOVEBC          -- MOVE BYTES PTED TO BY HL TO
;                                  LOCATION PTED TO BY DE FOR BC BYTES
;
;  NO REGISTERS ARE TO BE AFFECTED
;
;       EXT     HMOVB           -- LIKE MOVEB, BUT HL AND DE PT TO BYTE AFTER
;                                  LAST BYTE MOVED WHEN DONE
;       EXT     HMOVBC          -- LIKE MOVEBC, BUT HL AND DE PT TO BYTE AFTER
;                                  LAST BYTE MOVED WHEN DONE
;

;
;  SUPPORTING MACROS --
;
PUTRG   MACRO           ; SAVE ALL REGS
       PUSH    PSW
       PUSH    B
       PUSH    D
       PUSH    H
       ENDM

GETRG   MACRO           ; RESTORE ALL REGS
       POP     H
       POP     D
       POP     B
       POP     PSW
       ENDM

;
;  HMOVB AND HMOVBC ROUTINES --
;
HMOVB::
       CALL    MOVEB   ; DO THE MOVE
       PUSH    B       ; SAVE BC
       MOV     C,B     ; BC=B
       MVI     B,0
       DAD     B       ; HL PTS TO BYTE AFTER LAST BYTE MOVED
       XCHG
       DAD     B       ; DE PTS TO BYTE AFTER LAST BYTE MOVED
       XCHG
       POP     B       ; GET BC
       RET

HMOVBC::
       CALL    MOVEBC  ; DO THE MOVE
       PUSH    B       ; SAVE BC
       DAD     B       ; HL PTS TO BYTE AFTER LAST BYTE MOVED
       XCHG
       DAD     B       ; DE PTS TO BYTE AFTER LAST BYTE MOVED
       XCHG
       POP     B       ; GET BC
       RET

;
;  MOVEB AND MOVEBC ROUTINES --
;
MOVEB::
       PUSH    B       ; SAVE BC
       MOV     C,B     ; C=B
       MVI     B,0     ; B=0
       CALL    MOVEBC  ; USE MOVEBC
       POP     B       ; RESTORE BC
       RET

MOVEBC::
       PUTRG           ; SAVE ALL REGS

;  DETERMINE IF HL < DE; IF SO, MOVE BACK TO FRONT; OTHERWISE, FRONT TO BACK
       MOV     A,H     ; HL<DE?
       CMP     D
       JC      MOVER   ; MOVE BACK-TO-FRONT
       JNZ     MOVEF   ; MOVE FRONT-TO-BACK IF HL>DE
       MOV     A,L     ; HL<DE?
       CMP     E
       JC      MOVER   ; MOVE BACK-TO-FRONT

;  MOVE FRONT-TO-BACK
MOVEF:
       MOV     A,M     ; GET BYTE
       STAX    D       ; PUT BYTE
       INX     H       ; PT TO NEXT
       INX     D
       DCX     B       ; COUNT DOWN
       MOV     A,B     ; DONE?
       ORA     C
       JNZ     MOVEF

;  DONE WITH PROGRAM
DONE:
       GETRG           ; RESTORE ALL REGS
       RET

;  MOVE BACK-TO-FRONT
MOVER:
;  POINT TO END OF BUFFERS
       DCX     B       ; DECR COUNT BY 1
       DAD     B       ; PT TO END OF BUFFERS
       XCHG
       DAD     B
       XCHG
       INX     B       ; CORRECT BYTE COUNT
;  PERFORM MOVE
MOVERL:
       MOV     A,M     ; GET BYTE
       STAX    D       ; PUT BYTE
       DCX     H       ; PT TO NEXT
       DCX     D
       DCX     B       ; COUNT DOWN
       MOV     A,B     ; DONE?
       ORA     C
       JNZ     MOVERL
       JMP     DONE

       END