Last active
January 17, 2019 01:24
-
-
Save d3lta-v/2c4f1d4b9d057b600ac30d1f0cc31637 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;******************************************************************************* | |
| ; * | |
| ; Microchip licenses this software to you solely for use with Microchip * | |
| ; products. The software is owned by Microchip and/or its licensors, and is * | |
| ; protected under applicable copyright laws. All rights reserved. * | |
| ; * | |
| ; This software and any accompanying information is for suggestion only. * | |
| ; It shall not be deemed to modify Microchip?s standard warranty for its * | |
| ; products. It is your responsibility to ensure that this software meets * | |
| ; your requirements. * | |
| ; * | |
| ; SOFTWARE IS PROVIDED "AS IS". MICROCHIP AND ITS LICENSORS EXPRESSLY * | |
| ; DISCLAIM ANY WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING * | |
| ; BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS * | |
| ; FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL * | |
| ; MICROCHIP OR ITS LICENSORS BE LIABLE FOR ANY INCIDENTAL, SPECIAL, * | |
| ; INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, HARM TO * | |
| ; YOUR EQUIPMENT, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR * | |
| ; SERVICES, ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY * | |
| ; DEFENSE THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER * | |
| ; SIMILAR COSTS. * | |
| ; * | |
| ; To the fullest extend allowed by law, Microchip and its licensors * | |
| ; liability shall not exceed the amount of fee, if any, that you have paid * | |
| ; directly to Microchip to use this software. * | |
| ; * | |
| ; MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF * | |
| ; THESE TERMS. * | |
| ; * | |
| ;******************************************************************************* | |
| ; * | |
| ; Filename: assignment.asm * | |
| ; Date: 2018-07-04 * | |
| ; File Version: 1.0 * | |
| ; Author: Brian Q., Ziyue P. * | |
| ; Company: Singapore Polytechnic * | |
| ; Description: AMT Assembly Assignment * | |
| ; * | |
| ;******************************************************************************* | |
| ; * | |
| ; Notes: In the MPLAB X Help, refer to the MPASM Assembler documentation * | |
| ; for information on assembly instructions. * | |
| ; * | |
| ;******************************************************************************* | |
| ; * | |
| ; Known Issues: This template is designed for relocatable code. As such, * | |
| ; build errors such as "Directive only allowed when generating an object * | |
| ; file" will result when the 'Build in Absolute Mode' checkbox is selected * | |
| ; in the project properties. Designing code in absolute mode is * | |
| ; antiquated - use relocatable mode. * | |
| ; * | |
| ;******************************************************************************* | |
| ; * | |
| ; Revision History: * | |
| ; * | |
| ;******************************************************************************* | |
| ;******************************************************************************* | |
| ; Processor Inclusion | |
| ;******************************************************************************* | |
| LIST P=18F97J60 ; directive to define processor | |
| #include <P18F97J60.INC> ; processor specific | |
| ;******************************************************************************* | |
| ; Configuration Word Setup | |
| ;******************************************************************************* | |
| config XINST = OFF | |
| config FOSC = HS | |
| config WDT = OFF | |
| ; Frequency = 25000000 or 25MHz | |
| ;******************************************************************************* | |
| ; | |
| ; Variable Definitions | |
| ; | |
| ; Refer to datasheet for available data memory (RAM) organization assuming | |
| ; relocatible code organization (which is an option in project | |
| ; properties > mpasm (Global Options)). Absolute mode generally should | |
| ; be used sparingly. | |
| ; | |
| ; Example of using GPR Uninitialized Data | |
| ; | |
| ; GPR_VAR UDATA | |
| ; MYVAR1 RES 1 ; User variable linker places | |
| ; MYVAR2 RES 1 ; User variable linker places | |
| ; MYVAR3 RES 1 ; User variable linker places | |
| ; | |
| ; ; Example of using Access Uninitialized Data Section (when available) | |
| ; ; The variables for the context saving in the device datasheet may need | |
| ; ; memory reserved here. | |
| ; INT_VAR UDATA_ACS | |
| ; W_TEMP RES 1 ; w register for context saving (ACCESS) | |
| ; STATUS_TEMP RES 1 ; status used for context saving | |
| ; BSR_TEMP RES 1 ; bank select used for ISR context saving | |
| ; | |
| ;******************************************************************************* | |
| ; Constants for note period length | |
| ; Note us HZ | |
| #define C6 D'33' ;1047 | |
| #define B5 D'35' ;987 | |
| #define A5 D'39' ;880 | |
| #define G5 D'44' ;784 | |
| #define F5 D'49' ;698 | |
| #define E5 D'52' ;659 | |
| #define D5 D'59' ;587 | |
| #define D5b D'62' ;554 | |
| #define C5 D'65' ;523 | |
| #define B4 D'70' ;493 | |
| #define B4b D'74' ;466 | |
| #define A4 D'78' ;440 | |
| #define A4b D'83' ;415 | |
| #define G4 D'88' ;392 | |
| #define F4 D'98' ;349 | |
| #define E4 D'105' ;329 | |
| #define E4b D'111' ;311 | |
| #define D4 D'117' ;293 | |
| #define D4b D'124' ;277 | |
| #define C4 D'132' ;261 | |
| #define B3 D'139' ;247 | |
| #define B3b D'148' ;233 | |
| #define A3 D'157' ;220 | |
| #define A3b D'166' ;207 | |
| #define G3 D'176' ;196 | |
| #define E3 D'209' ;164 | |
| #define D3 D'234' ;146 | |
| ; Variables for individual tone generation | |
| cblock | |
| MICROSECONDS ; Microseconds to delay | |
| NOTE_ITER ; No. of iterations the note must sound for | |
| NOTE_ITER2 | |
| BUTTON_NUM | |
| NOTES_LEFT ; notes left to play | |
| endc | |
| ; Registers for delay routines | |
| cblock | |
| d1 | |
| d2 | |
| d3 | |
| endc | |
| ;******************************************************************************* | |
| ; Reset Vector | |
| ;******************************************************************************* | |
| ORG 0x0000 | |
| ResetV goto MAIN ; Skip over interrupt vectors | |
| ;******************************************************************************* | |
| ; Interrupt Service Routines | |
| ; | |
| ; There are a few different ways to structure interrupt routines in the 8 | |
| ; bit device families. On PIC18's the high priority and low priority | |
| ; interrupts are located at 0x0008 and 0x0018, respectively. On PIC16's and | |
| ; lower the interrupt is at 0x0004. Between device families there is subtle | |
| ; variation in the both the hardware supporting the ISR (for restoring | |
| ; interrupt context) as well as the software used to restore the context | |
| ; (without corrupting the STATUS bits). | |
| ; | |
| ; General formats are shown below in relocatible format. | |
| ; | |
| ;----------------------------------PIC18's-------------------------------------- | |
| ; | |
| ; ISRHV CODE 0x0008 | |
| ; GOTO HIGH_ISR | |
| ; ISRLV CODE 0x0018 | |
| ; GOTO LOW_ISR | |
| ; | |
| ; ISRH CODE ; let linker place high ISR routine | |
| ; HIGH_ISR | |
| ; <Insert High Priority ISR Here - no SW context saving> | |
| ; RETFIE FAST | |
| ; | |
| ; ISRL CODE ; let linker place low ISR routine | |
| ; LOW_ISR | |
| ; <Search the device datasheet for 'context' and copy interrupt | |
| ; context saving code here> | |
| ; RETFIE | |
| ; | |
| ;******************************************************************************* | |
| ORG 0x0008 | |
| HPISR | |
| retfie | |
| ORG 0x0018 | |
| LPISR | |
| retfie | |
| ;******************************************************************************* | |
| ; MAIN PROGRAM | |
| ;******************************************************************************* | |
| ORG 0x0100 ; Suggest starting address for codes | |
| ; ============================= Delay subroutines ============================== | |
| ; The delay_us routine requires the MICROSECONDS variable | |
| ; to be populated with a certain amount of microseconds | |
| ; to delay. A 1us delay should take 6.25 cycles nominal | |
| ; | |
| ; Remember: the time taken for each cycle is Tcy | |
| ; Tcy = 4/Fosc = 4/25000000 = 0.16us | |
| ; | |
| ; The equation for getting the total number of cycles this | |
| ; generates is: | |
| ; Cycles = 2 + (MICROSECONDS-1)(2+1+1+2) + (2+1+1+1) + 2 | |
| ; Divide the above by the number of microseconds and | |
| ; check if the number is near 6.25 | |
| ; | |
| ; This routine only works well for numbers in (33,234) and | |
| ; overly small or large numbers may not work | |
| delay_us ; [2 cy] | |
| goto $+4 ; [2 cy] | |
| nop ; [1 cy] | |
| decfsz MICROSECONDS ; [1 cy] | |
| bra delay_us ; [2 cy] [1 cy if skipped] | |
| return ; [2 cy] (excluding call) | |
| ; ============================================================================== | |
| ; This function loads up a block of RAM at 0x40 with melody 1 | |
| ; and resets FSR1 so that the user can access it | |
| ; Melody1 has 12/30 notes | |
| ; Starbound Theme | |
| ; E5,A4b,A4,B4,A4,A4b,E5,B4,E4,D5b,B4,A4 | |
| load_melody1 lfsr FSR1,0x40 | |
| movlw E4 | |
| movwf POSTINC1 | |
| movlw A3b | |
| movwf POSTINC1 | |
| movlw A3 | |
| movwf POSTINC1 | |
| movlw B3 | |
| movwf POSTINC1 | |
| movlw A3 | |
| movwf POSTINC1 | |
| movlw A3b | |
| movwf POSTINC1 | |
| movlw E4 | |
| movwf POSTINC1 | |
| movlw B3 | |
| movwf POSTINC1 | |
| movlw E3 | |
| movwf POSTINC1 | |
| movlw D4b | |
| movwf POSTINC1 | |
| movlw B3 | |
| movwf POSTINC1 | |
| movlw A3 | |
| movwf POSTINC1 | |
| lfsr FSR1,0x40 | |
| return | |
| ; This function loads up a block of RAM at 0x40 with melody 2 | |
| ; and resets FSR1 so that the user can access it | |
| ; Melody2 has 17/30 notes | |
| ; Music Box Dancer | |
| ; C5,C5,G4,C5,E5,C5,E5,G5,C5,C6,C6,B5,B5,A5,A5,G5,G5 | |
| ; The above notes are shifted down by one octave | |
| load_melody2 lfsr FSR1,0x40 | |
| movlw C4 | |
| movwf POSTINC1 | |
| movlw C4 | |
| movwf POSTINC1 | |
| movlw G3 | |
| movwf POSTINC1 | |
| movlw C4 | |
| movwf POSTINC1 | |
| movlw E4 | |
| movwf POSTINC1 | |
| movlw C4 | |
| movwf POSTINC1 | |
| movlw E4 | |
| movwf POSTINC1 | |
| movlw G4 | |
| movwf POSTINC1 | |
| movlw C4 | |
| movwf POSTINC1 | |
| movlw C5 | |
| movwf POSTINC1 | |
| movlw C5 | |
| movwf POSTINC1 | |
| movlw B4 | |
| movwf POSTINC1 | |
| movlw B4 | |
| movwf POSTINC1 | |
| movlw A4 | |
| movwf POSTINC1 | |
| movlw A4 | |
| movwf POSTINC1 | |
| movlw G4 | |
| movwf POSTINC1 | |
| movlw G4 | |
| movwf POSTINC1 | |
| lfsr FSR1,0x40 | |
| return | |
| ; ============================================================================== | |
| ; The play routine plays a melody. | |
| ; Make sure that the NOTES_LEFT variable is set with the correct | |
| ; no. of notes this melody has, and call the load_melody[n] | |
| ; subroutine to load the melody into memory before calling this | |
| ; subroutine | |
| play | |
| play_start: movlw D'255' ; Reset NOTE_ITER variables | |
| movwf NOTE_ITER | |
| movlw D'5' | |
| movwf NOTE_ITER2 | |
| note_start: movlw 0xff ; Turn Port C on | |
| movwf LATC | |
| movf INDF1,W ; Delay based on period from pointer | |
| movwf MICROSECONDS | |
| call delay_us | |
| movlw 0x00 ; Turn Port C off | |
| movwf LATC | |
| movf INDF1,W ; Delay based on period from pointer | |
| movwf MICROSECONDS | |
| call delay_us | |
| decfsz NOTE_ITER,1 ; Go back, if we haven't played the | |
| bra note_start ; note for enough time | |
| decfsz NOTE_ITER2,1 | |
| bra note_start | |
| ; Now that the note has finished playing, go to the next note | |
| ; by incrementing the index or exit this subroutine | |
| dcfsnz NOTES_LEFT ; NOTES_LEFT--; if (NOTES_LEFT==0) { | |
| bra note_end ; goto note_end; | |
| ; } else { | |
| movf POSTINC1,W ; FSR1++; | |
| bra play_start ; goto play_start; } | |
| note_end: return | |
| ; ============================================================================== | |
| MAIN ; Start of main program | |
| ; ========================== Initialisation routines =========================== | |
| ; Configure PORTC as an output at RC3 only | |
| movlw B'11110111' | |
| movwf TRISC | |
| ; Reset Port C, just in case if it's on | |
| movlw 0x00 | |
| movwf LATC | |
| ; Configure Port B as input for buttons | |
| movlw 0xFF | |
| movwf TRISB | |
| ; ================================= Main loop ================================== | |
| again: | |
| ; Determine button number pressed (from 0 to 3) | |
| ; NOTE: buttons on PORTB are active low | |
| movff PORTB,BUTTON_NUM | |
| ; Melody 1 | |
| button1: btfsc BUTTON_NUM,0 ; if (RB0 == 1) | |
| bra button2 ; goto button2; | |
| ; else | |
| call load_melody1 ; melody1(); | |
| movlw D'12' | |
| movwf NOTES_LEFT | |
| bra start_playing | |
| ; Melody 2 | |
| button2: btfsc BUTTON_NUM,1 ; if (RB1 == 1) | |
| bra again ; goto again; | |
| ; else | |
| call load_melody2 ; melody2(); | |
| movlw D'17' | |
| movwf NOTES_LEFT | |
| bra start_playing | |
| start_playing: call play | |
| bra again | |
| ; ============================== End of Main loop ============================== | |
| END ; No code beyond this line, absolutely. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment