Disk 5: STRINGS 0.3.0 updates

- separated subroutines into own files
- added some, but very little, additional error handling; Leventhal's routines already handle errors pretty well, so there isn't much to add in that regard until a total rewrite of each
This commit is contained in:
nathanriggs 2019-01-21 13:27:30 -05:00
parent d99c32fdda
commit e0c1f8e82d
42 changed files with 7528 additions and 9105 deletions

Binary file not shown.

View File

@ -0,0 +1,30 @@
5 HOME
8 ONERR GOTO 1000
10 PRINT "ASSEMBLY CODE MINIFIER"
20 PRINT "-=-=-=-=-=-=-=-=-=-=-="
30 PRINT
35 DIM FC$(1000):C = 0
40 INPUT "ENTER THE SOURCE FILE NAME: ";FF$
50 INPUT "ENTER THE DESTINATION FILE NAME: ";DD$
55 PRINT "WORKING.."
60 PRINT CHR$ (4);"OPEN ";FF$
70 PRINT CHR$ (4);"READ ";FF$
80 GET AA$
85 REM ? CHR$ (34);".";
90 IF AA$ = CHR$ (13) THEN GOTO 200
95 S$ = S$ + AA$
110 GOTO 80
200 IF LEFT$ (S$,1) = "*" OR LEFT$ (S$,1) = ";" THEN S$ = ""
500 FC$(C) = S$
510 S$ = ""
520 C = C + 1
990 GOTO 80
1000 PRINT : PRINT CHR$ (4);"CLOSE ";FF$
1010 PRINT CHR$ (4);"OPEN ";DD$
1020 PRINT CHR$ (4);"WRITE ";DD$
1030 FOR Z = 0 TO C
1040 IF FC$(Z) < > "" THEN PRINT FC$(Z)
1050 NEXT Z
1060 PRINT CHR$ (4);"CLOSE ";DD$
1070 PRINT "DONE!": PRINT : PRINT : PRINT
1080 PRINT CHR$ (7): PRINT CHR$ (7): PRINT CHR$ (7)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,98 +0,0 @@
*
NUM2STR
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :VALSTR
PLA
STA :VALSTR+1
STA :NGFLAG
BPL :GETBP
LDA #0
SEC
SBC :VALSTR
STA :VALSTR
LDA #0
SBC :VALSTR+1
STA :VALSTR+1
:GETBP
LDA #<RETURN
STA ADDR1
LDA #>RETURN+1
STA ADDR1+1
LDA #0
LDY #0
STA (ADDR1),Y
:CNVERT
LDA #0
STA :MOD10
STA :MOD10+1
LDX #16
CLC
:DVLOOP
ROL :VALSTR
ROL :VALSTR+1
ROL :MOD10
ROL :MOD10+1
SEC
LDA :MOD10
SBC #10
TAY
LDA :MOD10+1
SBC #0
BCC :DECCNT
STY :MOD10
STA :MOD10+1
:DECCNT
DEX
BNE :DVLOOP
ROL :VALSTR
ROL :VALSTR+1
:CONCH
LDA :MOD10
CLC
ADC #$B0
JSR :CONCAT
LDA :VALSTR
ORA :VALSTR+1
BNE :CNVERT
:EXIT
LDA :NGFLAG
BPL :POS
LDA #173
JSR :CONCAT
:POS
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:CONCAT
PHA
LDY #0
LDA (ADDR1),Y
TAY
BEQ :EXITMR
:MVELP
LDA (ADDR1),Y
INY
STA (ADDR1),Y
DEY
DEY
BNE :MVELP
:EXITMR
PLA
LDY #1
STA (ADDR1),Y
LDY #0
LDA (ADDR1),Y
CLC
ADC #1
STA (ADDR1),Y
RTS
:NGFLAG DS 1
:VALSTR DS 2
:MOD10 DS 2

View File

@ -1,4 +1,3 @@
*
*``````````````````````````````*
* NUM2STR :: NUMBER TO STRING *
*- -*

View File

@ -0,0 +1,97 @@
NUM2STR
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :VALSTR
PLA
STA :VALSTR+1
STA :NGFLAG
BPL :GETBP ; BR IF VAL IS POS
LDA #0
SEC
SBC :VALSTR
STA :VALSTR
LDA #0
SBC :VALSTR+1
STA :VALSTR+1
:GETBP
LDA #<RETURN
STA ADDR1 ; ADDRESS TO STORE STRING
LDA #>RETURN+1
STA ADDR1+1
LDA #0 ; SET BUFFER TO EMPTY
LDY #0
STA (ADDR1),Y ; BUFFER(0) = 0
:CNVERT
LDA #0
STA :MOD10
STA :MOD10+1
LDX #16
CLC ; CLEAR CARRY
:DVLOOP
ROL :VALSTR ; SHIFT CARRY INTO DIVBIT 0
ROL :VALSTR+1 ; WHICH WILL BE THE QUOTIENT
ROL :MOD10 ; + SHIFT DIV AT SAME TIME
ROL :MOD10+1
SEC
LDA :MOD10
SBC #10
TAY ; SAVE LOWB IN REG Y
LDA :MOD10+1
SBC #0 ; SUBTRACT CARRY
BCC :DECCNT ; BR IF DEND < DIVISOR
STY :MOD10 ; ELSE
STA :MOD10+1 ; NXT BIT OF Q IS A ONE AND SET
; DIVIDEND = DEND - DIVISOR
:DECCNT
DEX
BNE :DVLOOP
ROL :VALSTR ; SHIFT IN LAST CARRY FOR Q
ROL :VALSTR+1
:CONCH
LDA :MOD10
CLC
ADC #$B0
JSR :CONCAT
LDA :VALSTR
ORA :VALSTR+1
BNE :CNVERT ; BR IF VALUE != 0
:EXIT
LDA :NGFLAG
BPL :POS ; BR IF ORIG VAL POS
LDA #173 ; ELSE
JSR :CONCAT ; PUT A MINUS SIGN IN FRONT
:POS
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS ; RETURN
:CONCAT
PHA ; SAVE CHAR ON STACK
LDY #0
LDA (ADDR1),Y ; GET CURRENT LENGTH
TAY
BEQ :EXITMR ; BR IF LENGTH=0
:MVELP
LDA (ADDR1),Y ; GET NEXT CHAR
INY
STA (ADDR1),Y ; STORE IT
DEY
DEY
BNE :MVELP ; CONT UNTIL DONE
:EXITMR
PLA ; GET CHAR BACK FROM STACK
LDY #1
STA (ADDR1),Y ; STORE THE CHAR
LDY #0
LDA (ADDR1),Y ; GET LENGTH BYTE
CLC
ADC #1 ; INC LENGTH BY ONE
STA (ADDR1),Y ; UPDATE LENGTH
RTS
:NGFLAG DS 1
:VALSTR DS 2
:MOD10 DS 2

View File

@ -1,4 +1,3 @@
*
*``````````````````````````````*
* PRNSTR :: PRINT INDEXED STR *
*- -*

View File

@ -1,23 +1,22 @@
*
PRNSTR
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA ADDR1
STA ADDR1 ; ADDRESS OF STRING
PLA
STA ADDR1+1
LDY #0
LDA (ADDR1),Y
LDA (ADDR1),Y ; GET STRING LENGTH
STA :S1LEN
:LP
INY
LDA (ADDR1),Y
JSR SCOUT1
CPY :S1LEN
LDA (ADDR1),Y ; GET CHARACTER
JSR SCOUT1 ; PRINT CHARACTER TO SCREEN
CPY :S1LEN ; IF Y < LENGTH
BNE :LP
; LOOP; ELSE
LDY #0
LDA (ADDR1),Y
LDA RETADR+1
@ -25,8 +24,8 @@ PRNSTR
LDA RETADR
PHA
LDY #0
LDA (ADDR1),Y
LDA (ADDR1),Y ; STRING LENGTH IN A
LDY ADDR1
LDX ADDR1+1
LDX ADDR1+1 ; ADDRESS IN Y,X
RTS
:S1LEN DS 1

View File

@ -1,46 +0,0 @@
*
*``````````````````````````````*
* DECLARATIONS.PUT *
*- -*
* USED IN CONJUNCTION WITH *
* OTHER PUT FILES. DEFINES *
* BASIC DECLARATIONS USED *
* ACROSS DIFFERENT ROUTINES *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** ADDRESS STORAGE LOCATIONS FOR
** INDIRECT ADDRESSING.
*
ADDR1 EQU $06
ADDR2 EQU $08
ADDR3 EQU $EB
ADDR4 EQU $ED
*
** SCRATCHPAD ZERO PAGE LOCATIONS AND
** DEDICATED ZERO PAGE ADDRESS TO HOLD
** A RETURN ADDRESS PASSED VIA THE STACK
*
SCRATCH EQU $19
SCRATCH2 EQU $1E
RETADR EQU $FE
*
** ZERO PAGE ADDRESSES DEDICATED TO PASSING
** BACK RESULTS WHEN THERE ARE MORE THAN
** THREE BYTES BEING PASSED (AXY) AND THE
** USE OF THE STACK IS IMPRACTICAL OR TOO SLOW
*
RESULT EQU $FA
RESULT2 EQU $FC
*
** VARIOUS HOOKS USED BY ALL ROUTINES
*
REENTRY EQU $3D0
*
** ERROR HANDLING MEMORY LOCATIONS
*
** THIS DESIGNATES A 16-BYTE BLOCK OF MEMORY
** THAT HOLDS DATA RELATED TO IDENTIFYING
** RUNTIME VALUES FOR DEBUGGING.
*
ERRLOC EQU $0C00
*

View File

@ -0,0 +1,10 @@
ADDR1 EQU $06
ADDR2 EQU $08
ADDR3 EQU $EB
ADDR4 EQU $ED
SCRATCH EQU $19
SCRATCH2 EQU $1E
RETADR EQU $FE
RESULT EQU $FA
RESULT2 EQU $FC
REENTRY EQU $3D0

View File

