AppleIIAsm-Collection/disks/disk5_strings/T.SUBCOPY
nathanriggs 16c1731e54 Strings 0.2.0 update
- bugfixes
- implemented required library
- commenting updates
- .min of every routine
2018-12-22 20:35:05 -05:00

213 lines
5.5 KiB
Plaintext

*
*``````````````````````````````*
* SUBCOPY :: COPY SUBSTRING *
*- -*
* COPY A SUBSTRING FROM A *
* STRING TO [RETURN]. *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>STR ; SOURCE STRING *
* PHA *
* LDA #<STR *
* PHA *
* LDA #IND ; COPY START INDEX *
* PHA *
* LDA LEN ; LENGTH OF SUBSTR *
* PHA *
* LDA MLEN ; MAX LENGTH *
* PHA *
* JSR SUBCOPY *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* MAX LENGTH OF DEST STRING *
* NUMBER OF BYTES TO COPY *
* STARTING INDEX TO COPY FROM *
* LO BYTE OF SRC STRING ADDR *
* HI BYTE OF SOURCE STR ADDR *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
* .Y = TRASH *
* .X = TRASH *
* .A = TRASH *
* *
* CARRY FLAG WILL BE 0 IF NO *
* ERRORS; ELSE, CARRY = 1 *
*- -*
* ADAPTED FROM LEVANTHAL AND *
* WINTHROP'S /6502 ASSEMBLY *
* LANGUAGE ROUTINES/. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
SUBCOPY
*
** SAVE RETURN ADDRESS
*
PLA
STA RETADR
PLA
STA RETADR+1
*
** GET PARAMETERS
*
PLA
STA :MLEN
PLA
STA :SCNT
STA RETLEN
PLA
STA :SINDEX
PLA
STA ADDR1
PLA
STA ADDR1+1
*
LDA #<RETURN
STA ADDR2
LDA #>RETURN
STA ADDR2+1
*
** RESTORE RETURN ADDRESS
*
LDA RETADR+1
PHA
LDA RETADR
PHA
*
LDA #0
STA :S2LEN ; DESTINATION LENGTH = 0
STA :SCERR ; ASSUME NO ERRORS
*
** CHECK FOR ZERO BYTES TO COPY OR ZERO MAX SUBSTR LENGTH
*
LDA :SCNT
BEQ :OKEXIT ; BR IF 0 BYTES TO COPY,
; S2A WILL JUST HAVE ZERO LENGTH
LDA :MLEN
BEQ :EREXIT ; ERROR EXIT IF SUBSTR HAS
; ZERO MAX LENGTH
LDA :SINDEX
BEQ :EREXIT ; ERROR EXIT IF START IDX = 0
*
** CHECK IF SRC STR REACHES STARTING INDEX
*
LDY #0
LDA (ADDR1),Y ;
STA :S1LEN ; GET LENGTH OF SOURCE STRING
CMP :SINDEX ; COMPARE TO STARTING INDEX
BCC :EREXIT ; ERROR EXIT IF INDEX TOO BIG
*
** CHECK THAT WE DO NOT COPY BEYOND THE END OF
** THE SOURCE STRING.
** IF INDEX + COUNT -1 > SLEN THEN
** COUNT = SLEN - SINDEX + 1
*
LDA :SINDEX
CLC
ADC :SCNT
BCS :RECALC
TAX ; BR IF INDEX + COUNT > 255
DEX
CPX :S1LEN
BCC :CNT10K ; BR IF IND + CNT - 1 < S1LEN
BEQ :CNT10K ; OR EQUAL
*
** THE CALLER ASKED FOR TOO MANY CHARS SO
** JUST RETURN EVERYTHING BETWEEN INDEX AND
** END OF STRING. SO CNT = S1LEN - INDEX + 1
*
:RECALC
LDA :S1LEN ; RECALCULATE COUNT
SEC
SBC :SINDEX
STA :SCNT
INC :SCNT ; CNT = S1LEN - IND + 1
LDA #$0FF
STA :SCERR ; INDICATE TRUNCATION
*
** CHECK IF COUNT IS <= THE MAXIMUM LENGTH
** OF THE DEST STRING. IF NOT, THEN SET COUNT TO
** MAX LENGTH.
** IF COUNT > MAXLEN THEN
** COUNT = MAXLEN
*
:CNT10K
LDA :SCNT
CMP :MLEN ; IF CNT > M SUBSTR LEN ?
BCC :CNT20K ; BR IF CNT < MAXLEN
BEQ :CNT20K ; BR IF CNT = MAXLEN
LDA :MLEN
STA :SCNT ; ELSE CNT = MAXLEN
LDA #$0FF
STA :SCERR ; INDICATE DEST STR OVERFLOW
*
** EVERYTHING IS SET UP SO MOVE THE
** SUBSTRING TO THE DESTINATION STRING
*
:CNT20K
LDX :SCNT ; REG X WILL BE COUNTER
BEQ :EREXIT ; ERR IF 0
LDA #1 ; START WITH 1ST CHAR IN DEST
STA :S2LEN ; RUNNING DEST INDEX
; __SINDEX IS SRC INDEX
:MVLP
LDY :SINDEX
LDA (ADDR1),Y ; GET NEXT SRC CHAR
LDY :S2LEN
STA (ADDR2),Y ; MOVE NEXT CHAR TO DEST
INC :SINDEX ; INC SRC INDEX
INC :S2LEN ; INC DEST INDEX
DEX ; DECREMENT COUNTER
BNE :MVLP ; CONT UNTIL CNT = 0
DEC :S2LEN ; SUBSTR LEN=FINAL DEST IND-1
LDA :SCERR ; CHECK FOR ANY ERRORS
BNE :EREXIT ; BR IF STR TRUNCATED OR OVERFLOW
*
** GOOD EXIT
*
:OKEXIT
CLC
BCC :EXIT
*
** ERROR EXIT
*
:EREXIT
SEC
*
** STORE LENGTH BYTE IN FRONT OF SUBSTR
*
:EXIT
LDA :S2LEN
LDY #0
STA (ADDR2),Y
STA RETLEN
RTS
*
** DATA
*
:S1LEN DS 1
:S2LEN DS 1
:MLEN DS 1
:SCNT DS 1
:SINDEX DS 1
:SCERR DS 1
*