452 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
			
		
		
	
	
			452 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
; do *NOT* use register4 to register7 during time slicing
 | 
						|
strChr              EQU     register0
 | 
						|
strAddr             EQU     register0
 | 
						|
strHex              EQU     register1
 | 
						|
strLen              EQU     register2
 | 
						|
strDstLen           EQU     register0
 | 
						|
strFinish           EQU     register0
 | 
						|
strSrcAddr          EQU     register1
 | 
						|
strDstAddr          EQU     register2
 | 
						|
strSrcLen           EQU     register3
 | 
						|
strOffset           EQU     register8
 | 
						|
strSrcAddr2         EQU     register9
 | 
						|
strTmpAddr          EQU     register10
 | 
						|
strLutAddr          EQU     register11
 | 
						|
strBakAddr          EQU     register12
 | 
						|
strSrcLen2          EQU     register13
 | 
						|
strInteger          EQU     register0
 | 
						|
strDigit            EQU     register1
 | 
						|
strMult             EQU     register3
 | 
						|
 | 
						|
 | 
						|
%SUB                stringChr
 | 
						|
                    ; create a char string, (parameter in strChr)
 | 
						|
stringChr           LDI     1
 | 
						|
                    POKE    strDstAddr                          ; set destination buffer length
 | 
						|
                    INC     strDstAddr
 | 
						|
                    LD      strChr
 | 
						|
                    POKE    strDstAddr                          ; copy char
 | 
						|
                    INC     strDstAddr
 | 
						|
                    LDI     0
 | 
						|
                    POKE    strDstAddr                          ; terminating 0
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringSpc
 | 
						|
                    ; create a spc string, (parameter in strLen)
 | 
						|
stringSpc           LD      strLen
 | 
						|
                    BEQ     stringS_exit
 | 
						|
                    SUBI    94
 | 
						|
                    BGT     stringS_exit
 | 
						|
                    POKE    strAddr                             ; set destination buffer length
 | 
						|
                    INC     strAddr
 | 
						|
                    
 | 
						|
stringS_loop        LDI     32
 | 
						|
                    POKE    strAddr                             ; copy char
 | 
						|
                    INC     strAddr
 | 
						|
                    LD      strLen
 | 
						|
                    SUBI    1
 | 
						|
                    ST      strLen
 | 
						|
                    BNE     stringS_loop
 | 
						|
                    LDI     0
 | 
						|
                    POKE    strAddr                             ; terminating 0
 | 
						|
                    
 | 
						|
stringS_exit        RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringHex
 | 
						|
                    ; creates a hex string at strAddr of strLen digits from strHex
 | 
						|
stringHex           LDWI    SYS_LSRW4_50                        ; shift right by 4 SYS routine
 | 
						|
                    STW     giga_sysFn
 | 
						|
                    LDW     strAddr
 | 
						|
                    STW     strTmpAddr                          ; store string start
 | 
						|
                    LD      strLen
 | 
						|
                    POKE    strAddr                             ; length byte
 | 
						|
                    ADDI    1
 | 
						|
                    ADDW    strAddr
 | 
						|
                    STW     strAddr                             ; offset by length byte and zero delimeter
 | 
						|
                    LDI     0
 | 
						|
                    POKE    strAddr                             ; zero delimiter
 | 
						|
                    
 | 
						|
stringH_loop        LDW     strAddr
 | 
						|
                    SUBI    1
 | 
						|
                    STW     strAddr                             ; start at LSD and finish at MSD
 | 
						|
                    SUBW    strTmpAddr
 | 
						|
                    BEQ     stringH_done
 | 
						|
                    LD      strHex
 | 
						|
                    ANDI    0x0F
 | 
						|
                    SUBI    10
 | 
						|
                    BLT     stringH_skip
 | 
						|
                    ADDI    7
 | 
						|
                    
 | 
						|
