AppleIIAsm-Collection/disks/disk5_strings/T.STRCAT
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

206 lines
5.2 KiB
Plaintext

*
*``````````````````````````````*
* STRCAT :: STRING CONCATENATE *
*- -*
* CONCATENATE TWO STRINGS INTO *
* A SINGLE STRING STORE WHERE *
* THE FIRST STRING IS LOCATED. *
* ADDITIONALLY COPIES CONCAT'D *
* STRING TO [RETURN]. *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>CATSTR *
* PHA *
* LDA #<CATSTR *
* PHA *
* LDA #>CATSTR2 *
* PHA *
* LDA #<CATSTR2 *
* PHA *
* LDA #7 ; MAX SIZE OF CAT *
* PHA *
* JSR STRCAT *
* *
* CATSTR STR "ABC" *
* BLANK STR " " *
* CATSTR2 STR "DEF" *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* MAXIMUM LENGTH OF CONCAT STR *
* LOW BYTE OF STR2 ADDRESS *
* HIGH BYTE OF STR2 ADDRESS *
* LOW BYTE OF STR1 ADDRESS *
* HIGH BYTE OF STR1 ADDRESS *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
* .Y = CLOBBERED; TRASH *
* .X = LENGTH OF FINAL STRING *
* .A = 1 IF OVERFLOW, 0 IF NO *
* [RETURN] = CONCAT'D STRING *
* [RETLEN] = LENGTH OF NEW STR *
*- -*
* ADAPTED FROM LEVANTHAL AND *
* WINTHROP'S /6502 ASSEMBLY *
* LANGUAGE ROUTINES/. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
STRCAT
*
** SAVE RETURN ADDRESS
*
PLA
STA RETADR
PLA
STA RETADR+1
*
** GET PARAMETERS
*
PLA
STA :MLEN ; MAXIMUM CONCAT LENGTH
*
PLA
STA ADDR2 ; STRING 1 ADDRESS
PLA ; IN ZERO PAGE
STA ADDR2+1
PLA
STA ADDR1 ; STRING 2 ADDRESS
PLA ; IN ZERO PAGE
STA ADDR1+1
*
** DETERMINE WHERE TO START
*
LDY #0
LDA (ADDR1),Y ; GET CUR LGTH OF S1, STORE
STA :S1LEN
STA :S1IND
INC :S1IND ; START CONCAT AT END OF S1
LDA (ADDR2),Y ; GET LENGTH OF S2, STORE
STA :S2LEN
LDA #1
STA :S2IND ; START CONCAT AT BEGIN OF S2
*
** DETERMINE NUMBER OF CHAR
*
LDA :S2LEN ; GET S2 LENGTH
CLC
ADC :S1LEN ; ADD TO LENGTH OF S1
STA :S3LEN ; STORE CONCAT LENGTH
BCS :TOOLONG ; BR IF LENGTH > 255
CMP :MLEN ; CHECK AGAINST MAX LENGTH
BEQ :LENOK ; BR IF LENGTH < MAX
BCC :LENOK
*
** RESULTING STRING WILL BE TOO LONG SO
** INDICATE A STRING OVERFLOW, __SOVF = 0FF
** SET NUMBER OF CHARS TO CONCAT = MLEN - S1LEN
** SET LENGTH OF STRING 1 TO MAX LENGTH
*
:TOOLONG
LDA #$0FF
STA :SOVF ; INDICATE OVERFLOW
LDA :MLEN
SEC
SBC :S1LEN
BCC :EXIT
; EXIT IF MLEN < S1LEN
STA :SCNT ; ORIG STR WAS TOO LONG
LDA :MLEN
STA :S1LEN ; SET STR1 LENGTH TO MAX
JMP :DOCAT
*
** RESULTING LENGTH DOES NOT EXCEED MAX
** LENGTH OF STRING 1 = S1LEN + S2LEN
** INDICATE NO OVERFLOW, __SOVF = 0
** SET NUM OF CHARS TO CONCAT TO LENGTH OF STR 2
*
:LENOK
STA :S1LEN
LDA #0 ; SAVE SUM OF 2 LENGTHS
STA :SOVF ; INDICATE NO OVERFLOW
LDA :S2LEN
STA :SCNT ; COUNT = LENGTH OF STRING 2
*
** CONCAT STRINGS
*
:DOCAT
LDA :SCNT
BEQ :EXIT ; EXIT IF NO BYTES LEFT
*
:CATLP
LDY :S2IND
LDA (ADDR2),Y ; GET NEXT BYTE FROM S2
LDY :S1IND
STA (ADDR1),Y ; MOVE IT TO END OF STR 1
INC :S1IND ;INC STRING 1 INDEX
INC :S2IND ; INC STRING 2 INDEX
DEC :SCNT ; DECREMENT COUNTER
BNE :CATLP ; CONT UNTIL __SCNT = 0
*
:EXIT
*
** UPDATE STRING1 LENGTH
*
LDA :S1LEN
LDY #0
STA (ADDR1),Y
LDA :SOVF
ROR A
*
** RESTORE RETURN ADDRESS
*
LDA RETADR+1
PHA
LDA RETADR
PHA
*
** COPY TO [RETURN]
*
LDY #0
LDA (ADDR1),Y ; LENGTH OF STRING
STA RETLEN
LDA #1
:RLP
LDA (ADDR1),Y
STA RETURN,Y
CPY RETLEN
INY
BNE :RLP
LDA RETLEN
LDY #0
STA (ADDR1),Y
*
LDX :S3LEN ; RETURN FINAL LENGTH
*
RTS
*
** DATA
*
:S3LEN DS 1
:S1LEN DS 1
:S1IND DS 1
:S2LEN DS 1
:S2IND DS 1
:MLEN DS 1
:SCNT DS 1
:SOVF DS 1
*