AppleIIAsm-Collection/disks/disk2_common/T.MEMMOVE.SUB
nathanriggs 12a0b19398 Disk 2 COMMON library 0.3.0 updates
- added some error control
- added initial jump table
- fixed a few minor bugs
- separated common library into separate subroutine files
2019-01-14 10:57:05 -05:00

211 lines
5.4 KiB
Plaintext

*
*``````````````````````````````*
* 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
*