stringH_skip        ADDI    0x3A
 | 
						|
                    POKE    strAddr
 | 
						|
                    LDW     strHex
 | 
						|
                    SYS     50
 | 
						|
                    STW     strHex                              ; next nibble
 | 
						|
                    BRA     stringH_loop
 | 
						|
                    
 | 
						|
stringH_done        RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringCopy
 | 
						|
                    ; copy one string to another
 | 
						|
stringCopy          LDW     strSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    POKE    strDstAddr
 | 
						|
                    INC     strSrcAddr
 | 
						|
                    INC     strDstAddr
 | 
						|
                    BNE     stringCopy                          ; copy char until terminating char
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringCmp
 | 
						|
                    ; compares two strings: returns 0 for smaller, 1 for equal and 2 for larger
 | 
						|
stringCmp           LDW     strSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    STW     strSrcLen                           ; save str length
 | 
						|
                    LDW     strSrcAddr2
 | 
						|
                    PEEK
 | 
						|
                    STW     strSrcLen2                          ; save str length
 | 
						|
                    INC     strSrcAddr
 | 
						|
                    INC     strSrcAddr2                         ; skip lengths
 | 
						|
                    
 | 
						|
stringC_loop        LDW     strSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    BEQ     stringC_equal                       ; this assumes your strings are valid, (i.e. valid length and terminating bytes)
 | 
						|
                    STW     strChr
 | 
						|
                    LDW     strSrcAddr2
 | 
						|
                    PEEK
 | 
						|
                    SUBW    strChr
 | 
						|
                    BLT     stringC_larger
 | 
						|
                    BGT     stringC_smaller
 | 
						|
                    INC     strSrcAddr
 | 
						|
                    INC     strSrcAddr2
 | 
						|
                    BRA     stringC_loop
 | 
						|
 | 
						|
stringC_smaller     LDI     0
 | 
						|
                    RET
 | 
						|
                    
 | 
						|
stringC_equal       LDW     strSrcLen
 | 
						|
                    SUBW    strSrcLen2
 | 
						|
                    BLT     stringC_smaller
 | 
						|
                    BGT     stringC_larger                      ; if strings are equal, choose based on length
 | 
						|
                    LDI     1
 | 
						|
                    RET
 | 
						|
                    
 | 
						|
stringC_larger      LDI     2
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringAdd
 | 
						|
                    ; adds two strings together, (internal sub)
 | 
						|
stringAdd           LDW     strDstAddr
 | 
						|
                    STW     strTmpAddr
 | 
						|
                    XORW    strSrcAddr
 | 
						|
                    BNE     stringA_diff
 | 
						|
                    LDW     strDstAddr                          ; if src = dst then skip first copy
 | 
						|
                    PEEK
 | 
						|
                    STW     strDstLen
 | 
						|
                    ADDW    strDstAddr
 | 
						|
                    STW     strDstAddr                          ; skip length byte and point to end of dst
 | 
						|
                    INC     strDstAddr
 | 
						|
                    BRA     stringA_copy1
 | 
						|
 | 
						|
stringA_diff        INC     strSrcAddr
 | 
						|
                    INC     strDstAddr                          ; skip lengths
 | 
						|
                    LDI     0
 | 
						|
                    STW     strDstLen
 | 
						|
                    
 | 
						|
stringA_copy0       LDW     strSrcAddr                          ; assumes strSrcAddr is a valid string <= 94 length
 | 
						|
                    PEEK
 | 
						|
                    BEQ     stringA_copy1
 | 
						|
                    POKE    strDstAddr
 | 
						|
                    INC     strSrcAddr
 | 
						|
                    INC     strDstAddr
 | 
						|
                    INC     strDstLen
 | 
						|
                    BRA     stringA_copy0
 | 
						|
                    
 | 
						|
stringA_copy1       LDW     strDstLen
 | 
						|
                    SUBI    94
 | 
						|
                    BGE     stringA_exit                        ; maximum destination length reached
 | 
						|
                    INC     strSrcAddr2                         ; skips length first time
 | 
						|
                    LDW     strSrcAddr2
 | 
						|
                    PEEK
 | 
						|
                    BEQ     stringA_exit                        ; copy char until terminating char
 | 
						|
                    POKE    strDstAddr                          ; copy char
 | 
						|
                    INC     strDstAddr
 | 
						|
                    INC     strDstLen
 | 
						|
                    BRA     stringA_copy1
 | 
						|
 | 
						|