@ -1,235 +0,0 @@
*
JMP ENDVARS
*
*``````````````````````````````*
* REQUIRED.LIB *
*- -*
* GLOBAL ROUTINES AND *
* VARIABLES EITHER USED BY THE *
* LIBRARY OR PROVIDED FOR DEMO *
* USE OR DEBUGGING PURPOSES. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
********************************
* *
* GLOBAL ROUTINES *
* *
********************************
*
*``````````````````````````````*
* __GETRET: GET RETURN *
*- -*
* COPIES THE DATA IN [RETURN] *
* TO THE SPECIFIED LOCATION. *
* LENGTH IS DETERMINED BY *
* VALUE OF RETLEN. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
__GETRET
*
LDY #255
PLA
STA ADDR1
PLA
STA ADDR1+1
*
:LP
INY
LDA RETURN,Y
STA (ADDR1),Y
CPY RETLEN
BNE :LP
LDA ADDR1+1
PHA
LDA ADDR1
PHA
RTS
*
*``````````````````````````````*
* __SETPARM: SET PARAMETER *
*- -*
* COPIES DATA FROM SPECIFIED *
* ADDRESS TO THE [PARAM] *
* LOCATION FOR PASSING TO *
* A ROUTINE. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
__SETPARM
*
LDY #255
PLA
STA ADDR1
PLA
STA ADDR1+1
*
:LP
INY
LDA (ADDR1),Y
STA PARAM,Y
CPY PARLEN
BNE :LP
LDA ADDR1+1
PHA
LDA ADDR1
PHA
RTS
*
*``````````````````````````````*
* __DUMP: DUMP DATA *
*- -*
* OUTPUTS DATA LOCATED AT THE *
* SPECIFIED ADDRESS IN HEX *
* FORMAT FOR SPECIFIED NUMBER *
* OF BYTES. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
__DUMP
*
PLA
STA :RET
PLA
STA :RET+1
PLA
STA :LENGTH
PLA
STA ADDR3
PLA
STA ADDR3+1
*
LDA #$8D
JSR $FDF0
LDA ADDR3+1
AND #$F0
LSR
LSR
LSR
LSR
TAX
LDA :HEXTAB,X
JSR $FDF0
LDA ADDR3+1
AND #$0F
TAX
LDA :HEXTAB,X
JSR $FDF0
LDA ADDR3
AND #$F0
LSR
LSR
LSR
LSR
TAX
LDA :HEXTAB,X
JSR $FDF0
LDA ADDR3
AND #$0F
TAX
LDA :HEXTAB,X
JSR $FDF0
LDA #186 ; :
JSR $FDF0
LDA #160 ; SPC
JSR $FDF0
*
LDY #0
:LP
LDA (ADDR3),Y
AND #$F0 ; MASK RIGHT
LSR
LSR
LSR
LSR
STA :LEFT
LDA (ADDR3),Y
AND #$0F ; MASK LEFT
STA :RIGHT
LDX :LEFT
LDA :HEXTAB,X
JSR $FDF0
LDX :RIGHT
LDA :HEXTAB,X
JSR $FDF0
LDA #160
JSR $FDF0
INY
CPY :LENGTH
BNE :LP
*
*LDA #$8D
*JSR $FDF0
LDA :RET+1
PHA
LDA :RET
PHA
*
RTS
*
:RET DS 2
:RIGHT DS 1
:LEFT DS 1
:LENGTH DS 1
:HEXTAB ASC "0123456789ABCDEF"
*
*``````````````````````````````*
* __P: PRINT FOLLOWING ASC *
*- -*
* THIS IS THE XPRINT ROUTINE *
* FROM STDIO.LIB, BUT STRIPPED *
* OF COMMENTS. FOR DEBUG. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
__P
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #1
:LP LDA (ADDR1),Y
BEQ :DONE
JSR $FDF0
INY
BNE :LP
:DONE CLC
TYA
ADC ADDR1
STA ADDR1
LDA ADDR1+1
ADC #0
PHA
LDA ADDR1
PHA
RTS
*
*``````````````````````````````*
* __W: WAIT FOR KEYPRESS *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
__W
JSR $FD0C
RTS
*
********************************
* *
* GLOBAL VARIABLES *
* *
********************************
*
** 256 BYTES DEDICATED TO RETURN
** VALUES OF VARIABLE LENGTH; CAN BE
** MODIFIED TO SUIT SMALLER OR LARGER
** NEEDS.
*
*
RETLEN DS 1 ; RETURN VALUE BYTE LENGTH
RETURN DS 256
*
** 256 BYTE VALUE DEDICATED TO LARGE
** OR VARIABLE LENGTH PARAMETERS. THIS
** CAN ALSO BE CHANGED TO FIT SMALLER OR
** LARGER BOUNDS.
*
PARLEN DS 1
PARAM DS 256
*
ENDVARS
*

View File

@ -0,0 +1,358 @@
__GETRET
LDY #255
PLA
STA ADDR1
PLA
STA ADDR1+1
:LP
INY
LDA RETURN,Y
STA (ADDR1),Y
CPY RETLEN
BNE :LP
LDA ADDR1+1
PHA
LDA ADDR1
PHA
RTS
__SETPARM
LDY #255
PLA
STA ADDR1
PLA
STA ADDR1+1
:LP
INY
LDA (ADDR1),Y
STA PARAM,Y
CPY PARLEN
BNE :LP
LDA ADDR1+1
PHA
LDA ADDR1
PHA
RTS
__DUMP
PLA
STA :RET
PLA
STA :RET+1
PLA
STA :LENGTH
PLA
STA ADDR3
PLA
STA ADDR3+1
LDA #$8D
JSR $FDF0
LDA ADDR3+1
AND #$F0
LSR
LSR
LSR
LSR
TAX
LDA HEXTAB,X
JSR $FDF0
LDA ADDR3+1
AND #$0F
TAX
LDA HEXTAB,X
JSR $FDF0
LDA ADDR3
AND #$F0
LSR
LSR
LSR
LSR
TAX
LDA HEXTAB,X
JSR $FDF0
LDA ADDR3
AND #$0F
TAX
LDA HEXTAB,X
JSR $FDF0
LDA #186 ; :
JSR $FDF0
LDA #160 ; SPC
JSR $FDF0
LDY #0
:LP
LDA (ADDR3),Y
AND #$F0 ; MASK RIGHT
LSR
LSR
LSR
LSR
STA :LEFT
LDA (ADDR3),Y
AND #$0F ; MASK LEFT
STA :RIGHT
LDX :LEFT
LDA HEXTAB,X
JSR $FDF0
LDX :RIGHT
LDA HEXTAB,X
JSR $FDF0
LDA #160
JSR $FDF0
INY
CPY :LENGTH
BNE :LP
LDA :RET+1
PHA
LDA :RET
PHA
RTS
:RET DS 2
:RIGHT DS 1
:LEFT DS 1
:LENGTH DS 1
__P
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #1
:LP LDA (ADDR1),Y
BEQ :DONE
JSR $FDF0
INY
BNE :LP
:DONE CLC
TYA
ADC ADDR1
STA ADDR1
LDA ADDR1+1
ADC #0
PHA
LDA ADDR1
PHA
RTS
__W
JSR $FD0C
RTS
__RSAV
STA ERRA
STX ERRX
STY ERRY
:C BCC :C0
BCS :C1
:Z BEQ :Z1
BNE :Z0
:N BMI :N1
BPL :N0
:O BVC :O0
BVS :O1
JMP :EXIT
:C0 LDA #0
STA ERRCARRY
JMP :Z
:C1 LDA #1
STA ERRCARRY
JMP :Z
:Z1 LDA #1
STA ERRZERO
JMP :N
:Z0 LDA #0
STA ERRZERO
JMP :N
:N1 LDA #1
STA ERRNEG
JMP :O
:N0 LDA #0
STA ERRNEG
JMP :O
:O0 LDA #0
STA ERROVF
JMP :EXIT
:O1 LDA #1
STA ERROVF
:EXIT
RTS
__RDMP
_PRNT " ",8D8D
_PRNT "REGISTRY DUMP",8D
_PRNT "=============",8D
_PRNT "A: "
LDA ERRA
AND #$F0 ; MASK RIGHT
LSR
LSR
LSR
LSR
STA :LEFT
LDA ERRA
AND #$0F ; MASK LEFT
STA :RIGHT
LDX :LEFT
LDA HEXTAB,X
JSR $FDF0
LDX :RIGHT
LDA HEXTAB,X
JSR $FDF0
_PRNT " ",8D
_PRNT "X: "
LDA ERRX
AND #$F0 ; MASK RIGHT
LSR
LSR
LSR
LSR
STA :LEFT
LDA ERRX
AND #$0F ; MASK LEFT
STA :RIGHT
LDX :LEFT
LDA HEXTAB,X
JSR $FDF0
LDX :RIGHT
LDA HEXTAB,X
JSR $FDF0
_PRNT " ",8D
_PRNT "Y: "
LDA ERRY
AND #$F0 ; MASK RIGHT
LSR
LSR
LSR
LSR
STA :LEFT
LDA ERRY
AND #$0F ; MASK LEFT
STA :RIGHT
LDX :LEFT
LDA HEXTAB,X
JSR $FDF0
LDX :RIGHT
LDA HEXTAB,X
JSR $FDF0
_PRNT " ",8D8D
_PRNT "STATUS FLAGS",8D
_PRNT "============",8D8D
LDA #0
CMP ERRCARRY
BEQ :CARCLR
_PRNT "CARRY: SET",8D
JMP :TESTN
:CARCLR _PRNT "CARRY: CLEAR",8D
:TESTN LDA #0
CMP ERRNEG
BEQ :NEGCLR
_PRNT "NEGATIVE: SET",8D
JMP :TESTZ
:NEGCLR _PRNT "NEGATIVE: CLEAR",8D
:TESTZ LDA #0
CMP ERRZERO
BEQ :ZCLR
_PRNT "ZERO: SET",8D
JMP :TESTO
:ZCLR _PRNT "ZERO: CLEAR",8D
:TESTO
LDA #0
CMP ERROVF
BEQ :OCLR
_PRNT "OVERFLOW: SET",8D
JMP :FIN
:OCLR _PRNT "OVERFLOW: CLEAR",8D8D8D
:FIN
RTS
:LEFT DS 1
:RIGHT DS 1
HEXTAB ASC "0123456789ABCDEF"
__ERR
JSR __RSAV
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :DUMPLEN ; LENGTH OF DUMP
PLA
STA :DUMP ; DUMP ADDRESS LO
PLA
STA :DUMP+1 ; DUMP HI
PLA
STA :DMPMSG
PLA
STA :DMPMSG+1
PLA
STA :MESG ; ERROR MESSAGE ADDR LO
PLA
STA :MESG+1 ; HI
PLA
STA :SRID ; SUBROUTINE ID ADDR LO
PLA
STA :SRID+1 ; SUB ID HI
_PRNT " ",87878787878D8D
_PRNT "ERROR!",8D8D
_PRNT "SUBROUTINE: "
LDY #0
LDA :SRID
STA ADDR1
LDA :SRID+1
STA ADDR1+1
:LP1
LDA (ADDR1),Y
BEQ :LPX1
JSR $FDF0
INY
BNE :LP1
:LPX1
_PRNT " ",8D
_PRNT "MESSAGE: "
LDY #0
LDA :MESG
STA ADDR1
LDA :MESG+1
STA ADDR1+1
:LP2
LDA (ADDR1),Y
BEQ :LPX2
JSR $FDF0
INY
BNE :LP2
:LPX2
_PRNT " ",8D8D
_WAIT
LDY #0
LDA :DMPMSG
STA ADDR1
LDA :DMPMSG+1
STA ADDR1+1
:LP3
LDA (ADDR1),Y
BEQ :LPX3
JSR $FDF0
INY
BNE :LP3
:LPX3
_PRNT " ",8D
LDA :DUMP+1
PHA
LDA :DUMP
PHA
LDA :DUMPLEN
PHA
JSR __DUMP
_WAIT
LDA RETADR+1
PHA
LDA RETADR
PHA
_PRNT " ",8D8D
_WAIT
_RDUMP
_WAIT
LDA ERRSTOP
CMP #1
BEQ :KILL
RTS
:KILL
JMP $3D0
:DUMPLEN DS 1
:DUMP DS 2
:DMPMSG DS 2
:MESG DS 2
:SRID DS 2

View File

@ -1,134 +0,0 @@
********************************
* *
********************************
*
*``````````````````````````````*
* REQUIRED.MAC *
*- -*
* MACROS USED FOR CORE UTILS *
* AND LIBRARY ROUTINES. NOTE *
* THAT THE LIBRARIES DO NOT *
* USE THESE MACROS, BUT MAY *
* USE THE ROUTINES. THESE ARE *
* MERELY PROVIDED FOR THE SAKE *
* OF CONVENIENCE. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
*``````````````````````````````*
* _ISLIT: DETERMINES WHETHER A *
* PARAM IS LITERAL OR *
* NOT, AND CHANGES *
* APPROPRIATELY. FOR *
* MACRO USE ONLY. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_ISLIT MAC
IF #=]1 ; IF ]1 IS A LITERAL
LDA ]1/$100 ; GET HI
PHA
LDA ]1 ; GET LO
PHA
ELSE ; ]1 IS ADDRESS
LDA ]1+1 ; SO GET HIGH VAL FROM ADDR
PHA
LDA ]1 ; THEN LO VAL
PHA
FIN
<<<
*
*``````````````````````````````*
* _ISSTR: DETERMINES WHETHER A *
* PARAM IS A STRING OR *
* NOT, AND CHANGES *
* APPROPRIATELY. FOR *
* MACRO USE ONLY. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_ISSTR MAC
IF "=]1 ; IF ]1 IS A STRING
*
** STORE STRING AT TEMP ADDRESS, THEN
** PUSH TEMP ADDRESS
*
JMP STRCONT
]STRTMP STR ]1
STRCONT
LDY #0
LDA ]STRTMP
STA PARLEN
STA PARAM
]STRLP1
INY
LDA ]STRTMP,Y
STA PARAM,Y
CPY PARLEN
BNE ]STRLP1
*
LDA #>PARAM ; GET HI
PHA
LDA #<PARAM ; GET LO
PHA
ELSE ; ]1 IS ADDRESS
LDA #>]1 ; SO GET HIBYTE OF ADDR
PHA
LDA #<]1 ; THEN LOBYTE
PHA
FIN
<<<
*
*``````````````````````````````*
* _GRET: GET RETURN VALUE *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_GRET MAC
LDA #>]1
PHA
LDA #<]1
PHA
JSR __GETRET
<<<
*
*``````````````````````````````*
* _SPAR: SET PARAMETER *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_SPAR MAC
LDA #>]1
PHA
LDA #<]1
PHA
JSR __SETPARM
<<<
*
*``````````````````````````````*
* _DUMP: DUMP DATA *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_DUMP MAC
LDA #>]1
PHA
LDA #<]1
PHA
LDA ]2
PHA
JSR __DUMP
<<<
*
*``````````````````````````````*
* _PRNT: PRINT STRING *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_PRNT MAC
JSR __P
ASC ]1
HEX 00
<<<
*
*``````````````````````````````*
* _WAIT: WAIT FOR KEYPRESS *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_WAIT MAC
JSR __W
<<<
*

