272 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
			
		
		
	
	
			272 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
; do *NOT* use register4 to register7 during time slicing
 | 
						|
intSrcA             EQU     register0
 | 
						|
intSrcB             EQU     register1
 | 
						|
intSrcX             EQU     register2
 | 
						|
intSwap             EQU     register3
 | 
						|
intSrcAddr          EQU     register8
 | 
						|
intDigit            EQU     register9
 | 
						|
intResult           EQU     register10
 | 
						|
intNegative         EQU     register11
 | 
						|
bcdLength           EQU     register8
 | 
						|
bcdSrcAddr          EQU     register9
 | 
						|
bcdDstAddr          EQU     register10
 | 
						|
bcdSrcData          EQU     register11
 | 
						|
bcdDstData          EQU     register11          ; alias to make code less confusing
 | 
						|
bcdCarry            EQU     register12
 | 
						|
bcdBorrow           EQU     register12          ; alias to make code less confusing
 | 
						|
bcdValue            EQU     register0
 | 
						|
bcdDigit            EQU     register1
 | 
						|
bcdMult             EQU     register2
 | 
						|
 | 
						|
 | 
						|
%SUB                integerMin
 | 
						|
integerMin          LDW     intSrcA
 | 
						|
                    SUBW    intSrcB
 | 
						|
                    BLE     integerMi_A
 | 
						|
                    LDW     intSrcB
 | 
						|
                    RET
 | 
						|
 | 
						|
integerMi_A         LDW     intSrcA
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                integerMax
 | 
						|
integerMax          LDW     intSrcA
 | 
						|
                    SUBW    intSrcB
 | 
						|
                    BGE     integerMa_A
 | 
						|
                    LDW     intSrcB
 | 
						|
                    RET
 | 
						|
 | 
						|
integerMa_A         LDW     intSrcA
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                integerClamp
 | 
						|
integerClamp        LDW     intSrcX
 | 
						|
                    SUBW    intSrcA
 | 
						|
                    BGE     integerCl_X
 | 
						|
                    BRA     integerCl_A0
 | 
						|
 | 
						|
integerCl_X         LDW     intSrcX
 | 
						|
                    STW     intSrcA
 | 
						|
 | 
						|
integerCl_A0        LDW     intSrcA
 | 
						|
                    SUBW    intSrcB
 | 
						|
                    BLE     integerCl_A1
 | 
						|
                    LDW     intSrcB
 | 
						|
                    RET
 | 
						|
 | 
						|
integerCl_A1        LDW     intSrcA
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                integerStr
 | 
						|
                    ; converts a string to a +/- integer, assumes string pointer is pointing to first char and not the string length, (no overflow or underflow checks)
 | 
						|
integerStr          LDI     0
 | 
						|
                    ST      intNegative
 | 
						|
                    STW     intResult
 | 
						|
                    LDW     intSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    SUBI    45                  ; -ve
 | 
						|
                    BNE     integerS_loop
 | 
						|
                    LDI     1
 | 
						|
                    ST      intNegative
 | 
						|
                    INC     intSrcAddr          ; skip -ve
 | 
						|
 | 
						|
integerS_loop       LDW     intSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    SUBI    48                  ; str[i] - '0'
 | 
						|
                    BLT     integerS_neg
 | 
						|
                    STW     intDigit
 | 
						|
                    SUBI    9
 | 
						|
                    BGT     integerS_neg
 | 
						|
                    LDW     intResult
 | 
						|
                    LSLW
 | 
						|
                    LSLW
 | 
						|
                    ADDW    intResult
 | 
						|
                    LSLW
 | 
						|
                    ADDW    intDigit
 | 
						|
                    STW     intResult           ; result = result*10 + digit
 | 
						|
                    INC     intSrcAddr
 | 
						|
                    BRA     integerS_loop
 | 
						|
          
 | 
						|
integerS_neg        LD      intNegative
 | 
						|
                    BEQ     integerS_exit
 | 
						|
                    LDI     0
 | 
						|
                    SUBW    intResult           ; result *= -1
 | 
						|
                    RET
 | 
						|
                    
 | 
						|
integerS_exit       LDW     intResult
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
                    ; bcd values are stored unpacked lsd to msd
 | 
						|
%SUB                bcdAdd
 | 
						|
bcdAdd              LDI     0
 | 
						|
                    STW     bcdCarry
 | 
						|
                    
 | 
						|
bcdA_loop           LDW     bcdDstAddr
 | 
						|
                    PEEK                        ; expects unpacked byte values 0 to 9
 | 
						|
                    STW     bcdDstData
 | 
						|
                    LDW     bcdSrcAddr
 | 
						|
                    PEEK                        ; expects unpacked byte values 0 to 9
 | 
						|
                    ADDW    bcdDstData
 | 
						|
                    ADDW    bcdCarry
 | 
						|
                    STW     bcdDstData
 | 
						|
                    SUBI    10                  ; no handling of values > 9
 | 
						|
                    BLT     bcdA_nc
 | 
						|
                    STW     bcdDstData
 | 
						|
                    LDI     1
 | 
						|
                    BRA     bcdA_cont
 | 
						|
          
 | 
						|
bcdA_nc             LDI     0
 | 
						|
                    
 | 
						|
bcdA_cont           STW     bcdCarry
 | 
						|
          
 | 
						|
                    LDW     bcdDstData
 | 
						|
                    POKE    bcdDstAddr          ; modifies dst bcd value
 | 
						|
                    INC     bcdDstAddr
 | 
						|
                    INC     bcdSrcAddr
 | 
						|
                    LD      bcdLength
 | 
						|
                    SUBI    1
 | 
						|
                    ST      bcdLength           ; expects src and dst lengths to be equal
 | 
						|
                    BGT     bcdA_loop
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
                    ; bcd values are stored unpacked lsd to msd
 | 
						|
