mirror of
https://github.com/nathanriggs/AppleIIAsm-Collection.git
synced 2024-11-27 12:49:27 +00:00
c8cac53c5e
Massive updates that changes the way most subroutines are handled. Major bugfixes, various utilities added, started higher-level libraries.
240 lines
6.1 KiB
Plaintext
240 lines
6.1 KiB
Plaintext
*``````````````````````````````*
|
|
* SUBINS :: INSERT SUBSTRING *
|
|
*- -*
|
|
* INSERT A SUBSTRING INTO *
|
|
* ANOTHER STRING. *
|
|
*- -*
|
|
* CLOBBERS: *
|
|
* *
|
|
* FLAGS: ????---- REG: AXYM *
|
|
*- -*
|
|
* CYCLES: ??? *
|
|
* SIZE: *
|
|
*- -*
|
|
* USAGE: *
|
|
* *
|
|
* LDA #STR ; STRING TO INS TO *
|
|
* PHA *
|
|
* LDA #<STR *
|
|
* PHA *
|
|
* LDA IND ; INDEX TO START INS *
|
|
* PHA *
|
|
* LDA MLEN ; MAX LENGTH OF STR *
|
|
* PHA *
|
|
* LDA #>SUB ; SUBSTRING TO INS *
|
|
* PHA *
|
|
* LDA #<SUB *
|
|
* PHA *
|
|
* JST SUBINS *
|
|
*- -*
|
|
* ENTRY *
|
|
* *
|
|
* TOP OF STACK *
|
|
* *
|
|
* LOW BYTE OF RETURN ADDRESS *
|
|
* HI BYTE OF RETURN ADDRESS *
|
|
* LO BYTE OF SUBSTRING ADDRESS *
|
|
* HI BYTE OF SUBSTRING ADDRESS *
|
|
* MAX LENGTH OF FINAL STRING *
|
|
* STARTING INDEX FOR INSERTION *
|
|
* 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 = 0 IF NO ERRORS; ELSE *
|
|
* CARRY = 1 *
|
|
*- -*
|
|
* ADAPTED FROM LEVANTHAL AND *
|
|
* WINTHROP'S /6502 ASSEMBLY *
|
|
* LANGUAGE ROUTINES/. *
|
|
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
|
|
*
|
|
SUBINS
|
|
*
|
|
** GET RETURN ADDRESS
|
|
*
|
|
PLA
|
|
TAY
|
|
PLA
|
|
TAX
|
|
*
|
|
** GET PARAMETERS
|
|
*
|
|
PLA
|
|
STA ADDR2
|
|
PLA
|
|
STA ADDR2+1
|
|
PLA
|
|
STA :MLEN
|
|
PLA
|
|
STA :SINDEX
|
|
PLA
|
|
STA ADDR1
|
|
PLA
|
|
STA ADDR1+1
|
|
*
|
|
** RESTORE RETURN ADDRESS
|
|
*
|
|
TXA
|
|
PHA
|
|
TYA
|
|
PHA
|
|
*
|
|
*
|
|
** ASSUME NO ERRORS
|
|
*
|
|
LDA #0
|
|
STA :SCERR ; ASSUME NO ERR WILL BE FOUND
|
|
*
|
|
** GET SUBSTRING AND STRING LENGTHS
|
|
** IF SUB LENGTH = 0 THEN EXIT NO ERROR
|
|
*
|
|
LDY #0
|
|
LDA (ADDR1),Y
|
|
STA :S1LEN ; GET LENGTH OF STRING
|
|
LDA (ADDR2),Y
|
|
STA :S2LEN ; GET LENGTH OF SUB
|
|
BNE :IDX0
|
|
JMP :OKEXIT ; EXIT OF NO INSERT/ERR
|
|
*
|
|
** IF STARTING INDEX IS 0 THEN ERROR EXIT
|
|
*
|
|
:IDX0
|
|
LDA :SINDEX
|
|
BNE :CHKLEN ; BR OF INDEX NOT 0
|
|
JMP :EREXIT ; ELSE ERROR EXIT
|
|
*
|
|
** CHECK THAT THE RESULTING STRING AFTER THE
|
|
** INSERTION FITS IN THE SOURCE STRING. IF NOT
|
|
** THEN TRUNCATE THE SUBSTRING AND SET
|
|
** THE TRUNCATION FLAG.
|
|
*
|
|
:CHKLEN
|
|
LDA :S2LEN ; GET SUBSTR LENGTH
|
|
CLC
|
|
ADC :S1LEN
|
|
BCS :TRUNC ;TRUN IF S1+S2 LENGTH > 255
|
|
CMP :MLEN ;
|
|
BCC :IDXLEN ; BR IF S1+S2 LEN < MAX LENGTH
|
|
BEQ :IDXLEN ; BR IF EQUAL
|
|
*
|
|
** SUBSTRING DOES NOT FIT, SO TRUNCATE IT
|
|
*
|
|
:TRUNC
|
|
LDA :MLEN ; SUBSTR LEN = MLEN - STR LEN
|
|
SEC
|
|
SBC :S1LEN
|
|
BCC :EREXIT
|
|
BEQ :EREXIT ; ERR IF MLEN < STR LEN OR 0
|
|
; (ORIGINAL STRING WAS TOO LONG)
|
|
STA :S2LEN
|
|
LDA #$0FF
|
|
STA :SCERR ; INDICATE SUBSTR WAS TRUNCATED
|
|
*
|
|
** CHECK THAT INDEX IS WITHIN STRING. IF NOT, CONCAT
|
|
** SUBSTR ONTO THE END OF THE STRING.
|
|
*
|
|
:IDXLEN
|
|
LDA :S1LEN
|
|
CMP :SINDEX ;
|
|
BCS :LENOK ; BR IF INDEX WITHIN STR
|
|
LDX :S1LEN ; ELSE CONCAT SUB AT END OF STR
|
|
INX
|
|
STX :SINDEX ; START RIGHT AFTER END OF STR
|
|
LDA #$0FF
|
|
STA :SCERR ; INDICATE ERR IN INSERT
|
|
LDA :S1LEN
|
|
CLC
|
|
ADC :S2LEN
|
|
STA :S1LEN ; ADD LENGTHS TOGETHER
|
|
JMP :MVESUB ; PERFORM MOVE, NOTHING ELSE TODO
|
|
*
|
|
** OPEN UP A SPACE IN THE SOURCE STRING FOR THE
|
|
** SUBSTRING BY MOVING THE CHARACTERS FROM THE END
|
|
** OF THE SOURCE STRING DOWN TO INDEX, UP BY
|
|
** THE SIZE OF THE STRING.
|
|
*
|
|
:LENOK
|
|
*
|
|
** CALC NUMBER OF CHARS TO MOVE
|
|
** COUNT = STR LEN - START INDEX + 1
|
|
*
|
|
LDA :S1LEN
|
|
SEC
|
|
SBC :SINDEX
|
|
TAX
|
|
INX ; X= NUM OF CHARS TO MOV
|
|
*
|
|
** SET THE SOURCE INDEX AND CALC DEST INDEX
|
|
*
|
|
LDA :S1LEN
|
|
STA :SIDX ; SRC ENDS AT ORIG STR END
|
|
CLC
|
|
ADC :S2LEN
|
|
STA :SBIDX ; DEST ENDS FURTHER BY SUB LEN
|
|
STA :S1LEN ; SET NEW LENGTH TO THIS ALSO
|
|
*
|
|
:OPNLP
|
|
LDY :SIDX
|
|
LDA (ADDR1),Y
|
|
LDY :SBIDX
|
|
STA (ADDR1),Y ; MOVE IT UP IN MEM
|
|
DEC :SIDX
|
|
DEC :SBIDX ; DE DEST IDX, COUNTER
|
|
DEX
|
|
BNE :OPNLP ; CONT UNTIL COUNTER = 0
|
|
*
|
|
** MOVE THE SUBSTR INTO THE OPEN AREA
|
|
*
|
|
:MVESUB
|
|
LDA #1
|
|
STA :SIDX
|
|
; START AT ONE IN THE SUBSTR
|
|
; START AT INDEX IN THE STRING
|
|
LDX :S2LEN ; X = NUM OF CHARS TO MOVE
|
|
*
|
|
:MVELP
|
|
LDY :SIDX
|
|
LDA (ADDR2),Y ; GET NEXT CHAR
|
|
LDY :SINDEX
|
|
STA (ADDR1),Y
|
|
INC :SIDX ; INC SUBSTR INDEX
|
|
INC :SINDEX ; INC STR INDEX
|
|
DEX ; DEC COUNTER
|
|
BNE :MVELP ; CONT UNTIL COUNTER = 0
|
|
LDA :SCERR ; GET ERROR FLAG
|
|
BNE :EREXIT ; BR IF SUBSTR WAS TRUNCED
|
|
*
|
|
:OKEXIT
|
|
CLC
|
|
BCC :EXIT
|
|
:EREXIT
|
|
SEC ; ERROR EXIT
|
|
:EXIT
|
|
LDA :S1LEN
|
|
LDY #0
|
|
STA (ADDR1),Y
|
|
RTS
|
|
*
|
|
** DATA
|
|
*
|
|
:S1LEN DS 1
|
|
:S2LEN DS 1
|
|
:SUBLEN DS 1
|
|
:MLEN DS 1
|
|
:SINDEX DS 1
|
|
:SIDX DS 1
|
|
:SBIDX DS 1
|
|
:SCERR DS 1
|
|
*
|