?? csr_1hl.asm
字號:
mov X, A
index CSR_1_Diplex_Table ; get the diplex table MSB and LSB
mov [CSR_1_bDiplexMSB], A
mov A, X
inc A
index CSR_1_Diplex_Table
mov [CSR_1_bDiplexLSB], A
mov A, X
asl A
mov X, A
index CSR_1_Group_Table ; get first switch index
mov [CSR_1_bEndOfArray], A
mov [CSR_1_bCurPos], A
mov [CSR_1_bStartIndex], A
mov A, X
inc A
index CSR_1_Group_Table ; get size of group
add [CSR_1_bEndOfArray], A ; Store for later
mov A, X
add A, 2
index CSR_1_Group_Table ; get if diplexed or not and max size of centroid (data = 0 if not diplexed)
mov [CSR_1_bDiplexInfo], A ; Store for later
mov A, X
add A, 3
index CSR_1_Group_Table ; get divisions per switch fixed point multiplier
mov [CSR_1_bDivBtwSw], A ; Store for later
; First find the starting location and size of the largest centroid
mov [CSR_1_bBiggestCtrdStartPos], 0
mov [CSR_1_bBiggestCtrdSize], 0
mov [CSR_1_bCurCtrdStartPos], 0
mov [CSR_1_bCurCtrdSize], 0
mov A, [CSR_1_bStartIndex]
asl A ; multiply by two because we are using ints
mov X, A
.LocateCtrd:
mov A, [X+CSR_1_iaSwDiff]
jnz .DiffIsNotZero
mov A, [X+CSR_1_iaSwDiff+1]
jnz .DiffIsNotZero
; The difference is zero, we either just ended a centroid or are between centroids
; First check the Current Size, if zero, we are in the middle of zeros, else, we just ended
.DifferenceIsZero:
mov A, [CSR_1_bCurCtrdSize]
jz .LocateCtrdNextSwitch
; A centroid just ended. Is it the largest centroid?
cmp A, [CSR_1_bBiggestCtrdSize]
jc .ClearCurCtrdSize
; It is the biggest so far, store as biggest
mov [CSR_1_bBiggestCtrdSize], [CSR_1_bCurCtrdSize]
mov [CSR_1_bBiggestCtrdStartPos], [CSR_1_bCurCtrdStartPos]
.ClearCurCtrdSize:
mov [CSR_1_bCurCtrdSize], 0
jmp .LocateCtrdNextSwitch
;The difference is not zero, we either just started, or are in the middle of a centroid
.DiffIsNotZero:
mov A, [CSR_1_bCurCtrdSize]
jnz .IncCtrdSize
; Centroid just began, store the start pos
mov A, [CSR_1_bCurPos]
mov [CSR_1_bCurCtrdStartPos], A
.IncCtrdSize:
inc [CSR_1_bCurCtrdSize]
; Find out the next position
.LocateCtrdNextSwitch:
inc X
inc X
inc [CSR_1_bCurPos]
mov A, [CSR_1_bCurPos]
cmp A, [CSR_1_bEndOfArray] ; Check for the end of the array
jc .LocateCtrd
; Either at end of array, or diplexed
tst [CSR_1_bDiplexInfo], 0xff ; check if diplexed
jz .EndOfLocateCtrd
; Diplexed, so now find out if at end
sub A, [CSR_1_bEndOfArray] ; subtract the size of the array
add A, [CSR_1_bStartIndex] ; for comparison
cmp A, [CSR_1_bEndOfArray] ; Check for the end of the array
jnc .EndOfLocateCtrd
; Not the end of the diplexed array, find out offset of next position
mov A, [CSR_1_bCurPos]
sub A, [CSR_1_bStartIndex]
add A, [CSR_1_bDiplexLSB]
mov X, A
mov A, [CSR_1_bDiplexMSB]
adc A, 0 ; check if carry
romx ; get the offset from the start
add A, [CSR_1_bStartIndex]
asl A ; because using ints
mov X, A
jmp .LocateCtrd
.EndOfLocateCtrd:
; Need to check if the current centroid is biggest
mov A, [CSR_1_bCurCtrdSize]
jz .CalculateCtrd
; There was a centroid at the end, is it biggest?
cmp A, [CSR_1_bBiggestCtrdSize]
jc .CalculateCtrd ; if two are the same size, last one wins
; It is the biggest so far, store as biggest
mov [CSR_1_bBiggestCtrdSize], [CSR_1_bCurCtrdSize]
mov [CSR_1_bBiggestCtrdStartPos], [CSR_1_bCurCtrdStartPos]
.CalculateCtrd:
mov A, [CSR_1_bDiplexInfo] ; check if diplexed
jz .COM_Init
cmp [CSR_1_bBiggestCtrdSize], 2
jc .COM_Error ; for diplexing, one or less is too small
cmp A, [CSR_1_bBiggestCtrdSize]
jc .COM_Error ; for diplexing, check if centroid is too large
.COM_Init:
mov A, [CSR_1_bBiggestCtrdStartPos] ; Use for current position, may be diplexed
mov [CSR_1_bCurPos], A
mov [CSR_1_iDenom+1], 0 ; Clear the numerator and denominator
mov [CSR_1_iDenom], 0
mov [CSR_1_iNumer+2], 0
mov [CSR_1_iNumer+1], 0
mov [CSR_1_iNumer], 0
.COM_NextPosition:
mov A, [CSR_1_bCurPos]
cmp A, [CSR_1_bEndOfArray]
jnc .COM_CheckDiplex
asl A
mov X, A
jmp .COM_AddElement
; Must be diplexed, check for safe measure
.COM_CheckDiplex:
tst [CSR_1_bDiplexInfo], 0xff ; check if diplexed
jz .COM_Compute
; Find out offset of next position
mov A, [CSR_1_bCurPos]
sub A, [CSR_1_bStartIndex]
add A, [CSR_1_bDiplexLSB]
mov X, A
mov A, [CSR_1_bDiplexMSB]
adc A, 0 ; check if carry
romx ; get the offset from the start
add A, [CSR_1_bStartIndex]
asl A ; because using ints
mov X, A
.COM_AddElement:
; Store a copy of the switch difference in CSR_1_iMultTempX
mov A, [X+CSR_1_iaSwDiff+1]
mov [CSR_1_iMultTempX+2], A
; Add LSB to denominator
add [CSR_1_iDenom+1], A
mov A, [X+CSR_1_iaSwDiff]
mov [CSR_1_iMultTempX+1], A
mov [CSR_1_iMultTempX], 0
; Add MSB to denominator
adc [CSR_1_iDenom], A
mov A, [CSR_1_bCurPos]
sub A, [CSR_1_bStartIndex] ; we need offset from beginning of group
mov [CSR_1_bSwMaskPtr], A ; This is our multiplier (an unused temp)
call .MultiplyNumeratorWhole
inc [CSR_1_bCurPos]
dec [CSR_1_bBiggestCtrdSize]
jz .COM_Compute
jmp .COM_NextPosition
.COM_Compute:
mov A, [CSR_1_iNumer+2] ; Move numerator to temp
mov [CSR_1_iMultTempX+2], A
mov [CSR_1_iMultTempY+2], A
mov A, [CSR_1_iNumer+1]
mov [CSR_1_iMultTempX+1], A
mov [CSR_1_iMultTempY+1], A
mov A, [CSR_1_iNumer]
mov [CSR_1_iMultTempX], A
mov [CSR_1_iMultTempY], A
mov [CSR_1_iNumer+2], 0 ; Clear numerator
mov [CSR_1_iNumer+1], 0 ; Clear numerator
mov [CSR_1_iNumer], 0
mov A, [CSR_1_bDivBtwSw]
and F, ~0x04
rrc A
asr A
asr A
asr A
mov [CSR_1_bSwMaskPtr], A ; Multiplier for numerator
call .MultiplyNumeratorWhole ; Multiplies by whole part
mov [CSR_1_bSwMaskPtr], [CSR_1_bDivBtwSw]
call .MultiplyNumeratorFraction ; Multiplies by fractional part
; Now do the division of the numerator and denominator
; Round up the temp by half of the denominator (0.5 gets 1)
mov A, [CSR_1_iDenom]
mov [CSR_1_iMultTempX+1], A
mov A, [CSR_1_iDenom+1]
mov [CSR_1_iMultTempX+2], A
and F, ~0x04 ; Clear carry bit if set
rrc [CSR_1_iMultTempX+1] ; divide denominator by 2
rrc [CSR_1_iMultTempX+2]
mov A, [CSR_1_iMultTempX+2]
add [CSR_1_iNumer+2], A ; add 1/2 denominator
mov A, [CSR_1_iMultTempX+1]
adc [CSR_1_iNumer+1], A
adc [CSR_1_iNumer], 0
; Compute the division of numerator/denominator
mov [CSR_1_bCtrdPos], 0 ; Now will contain current position
.COM_Divide:
mov A, [CSR_1_iDenom+1]
sub [CSR_1_iNumer+2], A
mov A, [CSR_1_iDenom]
sbb [CSR_1_iNumer+1], A
sbb [CSR_1_iNumer], 0
jc .Finished_Ctrd_Position
inc [CSR_1_bCtrdPos]
jmp .COM_Divide
; We are finished, position is in [CSR_1_bCtrdPos]
.COM_Error:
mov A, 0xff
jmp .End_Ctrd_Function
.Finished_Ctrd_Position:
mov A, [CSR_1_bCtrdPos]
.End_Ctrd_Function:
RAM_RESTORE_NATIVE_PAGING
RAM_EPILOGUE RAM_USE_CLASS_4
ret
; Multiplication algorithm (for whole numbers)
.MultiplyNumeratorWhole:
tst [CSR_1_bSwMaskPtr], 0x01 ; See if one needs added
jz .OneFinished
mov A, [CSR_1_iMultTempX+2]
add [CSR_1_iNumer+2], A
mov A, [CSR_1_iMultTempX+1]
adc [CSR_1_iNumer+1], A
mov A, [CSR_1_iMultTempX]
adc [CSR_1_iNumer], A
.OneFinished:
asl [CSR_1_iMultTempX+2]
rlc [CSR_1_iMultTempX+1]
rlc [CSR_1_iMultTempX]
tst [CSR_1_bSwMaskPtr], 0x02 ; See if two needs added
jz .TwoFinished
mov A, [CSR_1_iMultTempX+2]
add [CSR_1_iNumer+2], A
mov A, [CSR_1_iMultTempX+1]
adc [CSR_1_iNumer+1], A
mov A, [CSR_1_iMultTempX]
adc [CSR_1_iNumer], A
.TwoFinished:
asl [CSR_1_iMultTempX+2]
rlc [CSR_1_iMultTempX+1]
rlc [CSR_1_iMultTempX]
tst [CSR_1_bSwMaskPtr], 0x04 ; See if four needs added
jz .FourFinished
mov A, [CSR_1_iMultTempX+2]
add [CSR_1_iNumer+2], A
mov A, [CSR_1_iMultTempX+1]
adc [CSR_1_iNumer+1], A
mov A, [CSR_1_iMultTempX]
adc [CSR_1_iNumer], A
.FourFinished:
asl [CSR_1_iMultTempX+2]
rlc [CSR_1_iMultTempX+1]
rlc [CSR_1_iMultTempX]
tst [CSR_1_bSwMaskPtr], 0x08 ; See if eight needs added
jz .EightFinished
mov A, [CSR_1_iMultTempX+2]
add [CSR_1_iNumer+2], A
mov A, [CSR_1_iMultTempX+1]
adc [CSR_1_iNumer+1], A
mov A, [CSR_1_iMultTempX]
adc [CSR_1_iNumer], A
.EightFinished:
asl [CSR_1_iMultTempX+2]
rlc [CSR_1_iMultTempX+1]
rlc [CSR_1_iMultTempX]
tst [CSR_1_bSwMaskPtr], 0x10 ; See if sixteen needs added
jz .SixteenFinished
mov A, [CSR_1_iMultTempX+2]
add [CSR_1_iNumer+2], A
mov A, [CSR_1_iMultTempX+1]
adc [CSR_1_iNumer+1], A
mov A, [CSR_1_iMultTempX]
adc [CSR_1_iNumer], A
.SixteenFinished:
asl [CSR_1_iMultTempX+2]
rlc [CSR_1_iMultTempX+1]
rlc [CSR_1_iMultTempX]
tst [CSR_1_bSwMaskPtr], 0x20 ; See if thirtytwo needs added
jz .ThirtytwoFinished
mov A, [CSR_1_iMultTempX+2]
add [CSR_1_iNumer+2], A
mov A, [CSR_1_iMultTempX+1]
adc [CSR_1_iNumer+1], A
mov A, [CSR_1_iMultTempX]
adc [CSR_1_iNumer], A
.ThirtytwoFinished:
asl [CSR_1_iMultTempX+2]
rlc [CSR_1_iMultTempX+1]
rlc [CSR_1_iMultTempX]
tst [CSR_1_bSwMaskPtr], 0x40 ; See if sixtyfour needs added
jz .SixtyfourFinished
mov A, [CSR_1_iMultTempX+2]
add [CSR_1_iNumer+2], A
mov A, [CSR_1_iMultTempX+1]
adc [CSR_1_iNumer+1], A
mov A, [CSR_1_iMultTempX]
adc [CSR_1_iNumer], A
.SixtyfourFinished:
ret
; Multiplication algorithm (for fractional numbers)
.MultiplyNumeratorFraction:
and F, ~0x04 ; clear carry bit if set
rrc [CSR_1_iMultTempY]
rrc [CSR_1_iMultTempY+1]
rrc [CSR_1_iMultTempY+2]
tst [CSR_1_bSwMaskPtr], 0x08 ; See if half needs added
jz .HalfFinished
mov A, [CSR_1_iMultTempY+2]
add [CSR_1_iNumer+2], A
mov A, [CSR_1_iMultTempY+1]
adc [CSR_1_iNumer+1], A
mov A, [CSR_1_iMultTempY]
adc [CSR_1_iNumer], A
.HalfFinished:
asr [CSR_1_iMultTempY]
rrc [CSR_1_iMultTempY+1]
rrc [CSR_1_iMultTempY+2]
tst [CSR_1_bSwMaskPtr], 0x04 ; See if quarter needs added
jz .QuarterFinished
mov A, [CSR_1_iMultTempY+2]
add [CSR_1_iNumer+2], A
mov A, [CSR_1_iMultTempY+1]
adc [CSR_1_iNumer+1], A
mov A, [CSR_1_iMultTempY]
adc [CSR_1_iNumer], A
.QuarterFinished:
asr [CSR_1_iMultTempY]
rrc [CSR_1_iMultTempY+1]
rrc [CSR_1_iMultTempY+2]
tst [CSR_1_bSwMaskPtr], 0x02 ; See if eighth needs added
jz .EigthFinished
mov A, [CSR_1_iMultTempY+2]
add [CSR_1_iNumer+2], A
mov A, [CSR_1_iMultTempY+1]
adc [CSR_1_iNumer+1], A
mov A, [CSR_1_iMultTempY]
adc [CSR_1_iNumer], A
.EigthFinished:
asr [CSR_1_iMultTempY]
rrc [CSR_1_iMultTempY+1]
rrc [CSR_1_iMultTempY+2]
tst [CSR_1_bSwMaskPtr], 0x01 ; See if sixteenth needs added
jz .SixteenthFinished
mov A, [CSR_1_iMultTempY+2]
add [CSR_1_iNumer+2], A
mov A, [CSR_1_iMultTempY+1]
adc [CSR_1_iNumer+1], A
mov A, [CSR_1_iMultTempY]
adc [CSR_1_iNumer], A
.SixteenthFinished:
ret
.ENDSECTION
ENDIF
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -