⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csr_1hl.asm

📁 Button 一个国外大学生毕业设计,用的是AVR单片机
💻 ASM
📖 第 1 页 / 共 4 页
字号:
   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 + -