View File

@ -0,0 +1,94 @@
_ISLIT MAC
IF #=]1 ; IF ]1 IS A LITERAL
LDA ]1/$100 ; GET HI
PHA
LDA ]1 ; GET LO
PHA
ELSE ; ]1 IS ADDRESS
LDA ]1+1 ; SO GET HIGH VAL FROM ADDR
PHA
LDA ]1 ; THEN LO VAL
PHA
FIN
<<<
_ISSTR MAC
IF "=]1 ; IF ]1 IS A STRING
JMP STRCONT
]STRTMP STR ]1
STRCONT
LDY #0
LDA ]STRTMP
STA PARLEN
STA PARAM
]STRLP1
INY
LDA ]STRTMP,Y
STA PARAM,Y
CPY PARLEN
BNE ]STRLP1
LDA #>PARAM ; GET HI
PHA
LDA #<PARAM ; GET LO
PHA
ELSE ; ]1 IS ADDRESS
LDA #>]1 ; SO GET HIBYTE OF ADDR
PHA
LDA #<]1 ; THEN LOBYTE
PHA
FIN
<<<
_GRET MAC
LDA #>]1
PHA
LDA #<]1
PHA
JSR __GETRET
<<<
_SPAR MAC
LDA #>]1
PHA
LDA #<]1
PHA
JSR __SETPARM
<<<
_DUMP MAC
LDA #>]1
PHA
LDA #<]1
PHA
LDA ]2
PHA
JSR __DUMP
<<<
_PRNT MAC
JSR __P
ASC ]1
HEX 00
<<<
_WAIT MAC
JSR __W
<<<
_RDUMP MAC
JSR __RDMP
<<<
_ERR MAC
LDA #>]1
PHA
LDA #<]1
PHA
LDA #>]2
PHA
LDA #<]2
PHA
LDA #>]3
PHA
LDA #<]3
PHA
LDA #>]4
PHA
LDA #<]4
PHA
LDA ]5
PHA
JSR __ERR
<<<

View File

@ -0,0 +1,72 @@
*
********************************
* *
* VARIABLES AND SETTINGS *
* *
********************************
*
* VARIABLE DECLARATIONS ********
*
** JUMP TABLE SETUP. THIS IS FOR LOADING
** SUBROUTINES INTO MEMORY FOR ACCESS BY
** EXTERNAL EXECUTIONS. NOTE THAT THIS
** SHOULD ALWAYS BE THE VERY FIRST BIT OF
** CODE IN THE PROGRAM SO THAT ITS
** LOCATION IN MEMORY IS EASILY KNOWN.
*
JUMPTBL JMP MAIN_START ; ** ALWAYS ** START WITH
; JUMP TO MAIN_START
DS 60 ; 20 MORE ENTRIES
*
** 256 BYTES DEDICATED TO RETURN
** VALUES OF VARIABLE LENGTH; CAN BE
** MODIFIED TO SUIT SMALLER OR LARGER
** NEEDS.
*
RETLEN DS 1 ; RETURN VALUE BYTE LENGTH
RETURN DS 256
*
** 256 BYTE VALUE DEDICATED TO LARGE
** OR VARIABLE LENGTH PARAMETERS. THIS
** CAN ALSO BE CHANGED TO FIT SMALLER OR
** LARGER BOUNDS.
*
PARLEN DS 1
PARAM DS 256
*
** ERROR HANDLING
*
ERRSTOP DS 1
ERRCTRL DS 1
ERRA DS 1
ERRX DS 1
ERRY DS 1
ERRCARRY DS 1
ERRNEG DS 1
ERRZERO DS 1
ERROVF DS 1
*
* SETTINGS *********************
*
MAIN_START
*
** ERROR HANDLING
*
** SET ERRSTOP TO 1 IF YOU WANT THE PROGRAM TO
** HALT WHEN AN ERROR IS CAUGHT
*
LDA #1
STA ERRSTOP
*
** SET ERRCTRL TO 1 IF YOU WANT ERROR CATCHING ON
** IN THE FIRST PLACE. HAVING THIS TURNED OFF WILL
** SAVE A FEW CYCLES, BUT POSSIBLY AT THE EXPENSE
** OF YOUR FRUSTRATION. CAN BE TURNED ON LATER THOUGH.
*
LDA #1
STA ERRCTRL
*
*
*
*
*

View File

@ -1,105 +0,0 @@
*
STR2NUM
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #0
LDA (ADDR1),Y
TAX
LDA #1
STA :NINDEX
LDA #0
STA :NACCUM
STA :NACCUM+1
STA :SNGFLAG
TXA
BNE :INIT1
JMP :EREXIT
:INIT1
LDY :NINDEX
LDA (ADDR1),Y
CMP #173
BNE :PLUS
LDA #$0FF
STA :SNGFLAG
INC :NINDEX
DEX
BEQ :EREXIT
JMP :CNVERT
:PLUS
CMP #'+'
BNE :CHKDIG
INC :NINDEX
DEX
BEQ :EREXIT
:CNVERT
LDY :NINDEX
LDA (ADDR1),Y
:CHKDIG
CMP #$B0 ; "0"
BMI :EREXIT
CMP #$BA
BPL :EREXIT
PHA
ASL :NACCUM
ROL :NACCUM+1
LDA :NACCUM
LDY :NACCUM+1
ASL :NACCUM
ROL :NACCUM+1
ASL :NACCUM
ROL :NACCUM+1
CLC
ADC :NACCUM
STA :NACCUM
TYA
ADC :NACCUM+1
STA :NACCUM+1
PLA
SEC
SBC #$B0
CLC
ADC :NACCUM
STA :NACCUM
BCC :D2B1
INC :NACCUM+1
:D2B1
INC :NINDEX
DEX
BNE :CNVERT
LDA :SNGFLAG
BPL :OKEXIT
LDA #0
SEC
SBC :NACCUM
STA :NACCUM
LDA #0
SBC :NACCUM+1
STA :NACCUM+1
:OKEXIT
CLC
BCC :EXIT
:EREXIT
SEC
:EXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
LDX :NACCUM+1
LDY :NACCUM
STY RETURN
STX RETURN+1
LDA #2
STA RETLEN
LDA :NINDEX
RTS
:NACCUM DS 2
:SNGFLAG DS 1
:NINDEX DS 1

View File

@ -1,4 +1,3 @@
*
*``````````````````````````````*
* STR2NUM :: STRING TO NUMBER *
*- -*
@ -166,6 +165,26 @@ STR2NUM
BCC :EXIT
:EREXIT
SEC
*
********************************
*
* ERROR CONTROL
*
********************************
*
LDA ERRCTRL
CMP #1
BEQ :CHKERR
JMP :ERREND
:CHKERR
_ERR :E_SID;:E_MSG;:E_DUMP;:NACCUM;#4
*
********************************
*
:ERREND
*
********************************
*
:EXIT
*
** RESTORE RETURN ADDRESS
@ -191,3 +210,6 @@ STR2NUM
:SNGFLAG DS 1
:NINDEX DS 1
*
:E_SID ASC "STR2NUM (S2N MACRO)",00
:E_MSG ASC "ERR! NO DATA, OR NOT A NUMERAL VALUE",00
:E_DUMP ASC "DUMPING :NACCUM(2) :SNGFLAG(1) :NINDEX(1)",00

View File

@ -0,0 +1,118 @@
STR2NUM
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA ADDR1 ; ADRESS OF STRING
PLA ; TO CNVERT
STA ADDR1+1
LDY #0
LDA (ADDR1),Y
TAX ; GET LENGITH; TO REGX
LDA #1
STA :NINDEX ; INDEX = 1
LDA #0
STA :NACCUM ; ACCUM = 0
STA :NACCUM+1
STA :SNGFLAG ; SIGN IS POSITIVE
TXA
BNE :INIT1 ; EXIT WITH ACCUM = 0
; IF BUFFER IS EMPTY
JMP :EREXIT ; ERROR EXIT IF NOTHING
; IN BUFFER
:INIT1
LDY :NINDEX
LDA (ADDR1),Y
CMP #173
BNE :PLUS ; BR IF NOT -
LDA #$0FF
STA :SNGFLAG ; ELSE SIGN IS NEGATIVE
INC :NINDEX
DEX ; DECREMENT COUNT
BEQ :EREXIT ; ERROR EXIT IF ONLY
; - IN BUFFER
JMP :CNVERT
:PLUS
CMP #'+'
BNE :CHKDIG ; START CONVERSION IF 1ST
INC :NINDEX
DEX ; DEC COUNT; IGNORE + SIGN
BEQ :EREXIT ; ERROR EXIT IF ONLY
; + IN THE BUFFER
:CNVERT
LDY :NINDEX
LDA (ADDR1),Y
; GET NEXT CHAR
:CHKDIG
CMP #$B0 ; "0"
BMI :EREXIT ; ERROR IF NOT A NUMERAL
CMP #$BA ; '9'+1; TECHNICALLY :
BPL :EREXIT ; ERR IF > 9 (NOT NUMERAL)
PHA ; PUSH DIGIT TO STACK
ASL :NACCUM
ROL :NACCUM+1 ; TIMES 2
LDA :NACCUM
LDY :NACCUM+1 ; SAVE ACCUM * 2
ASL :NACCUM
ROL :NACCUM+1
ASL :NACCUM
ROL :NACCUM+1 ; TIMES 8
CLC
ADC :NACCUM ; SUM WITH * 2
STA :NACCUM
TYA
ADC :NACCUM+1
STA :NACCUM+1 ; ACCUM=ACCUM * 10
PLA ; GET THE DIGIT NACK
SEC
SBC #$B0
CLC ; CONVERT STR TO BIN
ADC :NACCUM
STA :NACCUM
BCC :D2B1 ; BRANCH IF NO CARRY TO HBYTE
INC :NACCUM+1 ; ELSE INC HIGH BYTE
:D2B1
INC :NINDEX ;INC TO NEXT CHARACTER
DEX
BNE :CNVERT ; CONTINUE CONVERSION
LDA :SNGFLAG
BPL :OKEXIT ; BR IF VAL IS POSITIVE
LDA #0 ; ELSE REPLACE WITH -RESULT
SEC
SBC :NACCUM
STA :NACCUM
LDA #0
SBC :NACCUM+1
STA :NACCUM+1
:OKEXIT
CLC
BCC :EXIT
:EREXIT
SEC
LDA ERRCTRL
CMP #1
BEQ :CHKERR
JMP :ERREND
:CHKERR
_ERR :E_SID;:E_MSG;:E_DUMP;:NACCUM;#4
:ERREND
:EXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
LDX :NACCUM+1
LDY :NACCUM
STY RETURN
STX RETURN+1
LDA #2
STA RETLEN
LDA :NINDEX
RTS
:NACCUM DS 2
:SNGFLAG DS 1
:NINDEX DS 1
:E_SID ASC "STR2NUM (S2N MACRO)",00
:E_MSG ASC "ERR! NO DATA, OR NOT A NUMERAL VALUE",00
:E_DUMP ASC "DUMPING :NACCUM(2) :SNGFLAG(1) :NINDEX(1)",00

View File

