Skip to content

Instantly share code, notes, and snippets.

@d3lta-v
Last active January 17, 2019 01:24
Show Gist options
  • Select an option

  • Save d3lta-v/2c4f1d4b9d057b600ac30d1f0cc31637 to your computer and use it in GitHub Desktop.

Select an option

Save d3lta-v/2c4f1d4b9d057b600ac30d1f0cc31637 to your computer and use it in GitHub Desktop.
;*******************************************************************************
; *
; 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