* *``````````````````````````````* * MEMMOVE :: MOVE MEM BLOCK * *- -* * MOVES A SPECIFIED BLOCK OF * * MEMORY FROM A SOURCE ADDRESS * * TO A DESTINATION ADDRESS * * RANGE. * *- -* * CLOBBERS: * * * * FLAGS: ????---- REG: AXYM * *- -* * CYCLES: ??? * * SIZE: * *- -* * USAGE: * * * * LDA #>$6A00 * * PHA * * LDA #<$6A00 * * PHA * * LDA #>$7000 ; DEST * * PHA * * LDA #<$7000 * * PHA * * LDA #>1024 * * PHA * * LDA #<1024 * * PHA * * JSR MEMMOVE * *- -* * ENTRY * * * * TOP OF STACK * * * * LOW BYTE OF RETURN ADDRESS * * HI BYTE OF RETURN ADDRESS * * NUMBER OF BYTES TO MOVE * * LOW BYTE OF DESTINATION * * HIGH BYTE OF DESTINATION * * LOW BYTE OF SOURCE ADDRESS * * HIGH BYTE OF SOURCE ADDRESS * *- -* * EXIT * * * * TOP OF STACK * * * * LOW BYTE OF RETURN ADDRESS * * HI BYTE OF RETURN ADDRESS * * * * Y = COUNTER; TRASH * * X = COUNTER; TRASH * * A = LOW BYTE OF RET ADDR * *- -* * ADAPTED FROM LEVANTHAL AND * * WINTHROP'S /6502 ASSEMBLY * * LANGUAGE ROUTINES/. * *,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,* * MEMMOVE * ** SAVE RETURN ADDRESS * PLA STA RETADR PLA STA RETADR+1 * ** GET PARAMETERS * PLA STA :MVELEN PLA STA :MVELEN+1 PLA STA ADDR2 ; ZERO PAGE POINTER PLA STA ADDR2+1 PLA STA ADDR1 PLA STA ADDR1+1 * ** DETERMINE IF DEST AREA IS ** ABOVE SRC AREA BUT OVERLAPS ** IT. REMEMBER, OVERLAP CAN BE ** MOD 64K. OVERLAP OCCURS IF ** STARTING DEST ADDRESS MINUS ** STARTING SRC ADDRESS (MOD ** 64K) IS LESS THAN NUMBER ** OF BYTES TO MOVE. * 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 :MVELEN TYA SBC :MVELEN+1 BCS :DOLEFT ; BRANCH IF NO OVERLAP * ** DEST AREA IS ABOVE SRC AREA ** BUT OVERLAPS IT. ** MOVE FROM HIGHEST ADDR TO ** AVOID DESTROYING DATA * JSR :MVERHT JMP :EXIT * ** NO PROB DOING ORDINARY MOVE ** STARTING AT LOWEST ADDR * :DOLEFT JSR :MVELEFT :EXIT JMP :MREXIT * ******************************** * SUBROUTINE: MVELEFT * ******************************** * :MVELEFT LDY #0 ; ZERO INDEX LDX :MVELEN+1 ; X=# OF FULL PP TO MOVE BEQ :MLPART ; IF X=0, DO PARTIAL PAGE :MLPAGE LDA (ADDR1),Y STA (ADDR2),Y ;MOVE ONE BYTE INY ; NEXT BYTE BNE :MLPAGE ; CONT UNTIL 256B MOVED INC ADDR1+1 ; ADV TO NEXT SRC PAGE INC ADDR2+1 ; ADV NEXT DEST PAGE DEX ; DEC PAGE COUNT BNE :MLPAGE ; CONT UNTIL ALL FULL ; PAGES ARE MOVED :MLPART LDX :MVELEN ; GET LENGTH OF LAST PAGE BEQ :MLEXIT ; BR IF LENGTH OF LAST ; PAGE = 0 ; REG Y IS 0 :MLLAST LDA (ADDR1),Y STA (ADDR2),Y ; MOVE BYTE INY ; NEXT BYTE DEX ; DEC COUNTER BNE :MLLAST ; CONT UNTIL LAST P DONE :MLEXIT JMP :MREXIT * ******************************** * SUBROUTINE: MVERHT * ******************************** * :MVERHT * ** MOVE THE PARTIAL PAGE FIRST * LDA :MVELEN+1 CLC ADC ADDR1+1 STA ADDR1+1 ;POINT TO LAST P OF SRC LDA :MVELEN+1 CLC ADC ADDR2+1 STA ADDR2+1 ; POINT TO LAST P OF DEST * ** MOVE THE LAST PARTIAL PAGE FIRST * LDY :MVELEN ;GET LENGTH OF LAST PAGE BEQ :MRPAGE ; IF Y=0 DO THE FULL PAGES :MR0 DEY ; BACK UP Y TO NEXT BYTE LDA (ADDR1),Y STA (ADDR2),Y ; MOVE BYTE CPY #0 BNE :MR0 ; BR IF NOT DONE W LAST P :MRPAGE LDX :MVELEN+1 ; GET BYTE OF COUNT AS P CT BEQ :MREXIT ; BR IF HYBYTE = 0 (NO FULL P) :MR1 DEC ADDR1+1 ; BACK UP TO PREV SRC PAGE DEC ADDR2+1 ; AND DEST :MR2 DEY ; BACK UP Y TO NEXT BYTE LDA (ADDR1),Y STA (ADDR2),Y ; MOVE BYTE CPY #0 BNE :MR2 ; BR IF NOT DONE W THIS PAGE DEX BNE :MR1 BR IF NOT ALL PAGES MOVED :MREXIT * ** RESTORE RETURN ADDRESS * LDA RETADR+1 PHA LDA RETADR PHA RTS * ** DATA * :MVELEN DS 2 *