@ -1,96 +0,0 @@
*
STRCAT
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :MLEN
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #0
LDA (ADDR1),Y
STA :S1LEN
STA :S1IND
INC :S1IND
LDA (ADDR2),Y
STA :S2LEN
LDA #1
STA :S2IND
LDA :S2LEN
CLC
ADC :S1LEN
STA :S3LEN
BCS :TOOLONG
CMP :MLEN
BEQ :LENOK
BCC :LENOK
:TOOLONG
LDA #$0FF
STA :SOVF
LDA :MLEN
SEC
SBC :S1LEN
BCC :EXIT
STA :SCNT
LDA :MLEN
STA :S1LEN
JMP :DOCAT
:LENOK
STA :S1LEN
LDA #0
STA :SOVF
LDA :S2LEN
STA :SCNT
:DOCAT
LDA :SCNT
BEQ :EXIT
:CATLP
LDY :S2IND
LDA (ADDR2),Y
LDY :S1IND
STA (ADDR1),Y
INC :S1IND
INC :S2IND
DEC :SCNT
BNE :CATLP
:EXIT
LDA :S1LEN
LDY #0
STA (ADDR1),Y
LDA :SOVF
ROR A
LDA RETADR+1
PHA
LDA RETADR
PHA
LDY #0
LDA (ADDR1),Y
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
RTS
:S3LEN DS 1
:S1LEN DS 1
:S1IND DS 1
:S2LEN DS 1
:S2IND DS 1
:MLEN DS 1
:SCNT DS 1
:SOVF DS 1

View File

@ -1,4 +1,3 @@
*
*``````````````````````````````*
* STRCAT :: STRING CONCATENATE *
*- -*

View File

@ -0,0 +1,94 @@
STRCAT
PLA
STA RETADR
PLA
STA RETADR+1
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
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
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
:TOOLONG
LDA #$0FF
STA :SOVF ; INDICATE OVERFLOW
LDA :MLEN
SEC
SBC :S1LEN
BCC :EXIT
STA :SCNT ; ORIG STR WAS TOO LONG
LDA :MLEN
STA :S1LEN ; SET STR1 LENGTH TO MAX
JMP :DOCAT
:LENOK
STA :S1LEN
LDA #0 ; SAVE SUM OF 2 LENGTHS
STA :SOVF ; INDICATE NO OVERFLOW
LDA :S2LEN
STA :SCNT ; COUNT = LENGTH OF STRING 2
: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
LDA :S1LEN
LDY #0
STA (ADDR1),Y
LDA :SOVF
ROR A
LDA RETADR+1
PHA
LDA RETADR
PHA
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
:S3LEN DS 1
:S1LEN DS 1
:S1IND DS 1
:S2LEN DS 1
:S2IND DS 1
:MLEN DS 1
:SCNT DS 1
:SOVF DS 1

View File

@ -1,46 +0,0 @@
*
STRCMP
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #0
LDA (ADDR1),Y
CMP (ADDR2),Y
BCC :BEGCMP
LDA (ADDR2),Y
:BEGCMP
TAX
BEQ :TSTLEN
LDY #1
:CMPLP
LDA (ADDR1),Y
CMP (ADDR2),Y
BNE :EXIT
INY
DEX
BNE :CMPLP
:TSTLEN
LDY #0
LDA (ADDR1),Y
CMP (ADDR2),Y
:EXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
LDY #0
LDA (ADDR1),Y
TAX
LDA (ADDR2),Y
TAY
RTS

View File

@ -1,4 +1,3 @@
*
*``````````````````````````````*
* STRCMP :: STRING COMPARE *
*- -*

View File

@ -0,0 +1,47 @@
STRCMP
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #0
LDA (ADDR1),Y ; GET LENGTH OF STRING 1
CMP (ADDR2),Y
BCC :BEGCMP ; IF STRING 2 IS SHORTER THEN
LDA (ADDR2),Y ; USE ITS LENGTH INSTEAD
:BEGCMP
TAX ; X IS LENGTH OF SHORTER STRING
BEQ :TSTLEN ; BR IF LENGTH IS 0
LDY #1 ; POINT AT FIRST CHAR OF STRINGS
:CMPLP
LDA (ADDR1),Y
CMP (ADDR2),Y
BNE :EXIT ; BR IF CHARS NOT EQUAL
; Z,C WILL BE PROPERLY SET
; OR CLEARED
; ELSE
INY ; NEXT CHAR
DEX ; DECREMENT COUNTER
BNE :CMPLP ; CONTINUE UNTIL ALL BYTES PAIRED
:TSTLEN
LDY #0 ; COMPARE LENGTHS
LDA (ADDR1),Y
CMP (ADDR2),Y ; SET OR CLEAR THE FLAGS
:EXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
LDY #0
LDA (ADDR1),Y ; GET STR1 LENGTH
TAX ; RETURN IN X
LDA (ADDR2),Y ; STR2 LENGTH
TAY ; RETURN IN Y
RTS

View File

@ -3,9 +3,9 @@
* *
* -< STRINGS DEMO >- *
* *
* VERSION 00.02.00 *
* VERSION 00.03.00 *
* *
* 21-DEC-2018 *
* 20-JAN-2019 *
* *
********************************
* *
@ -17,9 +17,9 @@
** ASSEMBLER DIRECTIVES
*
CYC AVE
TR ON
EXP ONLY
DSK STRINGS.DEMO
*
OBJ $BFE0
ORG $6000
*
@ -27,10 +27,10 @@
* TOP INCLUDES (PUTS, MACROS) *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
USE REQUIRED.MAC
PUT REQUIRED.HOOKS
*
USE STRINGS.MAC
PUT REQUIRED.VARS
USE REQUIRED.MAC.MIN
PUT REQUIRED.HOOKS.MIN
USE STRINGS.MAC.MIN
PUT STRINGS.HOOKS
*
*
@ -193,16 +193,32 @@ CONT2
*
JMP REENTRY
*
ASTR STR "A"
BSTR STR "B"
LSTR STR "THIS IS A STRING."
*
*``````````````````````````````*
* BOTTOM INCLUDES *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** BOTTOM INCLUDES
*
PUT STRINGS.LIB
PUT SUBSTRINGS.LIB
PUT REQUIRED.LIB
PUT REQUIRED.LIB.MIN
*
** INDIVIDUAL SUBROUTINE INCLUDES
*
** STRING SUBROUTINES
*
PUT NUM2STR.SUB.MIN
PUT PRNSTR.SUB.MIN
PUT STRCAT.SUB.MIN
PUT STRCOMP.SUB.MIN
PUT STR2NUM.SUB.MIN
*
** SUBSTRING SUBROUTINES
*
PUT SUBCOPY.SUB.MIN
PUT SUBDEL.SUB.MIN
PUT SUBINS.SUB.MIN
PUT SUBPOS.SUB.MIN
*
ASTR STR "A"
BSTR STR "B"
LSTR STR "THIS IS A STRING."

View File

@ -1,853 +0,0 @@
*
JMP STRINGSX
*
*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*
* *
* STRINGS ROUTINE LIBRARY *
* *
* AUTHOR: NATHAN RIGGS *
* CONTACT: NATHAN.RIGGS@ *
* OUTLOOK.COM *
* *
* VERSION: 0.2.0 *
* DATE: 30-OCT-2018 *
* ASSEMBLER: MERLIN 8 PRO *
* OS: DOS 3.3 *
* LICENSE: APACHE 2.0 *
* *
* THIS IS A STANDARD LIBRARY *
* FOR STRING MANIPULATION. *
* *
*------------------------------*
* *
* LIST OF ROUTINES *
* *
* STRCOMP : STRING COMPARE *
* STRCAT : CONCATENATE STRING *
* PRNSTR : PRINT STRING *
* NUM2STR : NUMBER TO STRING *
* STR2NUM : STRING TO NUMBER *
* *
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*
*
*``````````````````````````````*
* STRCMP :: STRING COMPARE *
*- -*
* COMPARE TWO STRINGS AND *
* DETERMINE IF THEY ARE *
* IDENTICAL; IF NOT, DETERMINE *
* WHICH IS THE SHORTEST AND *
* WHICH IS THE LONGEST. *
* *
* Z FLAG = 1 IF IDENTICAL *
* Z FLAG = 0 IF NOT *
* CARRY = 1 IF STR2 > STR1 LEN *
* CARRY = 0 IF STR1 > STR2 LEN *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>STR1 *
* PHA *
* LDA #<STR1 *
* PHA *
* LDA #>STR2 *
* PHA *
* LDA #<STR2 *
* PHA *
* JSR STRCMP *
* *
* STR1 STR "STRING1 " *
* STR2 STR "ZTRING2" *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* STRING 2 ADDRESS LOW BYTE *
* STRING 2 ADDRESS HI BYTE *
* STRING 1 ADDRESS LOW BYTE *
* STRING 1 ADDRESS HI BYTE *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
* .Y = LENGTH OF STRING 2 *
* .X = LENGTH OF STRING 1 *
* .A = CLOBBERED; TRASH *
*- -*
* ADAPTED FROM LEVANTHAL AND *
* WINTHROP'S /6502 ASSEMBLY *
* LANGUAGE ROUTINES/. MAY NOT *
* FALL UNDER APACHE 2.0 UNTIL *
* SUBSTANTIALLY ALTERED. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
STRCMP
*
** SAVE RETURN ADDRESS
*
PLA
STA RETADR
PLA
STA RETADR+1
*
** GET PARAMETERS
*
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
*
LDY #0
LDA (ADDR1),Y ; GET LENGTH OF STRING 1
CMP (ADDR2),Y
BCC :BEGCMP ; IF STRING 2 IS SHORTER THEN
LDA (ADDR2),Y ; USE ITS LENGTH INSTEAD
*
** COMPARE THE STRINGS THROUGH THE
** LENGTH OF THE SHORTER STRING
*
:BEGCMP
TAX ; X IS LENGTH OF SHORTER STRING
BEQ :TSTLEN ; BR IF LENGTH IS 0
LDY #1 ; POINT AT FIRST CHAR OF STRINGS
:CMPLP
LDA (ADDR1),Y
CMP (ADDR2),Y
BNE :EXIT ; BR IF CHARS NOT EQUAL
; Z,C WILL BE PROPERLY SET
; OR CLEARED
; ELSE
INY ; NEXT CHAR
DEX ; DECREMENT COUNTER
BNE :CMPLP ; CONTINUE UNTIL ALL BYTES PAIRED
*
* THE 2 STRINGS ARE EQUAL TO LENGTH OF THE SHORTER
* SO USE LENGTHS AS BASIS FOR SETTING THE FLAGS
*
:TSTLEN
LDY #0 ; COMPARE LENGTHS
LDA (ADDR1),Y
CMP (ADDR2),Y ; SET OR CLEAR THE FLAGS
*
** Z FLAG = 1 IF STRINGS IDENTICAL
** Z FLAG = 0 IF NOT IDENTICAL
** CARRY = 0 IF STR2 LENGTH > STR1 LENGTH
** CARRY = 1 IF STR1 LENGTH >= STR2 LENGTH
*
:EXIT
*
** RESTORE RETURN ADDRESS
*
LDA RETADR+1
PHA
LDA RETADR
PHA
*
LDY #0
LDA (ADDR1),Y ; GET STR1 LENGTH
TAX ; RETURN IN X
LDA (ADDR2),Y ; STR2 LENGTH
TAY ; RETURN IN Y
*
RTS
*
*``````````````````````````````*
* 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
*
*``````````````````````````````*
* PRNSTR :: PRINT INDEXED STR *
*- -*
* PRINT A STRING WITH LENGTH *
* THAT PRECEDES START OF STR *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>STR ; STRING ADDRESS *
* PHA *
* LDA #<STR *
* PHA *
* JSR PRNSTR *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* LOW BYTE OF STRING ADDRESS *
* HIGH BYTE OF STRING ADDRESS *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
* .Y = LOW BYTE STRING ADDR *
* .X = HI BYTE STRING ADDR *
* .A = STRING LENGTH *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
PRNSTR
*
** SAVE RETURN ADDRESS
*
PLA
STA RETADR
PLA
STA RETADR+1
*
** GET PARAMETERS
*
PLA
STA ADDR1 ; ADDRESS OF STRING
PLA
STA ADDR1+1
*
LDY #0
LDA (ADDR1),Y ; GET STRING LENGTH
STA :S1LEN
:LP
INY
LDA (ADDR1),Y ; GET CHARACTER
JSR SCOUT1 ; PRINT CHARACTER TO SCREEN
CPY :S1LEN ; IF Y < LENGTH
BNE :LP
; LOOP; ELSE
LDY #0
LDA (ADDR1),Y
*
** RESTORE RETURN ADDRESS
*
LDA RETADR+1
PHA
LDA RETADR
PHA
*
LDY #0
LDA (ADDR1),Y ; STRING LENGTH IN A
LDY ADDR1
LDX ADDR1+1 ; ADDRESS IN Y,X
*
RTS
*
** DATA
*
:S1LEN DS 1
*
*``````````````````````````````*
* NUM2STR :: NUMBER TO STRING *
*- -*
* CONVERTS A 16-BIT NUMBER TO *
* ITS STRING EQUIVALENT. *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>11111 ; VALUE TO *
* PHA ; CONVERT *
* LDA #<11111 *
* PHA *
* JSR NUM2STR *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* LO BYTE VALUE TO CONVERT *
* HI BYTE VALUE TO CONVERT *
*- -*
* 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 *
* *
* [RETURN] = STRING VALUE *
* [RETLEN] = LENGTH OF STRING *
*- -*
* ADAPTED FROM LEVANTHAL AND *
* WINTHROP'S /6502 ASSEMBLY *
* LANGUAGE ROUTINES/. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
NUM2STR
*
** SAVE RETURN ADDRESS
*
PLA
STA RETADR
PLA
STA RETADR+1
*
** GET PARAMETERS
*
PLA
STA :VALSTR
PLA
STA :VALSTR+1
*
STA :NGFLAG
BPL :GETBP ; BR IF VAL IS POS
LDA #0
SEC
SBC :VALSTR
STA :VALSTR
LDA #0
SBC :VALSTR+1
STA :VALSTR+1
*
:GETBP
LDA #<RETURN
STA ADDR1 ; ADDRESS TO STORE STRING
LDA #>RETURN+1
STA ADDR1+1
LDA #0 ; SET BUFFER TO EMPTY
LDY #0
STA (ADDR1),Y ; BUFFER(0) = 0
*
** CONVERT VAL TO STRING
*
:CNVERT
*
** VALUE = VALUE DIV 10
** MOD10 = VALUE MOD 10
*
LDA #0
STA :MOD10
STA :MOD10+1
LDX #16
CLC ; CLEAR CARRY
*
:DVLOOP
ROL :VALSTR ; SHIFT CARRY INTO DIVBIT 0
ROL :VALSTR+1 ; WHICH WILL BE THE QUOTIENT
ROL :MOD10 ; + SHIFT DIV AT SAME TIME
ROL :MOD10+1
*
** A,Y = DIVIDEND - DIVISOR
*
SEC
LDA :MOD10
SBC #10
TAY ; SAVE LOWB IN REG Y
LDA :MOD10+1
SBC #0 ; SUBTRACT CARRY
BCC :DECCNT ; BR IF DEND < DIVISOR
STY :MOD10 ; ELSE
STA :MOD10+1 ; NXT BIT OF Q IS A ONE AND SET
; DIVIDEND = DEND - DIVISOR
:DECCNT
DEX
BNE :DVLOOP
ROL :VALSTR ; SHIFT IN LAST CARRY FOR Q
ROL :VALSTR+1
*
** CONCAT NEXT CHAR
*
:CONCH
LDA :MOD10
CLC
ADC #$B0
*
** ADC #'0' ; CONVERT 0..9 TO ASCII 0-9
*
JSR :CONCAT
*
** IF VALUE <> 0 THEN CONTINUE
*
LDA :VALSTR
ORA :VALSTR+1
BNE :CNVERT ; BR IF VALUE != 0
*
:EXIT
LDA :NGFLAG
BPL :POS ; BR IF ORIG VAL POS
LDA #173 ; ELSE
JSR :CONCAT ; PUT A MINUS SIGN IN FRONT
*
:POS
*
** RESTORE RETURN ADDRESS
*
LDA RETADR+1
PHA
LDA RETADR
PHA
*
RTS ; RETURN
*
********************************
* CONCAT SUBROUTINE
********************************
*
:CONCAT
PHA ; SAVE CHAR ON STACK
*
** MOVE BUFFER RIGHT ONE CHAR
*
LDY #0
LDA (ADDR1),Y ; GET CURRENT LENGTH
TAY
BEQ :EXITMR ; BR IF LENGTH=0
*
:MVELP
LDA (ADDR1),Y ; GET NEXT CHAR
INY
STA (ADDR1),Y ; STORE IT
DEY
DEY
BNE :MVELP ; CONT UNTIL DONE
*
:EXITMR
PLA ; GET CHAR BACK FROM STACK
LDY #1
STA (ADDR1),Y ; STORE THE CHAR
LDY #0
LDA (ADDR1),Y ; GET LENGTH BYTE
CLC
ADC #1 ; INC LENGTH BY ONE
STA (ADDR1),Y ; UPDATE LENGTH
*
RTS
*
** DATA
*
:NGFLAG DS 1
:VALSTR DS 2
:MOD10 DS 2
*
*``````````````````````````````*
* STR2NUM :: STRING TO NUMBER *
*- -*
* CONVERTS A STRING TO THE *
* EQUIVALENT 16BIT NUMBER. *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>$300 ; STRING ADDR *
* PHA *
* LDA #<$300 *
* PHA *
* JSR STR2NUM *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* LO BYTE OF STRING ADDRESS *
* HI BYTE OF STRING ADDRESS *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
* .Y = LO BYTE OF NUMBER *
* .X = HI BYTE OF NUMBER *
* .A = LOW BYTE OF RET ADDR *
* *
* [RETURN] = NUMBER VALUE WORD *
* [RETLEN] = 2 (NUM OF BYTES) *
*- -*
* ADAPTED FROM LEVANTHAL AND *
* WINTHROP'S /6502 ASSEMBLY *
* LANGUAGE ROUTINES/. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
STR2NUM
*
** SAVE RETURN ADDRESS
*
PLA
STA RETADR
PLA
STA RETADR+1
*
** GET PARAMETERS
*
PLA
STA ADDR1 ; ADRESS OF STRING
PLA ; TO CNVERT
STA ADDR1+1
*
** INITIALIZE
*
LDY #0
LDA (ADDR1),Y
TAX ; GET LENGITH; TO REGX
LDA #1
STA :NINDEX ; INDEX = 1
LDA #0
STA :NACCUM ; ACCUM = 0
STA :NACCUM+1
STA :SNGFLAG ; SIGN IS POSITIVE
*
** CHECK THAT BUFFER IS NOT ZERO
*
TXA
BNE :INIT1 ; EXIT WITH ACCUM = 0
; IF BUFFER IS EMPTY
JMP :EREXIT ; ERROR EXIT IF NOTHING
; IN BUFFER
:INIT1
LDY :NINDEX
LDA (ADDR1),Y
CMP #173
BNE :PLUS ; BR IF NOT -
LDA #$0FF
STA :SNGFLAG ; ELSE SIGN IS NEGATIVE
INC :NINDEX
DEX ; DECREMENT COUNT
BEQ :EREXIT ; ERROR EXIT IF ONLY
; - IN BUFFER
JMP :CNVERT
:PLUS
CMP #'+'
BNE :CHKDIG ; START CONVERSION IF 1ST
; CHARACTER IS NOT A +
INC :NINDEX
DEX ; DEC COUNT; IGNORE + SIGN
BEQ :EREXIT ; ERROR EXIT IF ONLY
; + IN THE BUFFER
:CNVERT
LDY :NINDEX
LDA (ADDR1),Y
; GET NEXT CHAR
:CHKDIG
CMP #$B0 ; "0"
BMI :EREXIT ; ERROR IF NOT A NUMERAL
CMP #$BA ; '9'+1; TECHNICALLY :
BPL :EREXIT ; ERR IF > 9 (NOT NUMERAL)
PHA ; PUSH DIGIT TO STACK
*
** VALID DECIMAL DIGIT SO
** ACCUM = ACCUM * 10
** = * (8+2)
** = (ACCUM * 8) + (ACCUM * 2)
*
ASL :NACCUM
ROL :NACCUM+1 ; TIMES 2
LDA :NACCUM
LDY :NACCUM+1 ; SAVE ACCUM * 2
ASL :NACCUM
ROL :NACCUM+1
ASL :NACCUM
ROL :NACCUM+1 ; TIMES 8
CLC
ADC :NACCUM ; SUM WITH * 2
STA :NACCUM
TYA
ADC :NACCUM+1
STA :NACCUM+1 ; ACCUM=ACCUM * 10
*
** ADD IN THE NEXT DIGIT
** ACCUM = ACCUM + DIGIT
*
PLA ; GET THE DIGIT NACK
SEC
SBC #$B0
CLC ; CONVERT STR TO BIN
ADC :NACCUM
STA :NACCUM
BCC :D2B1 ; BRANCH IF NO CARRY TO HBYTE
INC :NACCUM+1 ; ELSE INC HIGH BYTE
:D2B1
INC :NINDEX ;INC TO NEXT CHARACTER
DEX
BNE :CNVERT ; CONTINUE CONVERSION
LDA :SNGFLAG
BPL :OKEXIT ; BR IF VAL IS POSITIVE
LDA #0 ; ELSE REPLACE WITH -RESULT
SEC
SBC :NACCUM
STA :NACCUM
LDA #0
SBC :NACCUM+1
STA :NACCUM+1
*
** GET THE BINARY VALUE AND RETURN
*
:OKEXIT
CLC
BCC :EXIT
:EREXIT
SEC
:EXIT
*
** RESTORE RETURN ADDRESS
*
LDA RETADR+1
PHA
LDA RETADR
PHA
*
LDX :NACCUM+1
LDY :NACCUM
STY RETURN
STX RETURN+1
LDA #2
STA RETLEN
LDA :NINDEX
*
RTS
*
** DATA
*
:NACCUM DS 2
:SNGFLAG DS 1
:NINDEX DS 1
*
STRINGSX
*

View File

@ -0,0 +1,65 @@
SCMP MAC
_ISSTR ]1
_ISSTR ]2
JSR STRCMP
<<<
SCAT MAC
_ISSTR ]1
_ISSTR ]2
LDA ]3 ; MAX SIZE; BYTE
PHA
JSR STRCAT
<<<
SPRN MAC
LDA #>]1 ; ADDRESS OF STRING
PHA
LDA #<]1
PHA
JSR PRNSTR
<<<
TOSTR MAC
_ISLIT ]1
JSR NUM2STR
<<<
TONUM MAC
_ISSTR ]1
JSR STR2NUM
<<<
SPOS MAC
_ISSTR ]1
_ISSTR ]2
JSR SUBPOS
<<<
SCPY MAC
_ISSTR ]1
LDA ]2 ; STARTING INDEX
PHA
LDA ]3 ; SUBSTRING LENGTH
PHA
LDA ]4 ; MAX LENGTH OF SUBSTR
PHA
JSR SUBCOPY
<<<
SDEL MAC
LDA #>]1 ; STRING ADDRESS
PHA
LDA #<]1
PHA
LDA ]2 ; INDEX BYTE
PHA
LDA ]3 ; LENGTH
PHA
JSR SUBDEL
<<<
SINS MAC
LDA #>]1 ; PARENT STRING
PHA
LDA #<]1
PHA
LDA ]2 ; INDEX
PHA
LDA ]3 ; MAXIMUM LENGTH
PHA
_ISSTR ]4
JSR SUBINS
<<<

View File

