📄 test.asm
字号:
;interpolated VALUE
MPY AG2 ;Multiply VALUE by a magnitude
PAC ;Move the product to ACC
SACH AC1VAL,1 ;Store the new value, shift to get Q15
LDP 0 ;This section outputs the SINE wave
;to the DAC
LACC AC0VAL ;ACC = DAC0VAL - entry from the
;lookup table
ADD 000h ;Displace the value half the maximum
SFR ;Shift over 4 places since the DAC is
;12bits
SFR
SFR
SFR
SACL AC0VAL ;Store the new 12 bit value into DAC0VAL
LACC AC1VAL ;ACC = DAC0VAL - entry from the
;lookup table
ADD 8000h ;Displace the value half the maximum
SFR ;Shift over 4 places since the DAC is
;12bits
SFR
SFR
SFR
SACL AC1VAL ;Store the new 12 bit value into DAC0VAL
OUT AC0VAL,DAC0 ;Stores the 12 bit value
;into DAC0 register
OUT AC1VAL,DAC1 ;Stores the 12 bit value
;into DAC1 register
OUT AC0VAL,DACUPDATE;Causes the DAC to output the value
RESUME
LDP 232 ;DP = 232 - DP for Event Manager
LACC VIFRA ;Load EVIFRA - Type A Interrupt Flags
SACL VIFRA ;Clear the Interrupt Flags
B ITING
;I S R - INT1_ISR
INT1_ISR
LDP 0E0h ;DP = 224 Address 7000h-707Fh
LACL YSIVR ;Load peripheral INT vector address
LDP 0000h ;DP = 0 Addresses 0000h-007Fh
SUB 0006h ;Subtract RXINT offset from above
BCND X_ISR,EQ ;verify RXINT initiated interrupt
B D_INT ;Else, bad interrupt occurred
RX_ISR
MAR ,AR1 ;ARP = AR1
LACC ;Load ACC w/RX buffer character
BIT BIT6,AR3 ;Determine if the character is a letter
BCND NUMBER,NTC
AND 01011111b ;If a letter, capitalize the letter
NUMBER
SACL *+ ;Store the character/number
IP_VALUE
SUB #000Dh ;Check to see if <CR>
BCND CHECK_IP,EQ ;If value entered is a <CR>, then
;process input
B NO_IP ;else, wait until <CR> is pressed
CHECK_IP
LAR AR3,#B0_SADDR ;AR3 = Address of first value entered
LACC *+ ;ACC = ASCII equivalent of value
SUB #0046h ;Check to see if ASCII letter 'F'
BCND FREQ_CHG,EQ ;If 'F' goto routine to change frequency
ADD #0046h
SUB #0050h ;Check to see if ASCII letter 'P'
BCND PHASE_CHG,EQ ;If 'P' goto routine to change frequency
ADD #0050h
SUB #004Dh ;Check to see if ASCII letter 'M'
BCND MAG_CHG,EQ ;If 'M' goto routine to change frequency
ADD #004Dh
SUB #000Dh ;Check to see if ASCII <CR>
BCND SCI_ISR,EQ ;If <CR>, output "Ready"
B BAD_IP
B ISR_END ;If neither a 'F','P','M',or<CR>,
;then do nothing
BAD_IP
LAR AR2,#(B1_SADDR+LENGTH1)
;Address to output
;"Invalid Input"
SCI_ISR
MAR *,AR2 ;ARP = AR2
LDP #00E0h ;DP = 224 Addresses 7000h-707Fh
XMIT_CHAR
LACC *+,AR0 ;Load char to be xmitted into ACC
BCND ISR_END,EQ ;Check for Null Character
;YES? Return from INT1_ISR.
SACL *,AR2 ;NO? Load char into xmit buffer.
XMIT_RDY
BIT SCICTL2, BIT7 ;Test TXRDY bit
BCND XMIT_RDY, NTC ;If TXRDY=0,then repeat loop
B XMIT_CHAR ;else xmit next character
ISR_END
LAR AR2, #B1_SADDR ;Reload AR2 w/ TX data start address
LAR AR3, #B0_SADDR ;Reload AR3 w/ RX data start address
LDP #00E0h ;DP = 224 Addresses 7000h-707Fh
LACC #0Ah ;Cause a line feed in the terminal
SACL SCITXBUF ;transmit the line feed
LDP #0 ;DP = 0 Addresses 0000h-007Fh
CLRC INTM ;Enable Interrrupts
RET ;Return from INT1_ISR
NO_IP
LAR AR2, #B1_SADDR ;Reload AR2 w/ TX data start address
LDP #0 ;DP = 0 Addresses 0000h-007Fh
CLRC INTM ;Enable Interrupts
RET ;Return from interrupt
BAD_INT
LACC #0BADh ;Load ACC with "bad"
B BAD_INT ;Repeat loop
;The following section will modify the frequency of the specified channel
FREQ_CHG
LDP #0 ;DP = 0 Addresses 0000h -007Fh
SPLK #0000h,NEW_VALUE;Initialize NEW_VALUE
LACC *+
SUB #0041h ;Check whether to modify Channel A
BCND FREQ_A,EQ ;If 'A', goto part that
;modifies Chan. A
ADD #0041h
SUB #0042h ;Check whether to modify Channel B
BCND FREQ_B,EQ ;If 'B', goto part that
;modifies Chan. B
ADD #0042h
SUB #0052h ;Check whether to reset the Channels
BCND FREQ_RESET,EQ
B BAD_IP ;Else, bad input so end routine
FREQ_B
LACC FREQSTEP2 ;ACC = FREQSTEP2
SACL PREV_VALUE ;Keep the previous value in case
;the new value is invalid
CALL WHAT_VALUE ;Determine the entered frequency
LACC NEW_VALUE ;ACC = entered value
SUB PREV_VALUE ;If entered value is the same
;as the prev
BCND NO_CHGB,EQ ;then, the entered value was invalid,
;So nothing changes, else
CALL FSTEP_VALUE ;Determine the equivalent step value
NO_CHGB
LACC NEW_VALUE ;ACC = New step value
SACL FREQSTEP2 ;FREQSTEP2 = New step value
B ISR_END ;End of the frequency change
;for Chan. B
FREQ_A
LACC FREQSTEP1 ;ACC = FREQSTEP1
SACL PREV_VALUE ;Keep the previous value in case
;the new value is invalid
CALL WHAT_VALUE ;Determine the entered frequency
LACC NEW_VALUE ;ACC = entered value
SUB PREV_VALUE ;If entered value is the same
;as the prev
BCND NO_CHGA,EQ ;then, the entered value was
;invalid, so nothing changes, else
CALL FSTEP_VALUE ;Determine the equivalent step value
NO_CHGA
LACC NEW_VALUE ;ACC = New step value
SACL FREQSTEP1 ;FREQSTEP1 = New Step Value
B ISR_END ;End of the frequency change
;for Chan. A
FREQ_RESET
SPLK #1000,FREQSTEP1 ;Initialize Channel A to original value
SPLK #1000,FREQSTEP2 ;Initialize Channel B to original value
B ISR_END
;Converts the entered frequency into a step value
FSTEP_VALUE
LT NEW_VALUE ;TREG = NEW_VALUE
MPY #QT1PERIOD ;Multiply by the "sampling period"
PAC ;ACC = PREG
SACL NEW_VALUE,1 ;Store the new step value
RET ;Return from routine
;The following section will modify the phase of the specified channel
PHASE_CHG
LDP #0 ;DP = 0 Addresses 0000h -007Fh
SPLK #360,DIVISOR ;Initialize the max value to 360 deg
SPLK #0000h,QUOTIENT ;Initialize the quotient value
SPLK #0000h,NEW_VALUE;Initialize NEW_VALUE
LACC *+
SUB #0041h ;Check whether to modify Channel A
BCND PHASE_A,EQ
ADD #0041h
SUB #0042h ;Check whether to modify Channel B
BCND PHASE_B,EQ
ADD #0042h
SUB #0052h ;Check whether to reset the Channels
BCND PHASE_RESET,EQ
B BAD_IP ;Else, bad input so end routine
PHASE_B
LACC MODREG2 ;Load the Modulo Register of Channel B
SACL PREV_VALUE ;Save the value in case the entered
;value is invalid
CALL WHAT_VALUE ;Determine the entered phase
LACC NEW_VALUE ;Load the value
SUB PREV_VALUE ;If input value is invalid,WHAT_VALUE
BCND ISR_END,EQ ;sets NEXT_VALUE=PREV_VALUE
ADD PREV_VALUE
SUB #360 ;If input is a number, then
BCND BAD_IP,GT ;Check if value is larger than 360 deg
ADD #360
CALL DIVIDE ;If the value is okay, then determine
;what the Q15 fraction the
;value is of 360
LT QUOTIENT ;TREG = QUOTIENT
MPY #100h ;PREG = QUOTIENT * 256
PAC ;ACC = PREG
SACH NEW_VALUE,1 ;NEW_VALUE=QUOTIENT *256,Shift by 1 to
;remove extra sign bit
LACC NEW_VALUE,8 ;ACC = NEW_VALUE * 256
ADD MODREG1 ;Add the Modulo Register of Channel A
SACL MODREG2 ;Store the new value for Channel B
B ISR_END ;End of phase shift for Channel B
PHASE_A
LACC MODREG1 ;Load the Modulo Register of Channel A
SACL PREV_VALUE ;Save the value in case the entered value
;is invalid
CALL WHAT_VALUE ;Determine the entered phase
LACC NEW_VALUE ;Load the value
SUB PREV_VALUE ;If input value is invalid, WHAT_VALUE
BCND ISR_END,EQ ;sets NEXT_VALUE=PREV_VALUE
ADD PREV_VALUE
SUB #360 ;If input is a number, then
BCND BAD_IP,GT ;Check if value is larger than 360 degrees
ADD #360
CALL DIVIDE ;If the value is okay, then determine
;what the Q15 fraction the
;value is of 360
LT QUOTIENT ;TREG = QUOTIENT
MPY #100h ;PREG = QUOTIENT * 256
PAC ;ACC = PREG
SACH NEW_VALUE,1 ;NEW_VALUE = QUOTIENT * 256;Shift by 1
;To remove extra sign bit
LACC NEW_VALUE,8 ;ACC = NEW_VALUE * 256
ADD MODREG2 ;Add the Modulo Register of Channel B
SACL MODREG1 ;Store the new value for Channel A
B ISR_END ;End of phase shift for Channel A
PHASE_RESET
SPLK #0000h,MODREG1 ;Initialize Channel A to original value
SPLK #0000h,MODREG2 ;Initialize Channel B to original value
B ISR_END
;The following section will modify the magnitude of the specified channel
MAXMAG .equ 50
MAG_CHG
LDP #0 ;DP = 0 Addresses 0000h - 007Fh
SPLK #MAXMAG,DIVISOR ;Initialize DIVISOR
SPLK #7FFFh,TEMP ;Initialize TEMP
SPLK #0000h,QUOTIENT ;Initialize QUOTIENT
SPLK #0000h,NEW_VALUE;Initialize NEW_VALUE
LACC *+
SUB #0041h
BCND MAG_A,EQ ;Check whether to modify Channel A
ADD #0041h
SUB #0042h
BCND MAG_B,EQ ;Check whether to modify Channel B
ADD #0042h
SUB #0052h ;Check whether to reset the Channels
BCND MAG_RESET,EQ
B BAD_IP ;Else, bad input so end routine
MAG_B
LACC MAG2 ;ACC = MAG2
SACL PREV_VALUE ;Store the current magnitude in case
;the input value is invalid
CALL WHAT_VALUE ;Determine the entered magnitude
LACC NEW_VALUE ;ACC = Entered Value
SUB PREV_VALUE ;If input value is invalid,WHAT_VALUE
BCND ISR_END,EQ ;sets NEXT_VALUE=PREV_VALUE
ADD PREV_VALUE
SUB #MAXMAG ;If input is a number, then
BCND BAD_IP,GT ;Check if value is larger than MAXMAG
ADD #MAXMAG
CALL DIVIDE ;If the value is okay,determine what
;proportion the entered
;value is of MAXMAG
CALL MAG_VALUE ;Normalize the ratio to the maximum
;Q15 value
LACC NEW_VALUE
AND #7FFFh ;Make sure the value is positive
SACL MAG2 ;Store the new magnitude for Channel B
B ISR_END ;End of modifying magnitude
;for Channel B
MAG_A
LACC MAG1 ;ACC = MAG1
SACL PREV_VALUE ;Store the current magnitude in case
;the input value is invalid
CALL WHAT_VALUE ;determine the entered magnitude
LACC NEW_VALUE ;ACC = Entered value
SUB PREV_VALUE ;If input value is invalid, WHAT_VALUE
BCND ISR_END,EQ ;sets NEXT_VALUE=PREV_VALUE
ADD PREV_VALUE
SUB #MAXMAG ;If input is a number, then
BCND BAD_IP,GT ;Check if value is larger than MAXMAG
ADD #MAXMAG
CALL DIVIDE ;if the value is okay, determine what
;proportion the entered
;value is of MAXMAG
CALL MAG_VALUE ;Normalize the ratio to the maximum
;Q15 value
LACC NEW_VALUE
AND #7FFFh ;Make sure the value is positive
SACL MAG1 ;Store the new magnitude for Channel AB
ISR_END ;End of modifying magnitude
;for Channel A
MAG_RESET
SPLK #7FFFh,MAG1 ;Initialize Channel A to original value
SPLK #7FFFh,MAG2 ;Initialize Channel B to original value
B ISR_END
;Converts the entered magnitude into a Q15 value
MAG_VALUE
LACC QUOTIENT
SUB #08000h ;If the DIVISOR=DIVIDENT, then
BCND MAX_MAG,EQ ;set quotient to maximum Q15 value
LT TEMP ;TREG = TEMP
MPY QUOTIENT ;PREG = TEMP * QUOTIENT
PAC ;ACC = PREG
SACH NEW_VALUE,1 ;NEW_VALUE = TEMP * QUOTIENT;
;Shift by 1 to, remove extra sign bit
RET ;Return from routine
MAX_MAG
SPLK #7FFFh,NEW_VALUE;Set NEW_VALUE to maximum Q15 value
RET ;Return from Routine
;Routine to determine the next value
WHAT_VALUE
LACC *+ ;ACC = First place
SUB #000Dh ;Check if the value is a <CR>
BCND NO_VALUE,EQ
ADD #000Dh
SUB #0030h ;Check if value is below ASCII 0
BCND NO_VALUE,LT
ADD #0030h
SUB #0039h ;Check if value is above ASCII 9
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -