*
*``````````````````````````````*
* MEMSWAP ::       MEMORY SWAP *
*-                            -*
* SWAPS THE VALUES STORED IN   *
* TWO BLOCKS OF SEQUENTIAL     *
* MEMORY.                      *
*-                            -*
* CLOBBERS:                    *
*                              *
* FLAGS:  ????----  REG: AXYM  *
*-                            -*
* CYCLES: ???                  *
* SIZE:                        *
*-                            -*
* USAGE:                       *
*                              *
*  LDA #>$6A00                 *
*  PHA                         *
*  LDA #<$6A00                 *
*  PHA                         *
*  LDA #>$300                  *
*  PHA                         *
*  LDA #<$300                  *
*  PHA                         *
*  LDA #$100                   *
*  PHA                         *
*  JSR MEMSWAP                 *
*-                            -*
* ENTRY                        *
*                              *
* TOP OF STACK                 *
*                              *
* LOW BYTE OF RETURN ADDRESS   *
* HI BYTE OF RETURN ADDRESS    *
* LOW BYTE OF FIRST ADDRESS    *
* HIGH BYTE OF FIRST ADDRESS   *
* LOBYTE OF SECOND ADDRESS     *
* HIBYTE OF SECOND ADDRESS     *
*-                            -*
* EXIT                         *
*                              *
* TOP OF STACK                 *
*                              *
* LOW BYTE OF RETURN ADDRESS   *
* HI BYTE OF RETURN ADDRESS    *
*                              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
MEMSWAP
*
** GET RETURN ADDRESS
*
         PLA
         STA   RETADR
         PLA
         STA   RETADR+1
*
** GET VARIABLES
*
         PLA
         STA   :LENGTH
         PLA
         STA   ADDR1
         STA   :A1
         PLA
         STA   ADDR1+1
         STA   :A1+1
         PLA
         STA   ADDR2
         STA   :A2
         PLA
         STA   ADDR2+1
         STA   :A2+1
*
********************************
*
*  ERROR CONTROL
*
********************************
*
         LDA   ERRCTRL
         CMP   #1
         BEQ   :CHKERR
         JMP   :ERREND
:CHKERR
         LDA   ADDR2+1    ; IF #>A2 => #>A1
         CMP   ADDR1+1
         BCS   :CHKLO     ; CHECK LOW BYTES
         JMP   :A1GTA2    ; ELSE, A1 > A2
:CHKLO
         LDA   ADDR2
         CMP   ADDR1
         BCS   :A2GTA1
         JMP   :A1GTA2
:A2GTA1
         LDA   ADDR2      ;CALC DEST-SRC
         SEC
         SBC   ADDR1
         TAX
         LDA   ADDR2+1
         SBC   ADDR1+1    ; MOD 64K AUTOMATIC
                          ; -- DISCARD CARRY
         TAY
         TXA              ; CMP WITH # OF BYTES TO MOVE
         CMP   :LENGTH
         TYA
         SBC   :LENGTH+1
         BCS   :ERREND    ; BRANCH IF NO OVERLAP
         JMP   :OVF
:A1GTA2
         LDA   ADDR1
         SEC
         SBC   ADDR2
         TAX
         LDA   ADDR1+1
         SBC   ADDR2+1
         TAY
         TXA
         CMP   :LENGTH
         TYA
         SBC   :LENGTH+1
         BCS   :ERREND
:OVF
         _ERR  #:E_SID;#:E_OVF;#:E_DUMP;#:LENGTH;#6
*
********************************
*
:ERREND
*
********************************
*
         LDY   #255       ;  COUNTER
:LP
         INY
         LDA   (ADDR1),Y
         TAX              ; X CONTAINS ADDR1 VAL
         LDA   (ADDR2),Y  ; A CONTAINS ADDR2 VAL
         STA   (ADDR1),Y
         TXA
         STA   (ADDR2),Y
         CPY   :LENGTH
         BNE   :LP
*
** RESTORE RETURN ADDRESS
*
         LDA   RETADR+1
         PHA
         LDA   RETADR
         PHA
*
         RTS
*
** VARIABLES
*
:LENGTH  DS    2
:A1      DS    2
:A2      DS    2
*
:E_SID   ASC   "MEMSWAP (MSWAP MACRO)",00
:E_DUMP  ASC   "DUMPING LENGTH (2) A1(2) A2(2)",00
:E_OVF   ASC   "OVERFLOW! ADDRESSES OVERLAP.",00
*