stringA_exit        LDW     strDstLen
 | 
						|
                    POKE    strTmpAddr                          ; save concatenated string length
 | 
						|
                    LDI     0
 | 
						|
                    POKE    strDstAddr                          ; terminating zero
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringConcat
 | 
						|
                    ; concatenates multiple strings together
 | 
						|
stringConcat        PUSH
 | 
						|
                    LDWI    stringAdd
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    POP
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringConcatLut
 | 
						|
                    ; concatenates multiple strings together using a LUT of string addresses
 | 
						|
stringConcatLut     PUSH
 | 
						|
                    LDW     strLutAddr
 | 
						|
                    DEEK
 | 
						|
                    BEQ     stringCCL_exit
 | 
						|
                    STW     strSrcAddr
 | 
						|
                    LDW     strDstAddr
 | 
						|
                    STW     strBakAddr
 | 
						|
                    
 | 
						|
stringCCL_loop      INC     strLutAddr
 | 
						|
                    INC     strLutAddr
 | 
						|
                    LDW     strLutAddr
 | 
						|
                    DEEK
 | 
						|
                    BEQ     stringCCL_exit
 | 
						|
                    STW     strSrcAddr2
 | 
						|
                    LDWI    stringAdd
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    LDW     strBakAddr
 | 
						|
                    STW     strDstAddr
 | 
						|
                    STW     strSrcAddr
 | 
						|
                    BRA     stringCCL_loop
 | 
						|
                    
 | 
						|
stringCCL_exit      POP
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringLeft
 | 
						|
                    ; copies sub string from left hand side of source string to destination string
 | 
						|
stringLeft          LD      strDstLen
 | 
						|
                    POKE    strDstAddr                          ; destination length
 | 
						|
                    BEQ     stringL_exit                        ; exit if left length = 0
 | 
						|
                    LDW     strSrcAddr
 | 
						|
                    PEEK                                        ; get source length
 | 
						|
                    STW     strSrcLen
 | 
						|
                    SUBW    strDstLen
 | 
						|
                    BGE     stringL_skip                        ; is left length <= source length
 | 
						|
                    LD      strSrcLen
 | 
						|
                    STW     strDstLen
 | 
						|
                    POKE    strDstAddr                          ; new destination length
 | 
						|
                    
 | 
						|
stringL_skip        LDW     strSrcAddr
 | 
						|
                    ADDW    strDstLen
 | 
						|
                    STW     strFinish                           ; end source address
 | 
						|
                    
 | 
						|
stringL_loop        INC     strSrcAddr                          ; skip lengths the first time in
 | 
						|
                    INC     strDstAddr
 | 
						|
                    LDW     strSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    POKE    strDstAddr                          ; copy char
 | 
						|
                    LDW     strSrcAddr
 | 
						|
                    SUBW    strFinish
 | 
						|
                    BLT     stringL_loop                        ; until finished
 | 
						|
                    
 | 
						|
stringL_exit        INC     strDstAddr
 | 
						|
                    LDI     0
 | 
						|
                    POKE    strDstAddr                          ; terminating 0
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringRight
 | 
						|
                    ; copies sub string from right hand side of source string to destination string
 | 
						|
stringRight         LD      strDstLen
 | 
						|
                    POKE    strDstAddr                          ; destination length
 | 
						|
                    BEQ     stringR_exit                        ; exit if right length = 0
 | 
						|
                    LDW     strSrcAddr
 | 
						|
                    PEEK                                        ; get source length
 | 
						|
                    STW     strSrcLen
 | 
						|
                    SUBW    strDstLen
 | 
						|
                    BGE     stringR_skip                        ; length <= srcLength
 | 
						|
                    LD      strSrcLen
 | 
						|
                    STW     strDstLen
 | 
						|
                    POKE    strDstAddr                          ; new destination length
 | 
						|
                    LDI     0
 | 
						|
                    
 | 
						|
stringR_skip        ADDW    strSrcAddr
 | 
						|
                    STW     strSrcAddr                          ; copy from (source address + (source length - right length)) to destination address
 | 
						|
                    ADDW    strDstLen
 | 
						|
                    STW     strFinish                           ; end source address
 | 
						|
 | 
						|
stringR_loop        INC     strSrcAddr                          ; skip lengths the first time in
 | 
						|
                    INC     strDstAddr
 | 
						|
                    LDW     strSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    POKE    strDstAddr                          ; copy char
 | 
						|
                    LDW     strSrcAddr
 | 
						|
                    SUBW    strFinish
 | 
						|
                    BLT     stringR_loop                        ; until finished
 | 
						|
                    
 | 
						|
stringR_exit        INC     strDstAddr
 | 
						|
                    LDI     0
 | 
						|
                    POKE    strDstAddr                          ; terminating 0
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringMid
 | 
						|
                    ; copies length sub string from source offset to destination string
 | 
						|
stringMid           LD      strDstLen
 | 
						|
                    POKE    strDstAddr                          ; destination length
 | 
						|
                    BEQ     stringM_exit                        ; exit if right length = 0
 | 
						|
                    LDW     strSrcAddr
 | 
						|
                    PEEK                                        ; get source length
 | 
						|
                    STW     strSrcLen
 | 
						|
                    SUBW    strOffset                           
 | 
						|
                    SUBW    strDstLen
 | 
						|
                    BGE     stringM_skip                        ; length + offset <= srcLength
 | 
						|
                    LD      strSrcLen
 | 
						|
                    SUBW    strOffset
 | 
						|
                    STW     strDstLen
 | 
						|
                    POKE    strDstAddr                          ; new destination length
 | 
						|
                    
 | 
						|
stringM_skip        LDW     strSrcAddr
 | 
						|
                    ADDW    strOffset
 | 
						|
                    STW     strSrcAddr                          ; copy from (source address + (source length - right length)) to destination address
 | 
						|
                    ADDW    strDstLen
 | 
						|
                    STW     strFinish                           ; end source address
 | 
						|
 | 
						|
stringM_loop        INC     strSrcAddr                          ; skip lengths the first time in
 | 
						|
                    INC     strDstAddr
 | 
						|
                    LDW     strSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    POKE    strDstAddr                          ; copy char
 | 
						|
                    LDW     strSrcAddr
 | 
						|
                    SUBW    strFinish
 | 
						|
                    BLT     stringM_loop                        ; until finished
 | 
						|
                    
 | 
						|
stringM_exit        INC     strDstAddr
 | 
						|
                    LDI     0
 | 
						|
                    POKE    strDstAddr                          ; terminating 0
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringLower
 | 
						|
                    ; creates a lower case string
 | 
						|
stringLower         LDW     strSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    POKE    strDstAddr                          ; dst length = src length
 | 
						|
                    
 | 
						|
stringLo_next       INC     strSrcAddr                          ; next char, (skips length byte)
 | 
						|
                    INC     strDstAddr
 | 
						|
                    LDW     strSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    BEQ     stringLo_exit
 | 
						|
                    ST      strChr
 | 
						|
                    SUBI    65
 | 
						|
                    BLT     stringLo_char
 | 
						|
                    LD      strChr
 | 
						|
                    SUBI    90
 | 
						|
                    BGT     stringLo_char
 | 
						|
                    LD      strChr                              ; >= 65 'A' and <= 90 'Z'
 | 
						|
                    ADDI    32
 | 
						|
                    ST      strChr
 | 
						|
                    
 | 
						|
stringLo_char       LD      strChr
 | 
						|
                    POKE    strDstAddr                          ; lower case char
 | 
						|
                    BRA     stringLo_next
 | 
						|
                    
 | 
						|
stringLo_exit       POKE    strDstAddr                          ; terminating 0
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringUpper
 | 
						|
                    ; creates an upper case string
 | 
						|
stringUpper         LDW     strSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    POKE    strDstAddr                          ; dst length = src length
 | 
						|
    
 | 
						|
stringUp_next       INC     strSrcAddr                          ; next char, (skips length byte)
 | 
						|
                    INC     strDstAddr
 | 
						|
                    LDW     strSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    BEQ     stringUp_exit
 | 
						|
                    ST      strChr
 | 
						|
                    SUBI    97
 | 
						|
                    BLT     stringUp_char
 | 
						|
                    LD      strChr
 | 
						|
                    SUBI    122
 | 
						|
                    BGT     stringUp_char
 | 
						|
                    LD      strChr                              ; >= 97 'a' and <= 122 'z'
 | 
						|
                    SUBI    32
 | 
						|
                    ST      strChr
 | 
						|
                    
 | 
						|
stringUp_char       LD      strChr
 | 
						|
                    POKE    strDstAddr                          ; upper case char
 | 
						|
                    BRA     stringUp_next
 | 
						|
                    
 | 
						|
stringUp_exit       POKE    strDstAddr                          ; terminating 0
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringDigit
 | 
						|
stringDigit         LDW     strInteger
 | 
						|
 | 
						|
stringD_index       SUBW    strMult
 | 
						|
                    BLT     stringD_cont
 | 
						|
                    STW     strInteger
 | 
						|
                    INC     strDigit                            ; calculate digit
 | 
						|
                    BRA     stringD_index
 | 
						|
    
 | 
						|
stringD_cont        LD      strDigit
 | 
						|
                    BEQ     stringD_exit                        ; leading zero supressed
 | 
						|
                    ORI     0x30
 | 
						|
                    POKE    strTmpAddr                          ; store digit
 | 
						|
                    INC     strTmpAddr
 | 
						|
                    LDI     0x30
 | 
						|
                    ST      strDigit                            ; reset digit
 | 
						|
                    
 | 
						|
stringD_exit        RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                stringInt
 | 
						|
                    ; create a string from an int
 | 
						|
stringInt           PUSH
 | 
						|
                    LDI     0
 | 
						|
                    STW     strDigit
 | 
						|
                    LDW     strDstAddr
 | 
						|
                    STW     strTmpAddr
 | 
						|
                    INC     strTmpAddr                          ; skip length byte
 | 
						|
                    LDW     strInteger
 | 
						|
                    BGE     stringI_pos
 | 
						|
                    LDI     0x2D
 | 
						|
                    POKE    strTmpAddr                          ; -ve sign
 | 
						|
                    INC     strTmpAddr
 | 
						|
                    LDI     0
 | 
						|
                    SUBW    strInteger
 | 
						|
                    STW     strInteger                          ; +ve number
 | 
						|
 | 
						|
stringI_pos         LDWI    10000
 | 
						|
                    STW     strMult
 | 
						|
                    LDWI    stringDigit
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    LDWI    1000
 | 
						|
                    STW     strMult
 | 
						|
                    LDWI    stringDigit
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    LDI     100
 | 
						|
                    STW     strMult
 | 
						|
                    LDWI    stringDigit
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    LDI     10
 | 
						|
                    STW     strMult
 | 
						|
                    LDWI    stringDigit
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    LD      strInteger
 | 
						|
                    ORI     0x30
 | 
						|
                    POKE    strTmpAddr                          ; 1's digit
 | 
						|
                    LDW     strTmpAddr
 | 
						|
                    SUBW    strDstAddr
 | 
						|
                    POKE    strDstAddr                          ; length byte
 | 
						|
                    INC     strTmpAddr
 | 
						|
                    LDI     0
 | 
						|
                    POKE    strTmpAddr                          ; terminating 0                    
 | 
						|
                    POP
 | 
						|
                    RET
 | 
						|
%ENDS
 |