%SUB                bcdSub
 | 
						|
bcdSub              LDI     0
 | 
						|
                    STW     bcdBorrow
 | 
						|
                    
 | 
						|
bcdS_loop           LDW     bcdSrcAddr
 | 
						|
                    PEEK                        ; expects unpacked byte values 0 to 9
 | 
						|
                    STW     bcdSrcData
 | 
						|
                    LDW     bcdDstAddr
 | 
						|
                    PEEK                        ; expects unpacked byte values 0 to 9
 | 
						|
                    SUBW    bcdSrcData
 | 
						|
                    SUBW    bcdBorrow
 | 
						|
                    STW     bcdDstData
 | 
						|
                    BGE     bcdS_nb
 | 
						|
                    ADDI    10
 | 
						|
                    STW     bcdDstData
 | 
						|
                    LDI     1
 | 
						|
                    BRA     bcdS_cont
 | 
						|
          
 | 
						|
bcdS_nb             LDI     0
 | 
						|
                    
 | 
						|
bcdS_cont           STW     bcdBorrow
 | 
						|
          
 | 
						|
                    LDW     bcdDstData
 | 
						|
                    POKE    bcdDstAddr          ; modifies dst bcd value
 | 
						|
                    INC     bcdDstAddr
 | 
						|
                    INC     bcdSrcAddr
 | 
						|
                    LD      bcdLength
 | 
						|
                    SUBI    1
 | 
						|
                    ST      bcdLength           ; expects src and dst lengths to be equal
 | 
						|
                    BGT     bcdS_loop
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                bcdDigits
 | 
						|
bcdDigits           LDW     bcdValue
 | 
						|
 | 
						|
bcdD_index          SUBW    bcdMult
 | 
						|
                    BLT     bcdD_cont
 | 
						|
                    STW     bcdValue
 | 
						|
                    INC     bcdDigit                            ; calculate digit
 | 
						|
                    BRA     bcdD_index
 | 
						|
    
 | 
						|
bcdD_cont           LD      bcdDigit
 | 
						|
                    POKE    bcdDstAddr                          ; store digit
 | 
						|
                    LDW     bcdDstAddr
 | 
						|
                    SUBI    1
 | 
						|
                    STW     bcdDstAddr
 | 
						|
                    LDI     0
 | 
						|
                    ST      bcdDigit                            ; reset digit
 | 
						|
                    
 | 
						|
bcdD_exit           RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                bcdInt
 | 
						|
                    ; create a bcd value from a +ve int, (max 42767)
 | 
						|
bcdInt              PUSH
 | 
						|
                    LDW     bcdDstAddr
 | 
						|
                    ADDI    4
 | 
						|
                    STW     bcdDstAddr                          ; bcdDstAddr must point to >= 5 digit bcd value
 | 
						|
                    LDI     0
 | 
						|
                    STW     bcdDigit
 | 
						|
                    LDWI    10000
 | 
						|
                    STW     bcdMult
 | 
						|
                    LDWI    bcdDigits
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    LDWI    1000
 | 
						|
                    STW     bcdMult
 | 
						|
                    LDWI    bcdDigits
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    LDI     100
 | 
						|
                    STW     bcdMult
 | 
						|
                    LDWI    bcdDigits
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    LDI     10
 | 
						|
                    STW     bcdMult
 | 
						|
                    LDWI    bcdDigits
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    LD      bcdValue
 | 
						|
                    POKE    bcdDstAddr
 | 
						|
                    POP
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
                    ; bcd values are stored unpacked lsd to msd
 | 
						|
                    ; cmp expects addrs to be pointing to msd!
 | 
						|
%SUB                bcdCmp
 | 
						|
bcdCmp              LDW     bcdDstAddr
 | 
						|
                    PEEK                        ; expects unpacked byte values 0 to 9
 | 
						|
                    STW     bcdDstData
 | 
						|
                    LDW     bcdSrcAddr
 | 
						|
                    PEEK                        ; expects unpacked byte values 0 to 9
 | 
						|
                    SUBW    bcdDstData
 | 
						|
                    BGT     bcdC_gt
 | 
						|
                    BLT     bcdC_lt
 | 
						|
                    PUSH
 | 
						|
                    LDWI    bcdCmpExt
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    POP
 | 
						|
                    BGT     bcdCmp
 | 
						|
                    LDI     0
 | 
						|
                    RET
 | 
						|
 | 
						|
bcdC_gt             LDI     1
 | 
						|
                    RET
 | 
						|
                    
 | 
						|
bcdC_lt             LDWI    -1
 | 
						|
                    RET                    
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                bcdCmpExt
 | 
						|
bcdCmpExt           LDW     bcdDstAddr
 | 
						|
                    SUBI    1
 | 
						|
                    STW     bcdDstAddr
 | 
						|
                    LDW     bcdSrcAddr
 | 
						|
                    SUBI    1
 | 
						|
                    STW     bcdSrcAddr
 | 
						|
                    LD      bcdLength
 | 
						|
                    SUBI    1
 | 
						|
                    ST      bcdLength           ; expects src and dst lengths to be equal
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                bcdCpy
 | 
						|
bcdCpy              LDW     bcdSrcAddr
 | 
						|
                    PEEK
 | 
						|
                    POKE    bcdDstAddr
 | 
						|
                    INC     bcdSrcAddr
 | 
						|
                    INC     bcdDstAddr
 | 
						|
                    LD      bcdLength
 | 
						|
                    SUBI    1
 | 
						|
                    ST      bcdLength           ; expects src and dst lengths to be equal
 | 
						|
                    BGT     bcdCpy
 | 
						|
                    RET
 | 
						|
%ENDS
 |