@ -1,379 +0,0 @@
JMP STRINGSX
*
STRCMP
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #0
LDA (ADDR1),Y
CMP (ADDR2),Y
BCC :BEGCMP
LDA (ADDR2),Y
:BEGCMP
TAX
BEQ :TSTLEN
LDY #1
:CMPLP
LDA (ADDR1),Y
CMP (ADDR2),Y
BNE :EXIT
INY
DEX
BNE :CMPLP
:TSTLEN
LDY #0
LDA (ADDR1),Y
CMP (ADDR2),Y
:EXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
LDY #0
LDA (ADDR1),Y
TAX
LDA (ADDR2),Y
TAY
RTS
*
STRCAT
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :MLEN
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #0
LDA (ADDR1),Y
STA :S1LEN
STA :S1IND
INC :S1IND
LDA (ADDR2),Y
STA :S2LEN
LDA #1
STA :S2IND
LDA :S2LEN
CLC
ADC :S1LEN
STA :S3LEN
BCS :TOOLONG
CMP :MLEN
BEQ :LENOK
BCC :LENOK
:TOOLONG
LDA #$0FF
STA :SOVF
LDA :MLEN
SEC
SBC :S1LEN
BCC :EXIT
STA :SCNT
LDA :MLEN
STA :S1LEN
JMP :DOCAT
:LENOK
STA :S1LEN
LDA #0
STA :SOVF
LDA :S2LEN
STA :SCNT
:DOCAT
LDA :SCNT
BEQ :EXIT
:CATLP
LDY :S2IND
LDA (ADDR2),Y
LDY :S1IND
STA (ADDR1),Y
INC :S1IND
INC :S2IND
DEC :SCNT
BNE :CATLP
:EXIT
LDA :S1LEN
LDY #0
STA (ADDR1),Y
LDA :SOVF
ROR A
LDA RETADR+1
PHA
LDA RETADR
PHA
LDY #0
LDA (ADDR1),Y
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
RTS
:S3LEN DS 1
:S1LEN DS 1
:S1IND DS 1
:S2LEN DS 1
:S2IND DS 1
:MLEN DS 1
:SCNT DS 1
:SOVF DS 1
*
PRNSTR
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #0
LDA (ADDR1),Y
STA :S1LEN
:LP
INY
LDA (ADDR1),Y
JSR SCOUT1
CPY :S1LEN
BNE :LP
LDY #0
LDA (ADDR1),Y
LDA RETADR+1
PHA
LDA RETADR
PHA
LDY #0
LDA (ADDR1),Y
LDY ADDR1
LDX ADDR1+1
RTS
:S1LEN DS 1
*
NUM2STR
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :VALSTR
PLA
STA :VALSTR+1
STA :NGFLAG
BPL :GETBP
LDA #0
SEC
SBC :VALSTR
STA :VALSTR
LDA #0
SBC :VALSTR+1
STA :VALSTR+1
:GETBP
LDA #<RETURN
STA ADDR1
LDA #>RETURN+1
STA ADDR1+1
LDA #0
LDY #0
STA (ADDR1),Y
:CNVERT
LDA #0
STA :MOD10
STA :MOD10+1
LDX #16
CLC
:DVLOOP
ROL :VALSTR
ROL :VALSTR+1
ROL :MOD10
ROL :MOD10+1
SEC
LDA :MOD10
SBC #10
TAY
LDA :MOD10+1
SBC #0
BCC :DECCNT
STY :MOD10
STA :MOD10+1
:DECCNT
DEX
BNE :DVLOOP
ROL :VALSTR
ROL :VALSTR+1
:CONCH
LDA :MOD10
CLC
ADC #$B0
JSR :CONCAT
LDA :VALSTR
ORA :VALSTR+1
BNE :CNVERT
:EXIT
LDA :NGFLAG
BPL :POS
LDA #173
JSR :CONCAT
:POS
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:CONCAT
PHA
LDY #0
LDA (ADDR1),Y
TAY
BEQ :EXITMR
:MVELP
LDA (ADDR1),Y
INY
STA (ADDR1),Y
DEY
DEY
BNE :MVELP
:EXITMR
PLA
LDY #1
STA (ADDR1),Y
LDY #0
LDA (ADDR1),Y
CLC
ADC #1
STA (ADDR1),Y
RTS
:NGFLAG DS 1
:VALSTR DS 2
:MOD10 DS 2
*
STR2NUM
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #0
LDA (ADDR1),Y
TAX
LDA #1
STA :NINDEX
LDA #0
STA :NACCUM
STA :NACCUM+1
STA :SNGFLAG
TXA
BNE :INIT1
JMP :EREXIT
:INIT1
LDY :NINDEX
LDA (ADDR1),Y
CMP #173
BNE :PLUS
LDA #$0FF
STA :SNGFLAG
INC :NINDEX
DEX
BEQ :EREXIT
JMP :CNVERT
:PLUS
CMP #'+'
BNE :CHKDIG
INC :NINDEX
DEX
BEQ :EREXIT
:CNVERT
LDY :NINDEX
LDA (ADDR1),Y
:CHKDIG
CMP #$B0 ; "0"
BMI :EREXIT
CMP #$BA
BPL :EREXIT
PHA
ASL :NACCUM
ROL :NACCUM+1
LDA :NACCUM
LDY :NACCUM+1
ASL :NACCUM
ROL :NACCUM+1
ASL :NACCUM
ROL :NACCUM+1
CLC
ADC :NACCUM
STA :NACCUM
TYA
ADC :NACCUM+1
STA :NACCUM+1
PLA
SEC
SBC #$B0
CLC
ADC :NACCUM
STA :NACCUM
BCC :D2B1
INC :NACCUM+1
:D2B1
INC :NINDEX
DEX
BNE :CNVERT
LDA :SNGFLAG
BPL :OKEXIT
LDA #0
SEC
SBC :NACCUM
STA :NACCUM
LDA #0
SBC :NACCUM+1
STA :NACCUM+1
:OKEXIT
CLC
BCC :EXIT
:EREXIT
SEC
:EXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
LDX :NACCUM+1
LDY :NACCUM
STY RETURN
STX RETURN+1
LDA #2
STA RETLEN
LDA :NINDEX
RTS
:NACCUM DS 2
:SNGFLAG DS 1
:NINDEX DS 1
STRINGSX

View File

@ -1,100 +0,0 @@
*
SUBCOPY
*
PLA
STA RETADR
PLA
STA RETADR+1
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
LDA RETADR+1
PHA
LDA RETADR
PHA
LDA #0
STA :S2LEN
STA :SCERR
LDA :SCNT
BEQ :OKEXIT
LDA :MLEN
BEQ :EREXIT
LDA :SINDEX
BEQ :EREXIT
LDY #0
LDA (ADDR1),Y
STA :S1LEN
CMP :SINDEX
BCC :EREXIT
LDA :SINDEX
CLC
ADC :SCNT
BCS :RECALC
TAX
DEX
CPX :S1LEN
BCC :CNT10K
BEQ :CNT10K
:RECALC
LDA :S1LEN
SEC
SBC :SINDEX
STA :SCNT
INC :SCNT
LDA #$0FF
STA :SCERR
:CNT10K
LDA :SCNT
CMP :MLEN
BCC :CNT20K
BEQ :CNT20K
LDA :MLEN
STA :SCNT
LDA #$0FF
STA :SCERR
:CNT20K
LDX :SCNT
BEQ :EREXIT
LDA #1
STA :S2LEN
:MVLP
LDY :SINDEX
LDA (ADDR1),Y
LDY :S2LEN
STA (ADDR2),Y
INC :SINDEX
INC :S2LEN
DEX
BNE :MVLP
DEC :S2LEN
LDA :SCERR
BNE :EREXIT
:OKEXIT
CLC
BCC :EXIT
:EREXIT
SEC
:EXIT
LDA :S2LEN
LDY #0
STA (ADDR2),Y
STA RETLEN
RTS
:S1LEN DS 1
:S2LEN DS 1
:MLEN DS 1
:SCNT DS 1
:SINDEX DS 1
:SCERR DS 1

View File

@ -1,4 +1,3 @@
*
*``````````````````````````````*
* SUBCOPY :: COPY SUBSTRING *
*- -*

View File

@ -0,0 +1,99 @@
SUBCOPY
PLA
STA RETADR
PLA
STA RETADR+1
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
LDA RETADR+1
PHA
LDA RETADR
PHA
LDA #0
STA :S2LEN ; DESTINATION LENGTH = 0
STA :SCERR ; ASSUME NO ERRORS
LDA :SCNT
BEQ :OKEXIT ; BR IF 0 BYTES TO COPY,
LDA :MLEN
BEQ :EREXIT ; ERROR EXIT IF SUBSTR HAS
LDA :SINDEX
BEQ :EREXIT ; ERROR EXIT IF START IDX = 0
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
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
:RECALC
LDA :S1LEN ; RECALCULATE COUNT
SEC
SBC :SINDEX
STA :SCNT
INC :SCNT ; CNT = S1LEN - IND + 1
LDA #$0FF
STA :SCERR ; INDICATE TRUNCATION
: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
: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
:OKEXIT
CLC
BCC :EXIT
:EREXIT
SEC
:EXIT
LDA :S2LEN
LDY #0
STA (ADDR2),Y
STA RETLEN
RTS
:S1LEN DS 1
:S2LEN DS 1
:MLEN DS 1
:SCNT DS 1
:SINDEX DS 1
:SCERR DS 1

View File

@ -1,4 +1,3 @@
*
*``````````````````````````````*
* SUBDEL :: DELETE SUBSTRING *
*- -*

View File

@ -1,6 +1,4 @@
*
SUBDEL
*
PLA
TAY
PLA
@ -20,51 +18,51 @@ SUBDEL
LDY #0
STY :SCERR
LDA (ADDR1),Y
STA :S1LEN
STA :S1LEN ; GET STRING LENGTH
LDA :SCNT
BEQ :OKEXIT
LDA :SINDEX
BEQ :ERREXIT
BEQ :ERREXIT ; ERR EXIT IF START = 0
LDA :S1LEN
CMP :SINDEX
BCC :ERREXIT
LDA :SINDEX
CLC
ADC :SCNT
BCS :TRUNC
STA :SIDX
TAX
BCS :TRUNC ;TRUNCATE IF INDEX
STA :SIDX ; SAVE INDEX + COUNT AS
TAX ; X = INDEX + COUNT
DEX
CPX :S1LEN
BCC :CNTOK
BEQ :TRUNC
BCC :CNTOK ; BR IF IND + CNT - 1
BEQ :TRUNC ; TRUNC BUT NO ERROR--
LDA #$0FF
STA :SCERR
STA :SCERR ; INDICATE ERROR - NOT
:TRUNC
LDX :SINDEX
LDX :SINDEX ; STRING LENGTH =
DEX
STX :S1LEN
LDA :SCERR
BEQ :OKEXIT
BNE :ERREXIT
:CNTOK
LDA :S1LEN
LDA :S1LEN ; GET STR LENGTH
SEC
SBC :SIDX
SBC :SIDX ; SUBTRACT START INDEX
TAX
INX
BEQ :OKEXIT
BEQ :OKEXIT ; ADD 1 TO INCLUDE LAST
:MVLP
LDY :SIDX
LDA (ADDR1),Y
LDA (ADDR1),Y ; GET NEXT CHAR
LDY :SINDEX
STA (ADDR1),Y
STA (ADDR1),Y ;MOVE IT DOWN
INC :SINDEX
INC :SIDX
INC :SIDX ; INC DEST, SRC INDEXES
DEX
BNE :MVLP
BNE :MVLP ; CONT UNTIL CNT = 0
LDX :SINDEX
DEX
DEX ; START LENGTH = FINAL
STX :S1LEN
:OKEXIT
CLC
@ -74,7 +72,7 @@ SUBDEL
:EXIT
LDA :S1LEN
LDY #0
STA (ADDR1),Y
STA (ADDR1),Y ; SET LENGTH OF STRING
RTS
:S1LEN DS 1
:SCNT DS 1

View File

