528 lines
17 KiB
OpenEdge ABL
528 lines
17 KiB
OpenEdge ABL
; do *NOT* use register4 to register7 during time slicing
|
|
mathX EQU register8
|
|
mathY EQU register9
|
|
mathSum EQU register12
|
|
mathRem EQU register12
|
|
mathMask EQU register13
|
|
mathSign EQU register14
|
|
mathQuot EQU register15
|
|
mathShift EQU register15
|
|
mathBase EQU register10
|
|
mathPow EQU register11
|
|
mathResult EQU register14
|
|
|
|
|
|
%SUB sign
|
|
sign LDW mathX
|
|
BLE sign_le
|
|
LDI 1
|
|
RET
|
|
|
|
sign_le BLT sign_lt
|
|
LDI 0
|
|
RET
|
|
|
|
sign_lt LDWI 0xFFFF
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB absolute
|
|
absolute LDW mathX
|
|
BGE abs_exit
|
|
LDI 0
|
|
SUBW mathX
|
|
abs_exit RET
|
|
%ENDS
|
|
|
|
%SUB power16bit
|
|
; accumulator = mathX ** mathY, (result 16bit)
|
|
power16bit LDW mathX
|
|
BNE power16_cont0
|
|
LDI 0
|
|
RET
|
|
|
|
power16_cont0 SUBI 1
|
|
BNE power16_cont1
|
|
LDI 1
|
|
RET
|
|
|
|
power16_cont1 LDW mathY
|
|
BNE power16_cont2
|
|
LDI 1
|
|
RET
|
|
|
|
power16_cont2 SUBI 1
|
|
BNE power16_cont3
|
|
LDW mathX ; return mathX
|
|
RET
|
|
|
|
power16_cont3 LDWI SYS_LSRW1_48
|
|
STW giga_sysFn ; setup right shift
|
|
LDW mathX
|
|
STW mathBase
|
|
LDW mathY
|
|
STW mathPow
|
|
LDI 1
|
|
STW mathResult
|
|
PUSH
|
|
LDWI power16bitExt
|
|
CALL giga_vAC
|
|
POP
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB power16bitExt
|
|
power16bitExt PUSH
|
|
LDW mathPow
|
|
|
|
power16E_loop ANDI 1
|
|
BEQ power16E_skip
|
|
LDW mathBase
|
|
STW mathX
|
|
LDW mathResult
|
|
STW mathY
|
|
LDWI multiply16bit
|
|
CALL giga_vAC
|
|
STW mathResult ; mathResult = mathBase * mathResult
|
|
|
|
power16E_skip LDW mathBase
|
|
STW mathX
|
|
STW mathY
|
|
LDWI multiply16bit
|
|
CALL giga_vAC
|
|
STW mathBase ; mathBase = mathBase * mathBase
|
|
LDW mathPow
|
|
SYS 48
|
|
STW mathPow ; mathPow = mathPow / 2
|
|
BNE power16E_loop ; while mathPow > 0
|
|
POP
|
|
LDW mathResult
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB multiply16bit
|
|
; accumulator = mathX * mathY, (result 16bit)
|
|
multiply16bit LDI 0
|
|
STW mathSum
|
|
LDW mathX
|
|
BEQ multiply16_exit ; if x=0 then return 0
|
|
LDWI SYS_LSRW1_48
|
|
STW giga_sysFn
|
|
LDW mathY
|
|
|
|
multiply16_loop BEQ multiply16_exit ; if y=0 then return
|
|
ANDI 1
|
|
BEQ multiply16_skip
|
|
LDW mathSum
|
|
ADDW mathX
|
|
STW mathSum ; mathSum += mathX
|
|
|
|
multiply16_skip LDW mathX
|
|
LSLW
|
|
STW mathX ; mathX = mathX <<1
|
|
LDW mathY
|
|
SYS 48
|
|
STW mathY ; mathY = mathY >>1
|
|
BRA multiply16_loop
|
|
|
|
%if TIME_SLICING
|
|
multiply16_exit PUSH
|
|
CALL realTimeStubAddr
|
|
POP
|
|
LDW mathSum
|
|
%else
|
|
multiply16_exit LDW mathSum
|
|
%endif
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB multiply16bit_1
|
|
; accumulator = mathX * mathY, (result 16bit)
|
|
multiply16bit_1 LDI 0
|
|
STW mathSum
|
|
LDI 1
|
|
|
|
multiply161_loop STW mathMask
|
|
ANDW mathY
|
|
BEQ multiply161_skip
|
|
LDW mathSum
|
|
ADDW mathX
|
|
STW mathSum
|
|
|
|
multiply161_skip LDW mathX
|
|
ADDW mathX
|
|
STW mathX
|
|
LDW mathMask
|
|
ADDW mathMask
|
|
BNE multiply161_loop
|
|
%if TIME_SLICING
|
|
PUSH
|
|
CALL realTimeStubAddr
|
|
POP
|
|
%endif
|
|
LDW mathSum
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB divide16bit
|
|
; accumulator:mathRem = mathX / mathY, (results 16bit)
|
|
divide16bit LDW mathX
|
|
XORW mathY
|
|
STW mathSign
|
|
LDW mathX
|
|
BGE divide16_pos0
|
|
LDI 0
|
|
SUBW mathX
|
|
STW mathX
|
|
|
|
divide16_pos0 LDW mathY
|
|
BGE divide16_pos1
|
|
LDI 0
|
|
SUBW mathY
|
|
STW mathY
|
|
|
|
divide16_pos1 LDI 0
|
|
STW mathRem
|
|
LDI 1
|
|
|
|
divide16_loop STW mathMask
|
|
LDW mathRem
|
|
LSLW
|
|
STW mathRem
|
|
LDW mathX
|
|
BGE divide16_incr
|
|
INC mathRem
|
|
|
|
divide16_incr LDW mathX
|
|
LSLW
|
|
STW mathX
|
|
LDW mathRem
|
|
SUBW mathY
|
|
BLT divide16_incx
|
|
STW mathRem
|
|
INC mathX
|
|
|
|
divide16_incx LDW mathMask
|
|
LSLW
|
|
BNE divide16_loop
|
|
%if TIME_SLICING
|
|
PUSH
|
|
CALL realTimeStubAddr
|
|
POP
|
|
%endif
|
|
LDW mathSign
|
|
BGE divide16_exit
|
|
LDI 0
|
|
SUBW mathX
|
|
RET
|
|
|
|
divide16_exit LDW mathX
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB divide16bit_1
|
|
; accumulator:mathRem = mathX / mathY, (results 16bit)
|
|
divide16bit_1 LDI 0
|
|
STW mathQuot
|
|
STW mathRem
|
|
LDWI SYS_LSRW1_48
|
|
STW giga_sysFn
|
|
|
|
LDW mathX
|
|
XORW mathY
|
|
STW mathSign
|
|
LDW mathX
|
|
BGE divide161_pos0
|
|
LDI 0
|
|
SUBW mathX
|
|
STW mathX
|
|
|
|
divide161_pos0 LDW mathY
|
|
BGE divide161_pos1
|
|
LDI 0
|
|
SUBW mathY
|
|
STW mathY
|
|
|
|
divide161_pos1 LDWI 0x8000
|
|
|
|
divide161_loop STW mathMask
|
|
BEQ divide161_exit
|
|
LDW mathRem
|
|
LSLW
|
|
STW mathRem
|
|
LDW mathX
|
|
ANDW mathMask
|
|
BEQ divide161_skip1
|
|
INC mathRem
|
|
|
|
divide161_skip1 LDW mathRem
|
|
SUBW mathY
|
|
BLT divide161_skip2
|
|
STW mathRem
|
|
LDW mathQuot
|
|
ORW mathMask
|
|
STW mathQuot
|
|
|
|
divide161_skip2 LDW mathMask
|
|
SYS 48
|
|
BRA divide161_loop
|
|
|
|
%if TIME_SLICING
|
|
divide161_exit PUSH
|
|
CALL realTimeStubAddr
|
|
POP
|
|
LDW mathSign
|
|
%else
|
|
divide161_exit LDW mathSign
|
|
%endif
|
|
BLT divide161_sgn
|
|
LDW mathQuot
|
|
RET
|
|
|
|
divide161_sgn LDI 0
|
|
SUBW mathQuot
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB rand16bit
|
|
rand16bit LDWI SYS_Random_34
|
|
STW giga_sysFn
|
|
SYS 34
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB randMod16bit
|
|
randMod16bit PUSH
|
|
LDWI SYS_Random_34
|
|
STW giga_sysFn
|
|
SYS 34
|
|
STW mathX
|
|
LDWI divide16bit
|
|
CALL giga_vAC
|
|
LDW mathRem
|
|
POP
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftLeft4bit
|
|
shiftLeft4bit LDWI SYS_LSLW4_46
|
|
STW giga_sysFn
|
|
LDW mathShift
|
|
SYS 46
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftLeft8bit
|
|
shiftLeft8bit LDWI SYS_LSLW8_24
|
|
STW giga_sysFn
|
|
LDW mathShift
|
|
SYS 28
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRight1bit
|
|
shiftRight1bit LDWI SYS_LSRW1_48
|
|
STW giga_sysFn
|
|
LDW mathShift
|
|
SYS 48
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRight2bit
|
|
shiftRight2bit LDWI SYS_LSRW2_52
|
|
STW giga_sysFn
|
|
LDW mathShift
|
|
SYS 52
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRight3bit
|
|
shiftRight3bit LDWI SYS_LSRW3_52
|
|
STW giga_sysFn
|
|
LDW mathShift
|
|
SYS 52
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRight4bit
|
|
shiftRight4bit LDWI SYS_LSRW4_50
|
|
STW giga_sysFn
|
|
LDW mathShift
|
|
SYS 50
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRight5bit
|
|
shiftRight5bit LDWI SYS_LSRW5_50
|
|
STW giga_sysFn
|
|
LDW mathShift
|
|
SYS 50
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRight6bit
|
|
shiftRight6bit LDWI SYS_LSRW6_48
|
|
STW giga_sysFn
|
|
LDW mathShift
|
|
SYS 48
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRight7bit
|
|
shiftRight7bit LDWI SYS_LSRW7_30
|
|
STW giga_sysFn
|
|
LDW mathShift
|
|
SYS 30
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRight8bit
|
|
shiftRight8bit LDWI SYS_LSRW8_24
|
|
STW giga_sysFn
|
|
LDW mathShift
|
|
SYS 28
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRightSgn1bit
|
|
shiftRightSgn1bit LDWI SYS_LSRW1_48
|
|
STW giga_sysFn
|
|
LDWI 0x8000
|
|
STW mathSign
|
|
ANDW mathShift
|
|
BEQ shiftRS1_pos ; check sign
|
|
LDW mathShift
|
|
SYS 48 ; shift right 1
|
|
ORW mathSign ; fix sign
|
|
RET
|
|
|
|
shiftRS1_pos LDW mathShift ; positive number
|
|
SYS 48
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRightSgn2bit
|
|
shiftRightSgn2bit LDWI SYS_LSRW2_52
|
|
STW giga_sysFn
|
|
LD mathShift + 1
|
|
ANDI 0x80
|
|
BEQ shiftRS2_pos ; check sign
|
|
LDWI 0xC000
|
|
STW mathSign
|
|
LDW mathShift
|
|
SYS 52 ; shift right 2
|
|
ORW mathSign ; fix sign
|
|
RET
|
|
|
|
shiftRS2_pos LDW mathShift ; positive number
|
|
SYS 52
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRightSgn3bit
|
|
shiftRightSgn3bit LDWI SYS_LSRW3_52
|
|
STW giga_sysFn
|
|
LD mathShift + 1
|
|
ANDI 0x80
|
|
BEQ shiftRS3_pos ; check sign
|
|
LDWI 0xE000
|
|
STW mathSign
|
|
LDW mathShift
|
|
SYS 52 ; shift right 3
|
|
ORW mathSign ; fix sign
|
|
RET
|
|
|
|
shiftRS3_pos LDW mathShift ; positive number
|
|
SYS 52
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRightSgn4bit
|
|
shiftRightSgn4bit LDWI SYS_LSRW4_50
|
|
STW giga_sysFn
|
|
LD mathShift + 1
|
|
ANDI 0x80
|
|
BEQ shiftRS4_pos ; check sign
|
|
LDWI 0xF000
|
|
STW mathSign
|
|
LDW mathShift
|
|
SYS 50 ; shift right 4
|
|
ORW mathSign ; fix sign
|
|
RET
|
|
|
|
shiftRS4_pos LDW mathShift ; positive number
|
|
SYS 50
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRightSgn5bit
|
|
shiftRightSgn5bit LDWI SYS_LSRW5_50
|
|
STW giga_sysFn
|
|
LD mathShift + 1
|
|
ANDI 0x80
|
|
BEQ shiftRS5_pos ; check sign
|
|
LDWI 0xF800
|
|
STW mathSign
|
|
LDW mathShift
|
|
SYS 50 ; shift right 5
|
|
ORW mathSign ; fix sign
|
|
RET
|
|
|
|
shiftRS5_pos LDW mathShift ; positive number
|
|
SYS 50
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRightSgn6bit
|
|
shiftRightSgn6bit LDWI SYS_LSRW6_48
|
|
STW giga_sysFn
|
|
LD mathShift + 1
|
|
ANDI 0x80
|
|
BEQ shiftRS6_pos ; check sign
|
|
LDWI 0xFC00
|
|
STW mathSign
|
|
LDW mathShift
|
|
SYS 48 ; shift right 6
|
|
ORW mathSign ; fix sign
|
|
RET
|
|
|
|
shiftRS6_pos LDW mathShift ; positive number
|
|
SYS 48
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRightSgn7bit
|
|
shiftRightSgn7bit LDWI SYS_LSRW7_30
|
|
STW giga_sysFn
|
|
LD mathShift + 1
|
|
ANDI 0x80
|
|
BEQ shiftRS7_pos ; check sign
|
|
LDWI 0xFE00
|
|
STW mathSign
|
|
LDW mathShift
|
|
SYS 30 ; shift right 7
|
|
ORW mathSign ; fix sign
|
|
RET
|
|
|
|
shiftRS7_pos LDW mathShift ; positive number
|
|
SYS 30
|
|
RET
|
|
%ENDS
|
|
|
|
%SUB shiftRightSgn8bit
|
|
shiftRightSgn8bit LDWI SYS_LSRW8_24
|
|
STW giga_sysFn
|
|
LD mathShift + 1
|
|
ANDI 0x80
|
|
BEQ shiftRS8_pos ; check sign
|
|
LDWI 0xFF00
|
|
STW mathSign
|
|
LDW mathShift
|
|
SYS 28 ; shift right 8
|
|
ORW mathSign ; fix sign
|
|
RET
|
|
|
|
shiftRS8_pos LDW mathShift ; positive number
|
|
SYS 28
|
|
RET
|
|
%ENDS |