@ -1,121 +0,0 @@
*
SUBINS
*
PLA
TAY
PLA
TAX
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA :MLEN
PLA
STA :SINDEX
PLA
STA ADDR1
PLA
STA ADDR1+1
TXA
PHA
TYA
PHA
LDA #0
STA :SCERR
LDY #0
LDA (ADDR1),Y
STA :S1LEN
LDA (ADDR2),Y
STA :S2LEN
BNE :IDX0
JMP :OKEXIT
:IDX0
LDA :SINDEX
BNE :CHKLEN
JMP :EREXIT
:CHKLEN
LDA :S2LEN
CLC
ADC :S1LEN
BCS :TRUNC
CMP :MLEN
BCC :IDXLEN
BEQ :IDXLEN
:TRUNC
LDA :MLEN
SEC
SBC :S1LEN
BCC :EREXIT
BEQ :EREXIT
STA :S2LEN
LDA #$0FF
STA :SCERR
:IDXLEN
LDA :S1LEN
CMP :SINDEX
BCS :LENOK
LDX :S1LEN
INX
STX :SINDEX
LDA #$0FF
STA :SCERR
LDA :S1LEN
CLC
ADC :S2LEN
STA :S1LEN
JMP :MVESUB
:LENOK
LDA :S1LEN
SEC
SBC :SINDEX
TAX
INX
LDA :S1LEN
STA :SIDX
CLC
ADC :S2LEN
STA :SBIDX
STA :S1LEN
:OPNLP
LDY :SIDX
LDA (ADDR1),Y
LDY :SBIDX
STA (ADDR1),Y
DEC :SIDX
DEC :SBIDX
DEX
BNE :OPNLP
:MVESUB
LDA #1
STA :SIDX
LDX :S2LEN
:MVELP
LDY :SIDX
LDA (ADDR2),Y
LDY :SINDEX
STA (ADDR1),Y
INC :SIDX
INC :SINDEX
DEX
BNE :MVELP
LDA :SCERR
BNE :EREXIT
:OKEXIT
CLC
BCC :EXIT
:EREXIT
SEC
:EXIT
LDA :S1LEN
LDY #0
STA (ADDR1),Y
RTS
:S1LEN DS 1
:S2LEN DS 1
:SUBLEN DS 1
:MLEN DS 1
:SINDEX DS 1
:SIDX DS 1
:SBIDX DS 1
:SCERR DS 1

View File

@ -1,4 +1,3 @@
*
*``````````````````````````````*
* SUBINS :: INSERT SUBSTRING *
*- -*

View File

@ -0,0 +1,120 @@
SUBINS
PLA
TAY
PLA
TAX
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA :MLEN
PLA
STA :SINDEX
PLA
STA ADDR1
PLA
STA ADDR1+1
TXA
PHA
TYA
PHA
LDA #0
STA :SCERR ; ASSUME NO ERR WILL BE FOUND
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
:IDX0
LDA :SINDEX
BNE :CHKLEN ; BR OF INDEX NOT 0
JMP :EREXIT ; ELSE ERROR EXIT
: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
:TRUNC
LDA :MLEN ; SUBSTR LEN = MLEN - STR LEN
SEC
SBC :S1LEN
BCC :EREXIT
BEQ :EREXIT ; ERR IF MLEN < STR LEN OR 0
STA :S2LEN
LDA #$0FF
STA :SCERR ; INDICATE SUBSTR WAS TRUNCATED
: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
:LENOK
LDA :S1LEN
SEC
SBC :SINDEX
TAX
INX ; X= NUM OF CHARS TO MOV
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
:MVESUB
LDA #1
STA :SIDX
; 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
:S1LEN DS 1
:S2LEN DS 1
:SUBLEN DS 1
:MLEN DS 1
:SINDEX DS 1
:SIDX DS 1
:SBIDX DS 1
:SCERR DS 1

View File

@ -1,78 +0,0 @@
*
SUBPOS
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDA RETADR+1
PHA
LDA RETADR
PHA
:POS
LDY #0
LDA (ADDR1),Y
BEQ :NOTFND
STA :SLEN
LDA (ADDR2),Y
BEQ :NOTFND
STA :SUBLEN
LDA :SUBLEN
CMP :SLEN
BEQ :LENOK
BCS :NOTFND
:LENOK
LDA #1
STA :SINDEX
LDA :SLEN
SEC
SBC :SUBLEN
STA :SCOUNT
INC :SCOUNT
:SLP1
LDA :SINDEX
STA :SIDX
LDA #1
STA :SUBIDX
:CMPLP
LDY :SIDX
LDA (ADDR1),Y
LDY :SUBIDX
CMP (ADDR2),Y
BNE :SLP2
LDY :SUBIDX
CPY :SUBLEN
BEQ :FOUND
INY
STY :SUBIDX
INC :SIDX
JMP :CMPLP
:SLP2
INC :SINDEX
DEC :SCOUNT
BNE :SLP1
BEQ :NOTFND
:FOUND
LDA :SINDEX
JMP :EXIT
:NOTFND
LDA #0
:EXIT
STA RETURN
LDY #1
STY RETLEN
RTS
:SLEN DS 1
:SUBLEN DS 1
:SINDEX DS 1
:SUBIDX DS 1
:SCOUNT DS 1
:SIDX DS 1

View File

@ -1,4 +1,3 @@
*
*``````````````````````````````*
* SUBPOS :: SUBSTRING POSITION *
*- -*

View File

@ -0,0 +1,78 @@
SUBPOS
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDA RETADR+1
PHA
LDA RETADR
PHA
:POS
LDY #0
LDA (ADDR1),Y ; GET LENGTH OF STRING
BEQ :NOTFND ; EXIT IF LENGTH = 0
STA :SLEN
LDA (ADDR2),Y ; GET SUBSTR LENGTH
BEQ :NOTFND ; EXIT IF SUB LENGTH = 0
STA :SUBLEN
LDA :SUBLEN
CMP :SLEN
BEQ :LENOK
BCS :NOTFND ; CANNOT FIND SUBSTR IF
:LENOK
LDA #1
STA :SINDEX ; START LOOKING AT FIRST
; CHARACTER OF STRING
LDA :SLEN ; CONT UNTIL REMAINING STR
; TOO SHORT
SEC ; COUNT=STR LEN - SUB LEN+1
SBC :SUBLEN
STA :SCOUNT
INC :SCOUNT
:SLP1
LDA :SINDEX
STA :SIDX ; START STR AT INDEX
LDA #1
STA :SUBIDX ; START SUB IND AT 1
:CMPLP
LDY :SIDX
LDA (ADDR1),Y ; GET NEXT CHAR FROM STR
LDY :SUBIDX
CMP (ADDR2),Y ; COMPARE TO NEXT SUB CHAR
BNE :SLP2 ; BR IF SUB NOT HERE
LDY :SUBIDX
CPY :SUBLEN ; TEST IF WE ARE DONE
BEQ :FOUND ; BR IF ALL CHARS WERE EQUAL
INY ; ELSE INC TO NEXT CHAR
STY :SUBIDX
INC :SIDX
JMP :CMPLP ; CONTINUE
:SLP2
INC :SINDEX ; INCREMENT INDEX
DEC :SCOUNT ; DEC COUNT
BNE :SLP1 ; BR IF NOT DONE
BEQ :NOTFND ; ELSE EXIT TO NOT FOUND
:FOUND
LDA :SINDEX ; FOUND, A = STARTING IDX
JMP :EXIT
:NOTFND
LDA #0 ; SUB NOT FOUND, A=0
:EXIT
STA RETURN
LDY #1
STY RETLEN
RTS
:SLEN DS 1
:SUBLEN DS 1
:SINDEX DS 1
:SUBIDX DS 1
:SCOUNT DS 1
:SIDX DS 1

View File

@ -1,844 +0,0 @@
*
JMP SUBSTRINGSX
*
*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*
* *
* SUBSTRING ROUTINE LIBRARY *
* *
* AUTHOR: NATHAN RIGGS *
* CONTACT: NATHAN.RIGGS@ *
* OUTLOOK.COM *
* *
* VERSION: 0.2.0 *
* DATE: 30-OCT-2018 *
* ASSEMBLER: MERLIN 8 PRO *
* OS: DOS 3.3 *
* LICENSE: APACHE 2.0 *
* *
* THIS IS A LIBRARY FOR USING *
* SUBSTRING OPERATIONS. *
* *
*------------------------------*
* *
* LIST OF ROUTINES *
* *
* SUBPOS : FIND POS OF SUBSTR *
* SUBCOPY : COPY SUBSTRING *
* SUBDEL : DELETE SUBSTRING *
* SUBINS : INSERT SUBSTRING *
* *
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*
*
*``````````````````````````````*
* SUBPOS :: SUBSTRING POSITION *
*- -*
* FIND THE POSITION OF A SUB- *
* STRING WITHIN ANOTHER STRING *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>STR ; STRING ADDR *
* PHA *
* LDA #<STR *
* PHA *
* LDA #>SUB ; SUBSTR ADDR *
* PHA *
* LDA #<SUB *
* JSR SUBPOS *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* LOW BYTE OF SUBSTRING ADDR *
* HI BYTE OF SUBSTRING ADDR *
* LO BYTE OF STRING ADDR *
* HI BYTE OF STRING ADDRESS *
* HI BYTE OF RETURN ADDRESS *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
* .Y = CLOBBERED; TRASH *
* .X = CLOBBERED; TRASH *
* .A = INDEX OF SUBSTRING IF *
* FOUND; OTHERWISE, 0 *
* *
* [RETURN] = INDEX OF SUBSTR; *
* 0 IF NOT FOUND *
* [RETLEN] = 1 (INDEX LENGTH) *
*- -*
* ADAPTED FROM LEVANTHAL AND *
* WINTHROP'S /6502 ASSEMBLY *
* LANGUAGE ROUTINES/. MAY NOT *
* FALL UNDER APACHE 2.0 UNTIL *
* HEAVILY MODIFIED. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
SUBPOS
*
** SAVE RETURN ADDRESS
*
PLA
STA RETADR
PLA
STA RETADR+1
*
** GET PARAMETERS
*
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
*
** RESTORE RETURN ADDRESS
*
LDA RETADR+1
PHA
LDA RETADR
PHA
*
:POS
LDY #0
LDA (ADDR1),Y ; GET LENGTH OF STRING
BEQ :NOTFND ; EXIT IF LENGTH = 0
STA :SLEN
LDA (ADDR2),Y ; GET SUBSTR LENGTH
BEQ :NOTFND ; EXIT IF SUB LENGTH = 0
STA :SUBLEN
*
** IF THE SUBSTR IS LONGER THAN STR, DECLARE THE
** SUBSTR NOT FOUND
*
LDA :SUBLEN
CMP :SLEN
BEQ :LENOK
BCS :NOTFND ; CANNOT FIND SUBSTR IF
; LONGER THAN STR
*
** START, SEARCH, CONTINUE UNTIL
** REMAINING STR SHORTER THAN SUBSTR
*
:LENOK
LDA #1
STA :SINDEX ; START LOOKING AT FIRST
; CHARACTER OF STRING
LDA :SLEN ; CONT UNTIL REMAINING STR
; TOO SHORT
SEC ; COUNT=STR LEN - SUB LEN+1
SBC :SUBLEN
STA :SCOUNT
INC :SCOUNT
*
** SEARCH FOR SUBSTRING IN STRING
*
:SLP1
LDA :SINDEX
STA :SIDX ; START STR AT INDEX
LDA #1
STA :SUBIDX ; START SUB IND AT 1
*
** LOOK FOR SUBSTRING BEGINNING AT INDEX
*
:CMPLP
LDY :SIDX
LDA (ADDR1),Y ; GET NEXT CHAR FROM STR
LDY :SUBIDX
CMP (ADDR2),Y ; COMPARE TO NEXT SUB CHAR
BNE :SLP2 ; BR IF SUB NOT HERE
LDY :SUBIDX
CPY :SUBLEN ; TEST IF WE ARE DONE
BEQ :FOUND ; BR IF ALL CHARS WERE EQUAL
INY ; ELSE INC TO NEXT CHAR
STY :SUBIDX
INC :SIDX
JMP :CMPLP ; CONTINUE
*
** ARRIVE HERE IF SUBSTRING NOT FOUND
*
:SLP2
INC :SINDEX ; INCREMENT INDEX
DEC :SCOUNT ; DEC COUNT
BNE :SLP1 ; BR IF NOT DONE
BEQ :NOTFND ; ELSE EXIT TO NOT FOUND
*
:FOUND
LDA :SINDEX ; FOUND, A = STARTING IDX
JMP :EXIT
*
:NOTFND
LDA #0 ; SUB NOT FOUND, A=0
:EXIT
STA RETURN
LDY #1
STY RETLEN
RTS
*
** DATA
*
:SLEN DS 1
:SUBLEN DS 1
:SINDEX DS 1
:SUBIDX DS 1
:SCOUNT DS 1
:SIDX DS 1
*
*``````````````````````````````*
* 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
*
*``````````````````````````````*
* SUBDEL :: DELETE SUBSTRING *
*- -*
* DELETE A SUBSTRING FROM A *
* STRING. *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>STR ; STRING ADDRESS *
* PHA *
* LDA #<STR *
* PHA *
* LDA IND ; DEL START INDEX *
* PHA *
* LDA LEN ; LENGTH OF DELETE *
* PHA *
* JSR SUBDEL *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* NUMBER OF BYTES TO DELETE *
* STARTING INDEX OF DELETION *
* LO BYTE OF STRING ADDRESS *
* HI BYTE OF STRING ADDRESS *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
* .Y = TRASH *
* .X = TRASH *
* .A = TRASH *
* *
* IF NO ERRORS, CARRY = 0; *
* ELSE, CARRY = 1 *
*- -*
* ADAPTED FROM LEVANTHAL AND *
* WINTHROP'S /6502 ASSEMBLY *
* LANGUAGE ROUTINES/. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
SUBDEL
*
** SAVE RETURN ADDRES
*
PLA
TAY
PLA
TAX
*
** GET PARAMTERS
*
PLA
STA :SCNT
PLA
STA :SINDEX
PLA
STA ADDR1
PLA
STA ADDR1+1
*
** RESTORE RETURN ADDRESS
*
TXA
PHA
TYA
PHA
*
** INITIALIZE ERROR INDICATOR TO 0
*
LDY #0
STY :SCERR
LDA (ADDR1),Y
STA :S1LEN ; GET STRING LENGTH
*
** CHECK FOR A NON-ZERO COUNT AND INDEX
*
LDA :SCNT
BEQ :OKEXIT
; GOOD EXIT IF NO DELETE
LDA :SINDEX
BEQ :ERREXIT ; ERR EXIT IF START = 0
*
** CHECK FOR STARTING INDEX WITHIN THE STRING
*
* EXIT IF IT IS NOT
*
LDA :S1LEN
CMP :SINDEX
BCC :ERREXIT
*
** BE SURE THE NUMBER OF CHARACTERS REQUESTED
** TO BE DELETED ARE PRESENT.
** IF NOT, THEN ONLY DELETE FROM THE INDEX
** TO THE END OF THE STRING.
*
LDA :SINDEX
CLC
ADC :SCNT
BCS :TRUNC ;TRUNCATE IF INDEX
; + COUNT > 255
STA :SIDX ; SAVE INDEX + COUNT AS
; THE SOURCE INDEX
TAX ; X = INDEX + COUNT
DEX
CPX :S1LEN
BCC :CNTOK ; BR IF IND + CNT - 1
; < __S1LEN
; ELSE JUST TRUNC STRING
BEQ :TRUNC ; TRUNC BUT NO ERROR--
; EXACTLY ENOUGH CHARS
LDA #$0FF
STA :SCERR ; INDICATE ERROR - NOT
; ENOUGH CHARS TO DELETE
*
** TRUNCATE THE STRING - NO COMPACTING NECESSARY
*
:TRUNC
LDX :SINDEX ; STRING LENGTH =
; START INDEX - 1
DEX
STX :S1LEN
LDA :SCERR
BEQ :OKEXIT
BNE :ERREXIT
*
** DELETE THE SUBSTRING BY COMPACTING
** MOVE ALL CHARS ABOVE THE DELETED AREA DOWN
*
:CNTOK
*
** CALCULATE NUMBER OF CHARS TO MOVE
** (SLEN - SIDX + 1)
*
LDA :S1LEN ; GET STR LENGTH
SEC
SBC :SIDX ; SUBTRACT START INDEX
TAX
INX
BEQ :OKEXIT ; ADD 1 TO INCLUDE LAST
; CHAR; BR IF CNT = 0
:MVLP
LDY :SIDX
LDA (ADDR1),Y ; GET NEXT CHAR
LDY :SINDEX
STA (ADDR1),Y ;MOVE IT DOWN
INC :SINDEX
INC :SIDX ; INC DEST, SRC INDEXES
DEX
BNE :MVLP ; CONT UNTIL CNT = 0
LDX :SINDEX
DEX ; START LENGTH = FINAL
; DEST INDEX -1
STX :S1LEN
*
** GOOD EXIT
*
:OKEXIT
CLC
BCC :EXIT
:ERREXIT
SEC
*
:EXIT
LDA :S1LEN
LDY #0
STA (ADDR1),Y ; SET LENGTH OF STRING
RTS
*
** DATA
*
:S1LEN DS 1
:SCNT DS 1
:SINDEX DS 1
:SIDX DS 1
:SCERR DS 1
*
*``````````````````````````````*
* 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
*
SUBSTRINGSX
*

View File

@ -1,384 +0,0 @@
JMP SUBSTRINGSX
*
SUBPOS
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDA RETADR+1
PHA
LDA RETADR
PHA
:POS
LDY #0
LDA (ADDR1),Y
BEQ :NOTFND
STA :SLEN
LDA (ADDR2),Y
BEQ :NOTFND
STA :SUBLEN
LDA :SUBLEN
CMP :SLEN
BEQ :LENOK
BCS :NOTFND
:LENOK
LDA #1
STA :SINDEX
LDA :SLEN
SEC
SBC :SUBLEN
STA :SCOUNT
INC :SCOUNT
:SLP1
LDA :SINDEX
STA :SIDX
LDA #1
STA :SUBIDX
:CMPLP
LDY :SIDX
LDA (ADDR1),Y
LDY :SUBIDX
CMP (ADDR2),Y
BNE :SLP2
LDY :SUBIDX
CPY :SUBLEN
BEQ :FOUND
INY
STY :SUBIDX
INC :SIDX
JMP :CMPLP
:SLP2
INC :SINDEX
DEC :SCOUNT
BNE :SLP1
BEQ :NOTFND
:FOUND
LDA :SINDEX
JMP :EXIT
:NOTFND
LDA #0
:EXIT
STA RETURN
LDY #1
STY RETLEN
RTS
:SLEN DS 1
:SUBLEN DS 1
:SINDEX DS 1
:SUBIDX DS 1
:SCOUNT DS 1
:SIDX DS 1
*
SUBCOPY
*
PLA
STA RETADR
PLA
STA RETADR+1
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
LDA RETADR+1
PHA
LDA RETADR
PHA
LDA #0
STA :S2LEN
STA :SCERR
LDA :SCNT
BEQ :OKEXIT
LDA :MLEN
BEQ :EREXIT
LDA :SINDEX
BEQ :EREXIT
LDY #0
LDA (ADDR1),Y
STA :S1LEN
CMP :SINDEX
BCC :EREXIT
LDA :SINDEX
CLC
ADC :SCNT
BCS :RECALC
TAX
DEX
CPX :S1LEN
BCC :CNT10K
BEQ :CNT10K
:RECALC
LDA :S1LEN
SEC
SBC :SINDEX
STA :SCNT
INC :SCNT
LDA #$0FF
STA :SCERR
:CNT10K
LDA :SCNT
CMP :MLEN
BCC :CNT20K
BEQ :CNT20K
LDA :MLEN
STA :SCNT
LDA #$0FF
STA :SCERR
:CNT20K
LDX :SCNT
BEQ :EREXIT
LDA #1
STA :S2LEN
:MVLP
LDY :SINDEX
LDA (ADDR1),Y
LDY :S2LEN
STA (ADDR2),Y
INC :SINDEX
INC :S2LEN
DEX
BNE :MVLP
DEC :S2LEN
LDA :SCERR
BNE :EREXIT
:OKEXIT
CLC
BCC :EXIT
:EREXIT
SEC
:EXIT
LDA :S2LEN
LDY #0
STA (ADDR2),Y
STA RETLEN
RTS
:S1LEN DS 1
:S2LEN DS 1
:MLEN DS 1
:SCNT DS 1
:SINDEX DS 1
:SCERR DS 1
*
SUBDEL
*
PLA
TAY
PLA
TAX
PLA
STA :SCNT
PLA
STA :SINDEX
PLA
STA ADDR1
PLA
STA ADDR1+1
TXA
PHA
TYA
PHA
LDY #0
STY :SCERR
LDA (ADDR1),Y
STA :S1LEN
LDA :SCNT
BEQ :OKEXIT
LDA :SINDEX
BEQ :ERREXIT
LDA :S1LEN
CMP :SINDEX
BCC :ERREXIT
LDA :SINDEX
CLC
ADC :SCNT
BCS :TRUNC
STA :SIDX
TAX
DEX
CPX :S1LEN
BCC :CNTOK
BEQ :TRUNC
LDA #$0FF
STA :SCERR
:TRUNC
LDX :SINDEX
DEX
STX :S1LEN
LDA :SCERR
BEQ :OKEXIT
BNE :ERREXIT
:CNTOK
LDA :S1LEN
SEC
SBC :SIDX
TAX
INX
BEQ :OKEXIT
:MVLP
LDY :SIDX
LDA (ADDR1),Y
LDY :SINDEX
STA (ADDR1),Y
INC :SINDEX
INC :SIDX
DEX
BNE :MVLP
LDX :SINDEX
DEX
STX :S1LEN
:OKEXIT
CLC
BCC :EXIT
:ERREXIT
SEC
:EXIT
LDA :S1LEN
LDY #0
STA (ADDR1),Y
RTS
:S1LEN DS 1
:SCNT DS 1
:SINDEX DS 1
:SIDX DS 1
:SCERR DS 1
*
SUBINS
*
PLA
TAY
PLA
TAX
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA :MLEN
PLA
STA :SINDEX
PLA
STA ADDR1
PLA
STA ADDR1+1
TXA
PHA
TYA
PHA
LDA #0
STA :SCERR
LDY #0
LDA (ADDR1),Y
STA :S1LEN
LDA (ADDR2),Y
STA :S2LEN
BNE :IDX0
JMP :OKEXIT
:IDX0
LDA :SINDEX
BNE :CHKLEN
JMP :EREXIT
:CHKLEN
LDA :S2LEN
CLC
ADC :S1LEN
BCS :TRUNC
CMP :MLEN
BCC :IDXLEN
BEQ :IDXLEN
:TRUNC
LDA :MLEN
SEC
SBC :S1LEN
BCC :EREXIT
BEQ :EREXIT
STA :S2LEN
LDA #$0FF
STA :SCERR
:IDXLEN
LDA :S1LEN
CMP :SINDEX
BCS :LENOK
LDX :S1LEN
INX
STX :SINDEX
LDA #$0FF
STA :SCERR
LDA :S1LEN
CLC
ADC :S2LEN
STA :S1LEN
JMP :MVESUB
:LENOK
LDA :S1LEN
SEC
SBC :SINDEX
TAX
INX
LDA :S1LEN
STA :SIDX
CLC
ADC :S2LEN
STA :SBIDX
STA :S1LEN
:OPNLP
LDY :SIDX
LDA (ADDR1),Y
LDY :SBIDX
STA (ADDR1),Y
DEC :SIDX
DEC :SBIDX
DEX
BNE :OPNLP
:MVESUB
LDA #1
STA :SIDX
LDX :S2LEN
:MVELP
LDY :SIDX
LDA (ADDR2),Y
LDY :SINDEX
STA (ADDR1),Y
INC :SIDX
INC :SINDEX
DEX
BNE :MVELP
LDA :SCERR
BNE :EREXIT
:OKEXIT
CLC
BCC :EXIT
:EREXIT
SEC
:EXIT
LDA :S1LEN
LDY #0
STA (ADDR1),Y
RTS
:S1LEN DS 1
:S2LEN DS 1
:SUBLEN DS 1
:MLEN DS 1
:SINDEX DS 1
:SIDX DS 1
:SBIDX DS 1
:SCERR DS 1
SUBSTRINGSX