;------------------------------------------------------------------- ;ENSC 151 Sample File ;------------------------------------------------------------------- ;AUTHOR(S): Bill De Vries ;VERSION: 1.0 Module Created 99-01-20 (Bill De Vries) ;VERSION: 1.1 Comments added 00-01-22 (Veljko Jovanovic) ;VERSION: 2.0 IRQ Capabilities added 00-01-28 (Rob Trost) ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; This program is the sample code to show how to use interrupts. ;------------------------------------------------------------------- ;------------------------------------------------------------------- ; LOCAL DEFINITIONS ;------------------------------------------------------------------- PORTA: equ $00 ;Port A Data Register PORTB: equ $01 ;Port B Data Register DDRA: equ $02 ;Port A Data Direction Register DDRB: equ $03 ;Port B Data Direction Register PORTC: equ $04 ;Port C Data Register DDRC: equ $06 ;Port C Data Direction Register PORTE: equ $08 ;Port E Data Register DDRE: equ $09 ;Port E Data Direction Register PEAR: equ $0A ;Port E Assigment Register MODE: equ $0B ;Mode Register PUCR: equ $0C ;Pull Up Control Register RDRIV: equ $0D ;Reduced Drive of I/O Lines Register INITRM: equ $10 ;Initialization of Internal RAM Position Register INITRG: equ $11 ;Initialization of Internal Register Position Register INITEE: equ $12 ;Inittaps IRQVEC: equ $0B32 ;Address of IRQ jump vector STROBE: equ $04 ;Bit 2 for LCD Enable (Strobing in Data) CMDREG: equ $00 ;Bit 0 is RS, Bit 1 is R/W (write instructions to the LCD) DATAREG: equ $01 ;Bit 0 is RS, Bit 1 is R/W (write data to the LCD CG or DD RAM) ;------------------------------------------------------------------- ;------------------------------------------------------------------- ; INITIALIZATION CODE ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; This section of the code initializes the LCD display and sets up ; all of the sub functions required for proper operation. This ; includes the WRITE_LCD subroutine and specific delay ; counters. ;------------------------------------------------------------------- ***************** Main Program ***************** ORG $0800 ; beginning of RAM ldaa #%00000111 ; Set lower 3 bits of Port A staa DDRA ; to output mode ldaa #%11111111 ; Set all bits of Port B staa DDRB ; to output mode jsr LCD_INIT ; Initialize the LCD IRQ_INIT movw #IRQ_PROC,IRQVEC ; install vector address in table. cli LINE_1 ldaa #CMDREG ; Set the cursor position to the ldab #$80 ; beginning of the top line jsr WRITE_LCD ldx #STRING1 ; Write the first string to the jsr WRITE_MSG ; top line IDLE ldaa #CMDREG ; Set the cursor to second line ldab #$C0 jsr WRITE_LCD ldx #STRING3 ; Clear second line with blanks jsr WRITE_MSG bra IDLE ; Loop forever ********************* End Main Program ********************* ;------------------------------------------------------------------- ; PROCEDURE: IRQ_PROC ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; The interrupt procedure writes STRING2 to the second line when ; an interrupt request occurrs. ;------------------------------------------------------------------- IRQ_PROC ldaa #CMDREG ; Set the cursor position to the ldab #$C0 ; beginning of the bottom line jsr WRITE_LCD ldx #STRING2 ; Write the second string to the jsr WRITE_MSG ; bottom line rti ;------------------------------------------------------------------- ; PROCEDURE: WRITE_LCD ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; Strobes the correct control lines to write an instruction or data ; into the LCD. The insturcion or data must be stored in ACCB before ; executing. The appropriate values of the RS, R/W and Enable bits ; must be stored in ACCA (RS = 0/1 if writing instruction/data, ; R/W = 0 since we are writing, E = 0 to start). ;------------------------------------------------------------------- WRITE_LCD ; Assume data/instruction in ACCB stab PORTB ; Write data to Port B staa PORTA ; Write RS, R/W, E to Port A jsr PAUSE eora #STROBE ; Set the Enable bit staa PORTA ; Strobe the instruction/data jsr PAUSE ; into the LCD. eora #STROBE ; Clear the Enable bit staa PORTA jsr PAUSE rts ;------------------------------------------------------------------- ; PROCEDURE: WRITE_MESSAGE ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; Writes a message (a string of characters) to the LCD. ;------------------------------------------------------------------- WRITE_MSG ldaa #DATAREG ; Set RS bit (write data) NEXT_CHAR ldab 0,X ; Load string into ACCB cmpb #$00 ; Check for the end of the string beq END_MSG jsr WRITE_LCD inx ; Increment string pointer bra NEXT_CHAR END_MSG rts ;------------------------------------------------------------------- ; PROCEDURE: LCD_INIT ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; Initializes the LCD display for required operation (2x16 mode) ;------------------------------------------------------------------- LCD_INIT ldaa #CMDREG ; Clear RS bit (write instruction) ldab #$30 ; Set Data Interface Length to 8bits jsr WRITE_LCD ldab #!15 jsr LONGPAUSE ldab #$38 ; Set Number of Display Lines to 2 jsr WRITE_LCD ldab #$08 ; Turn Off Display, Cursor & Blink jsr WRITE_LCD ldab #$01 ; Clear Display jsr WRITE_LCD ldab #!4 jsr LONGPAUSE ldab #$06 ; Set Cursor Move Direction - jsr WRITE_LCD ; Increment After Each Byte Written ldab #$0C ; Turn On Display jsr WRITE_LCD rts ;------------------------------------------------------------------- ; PROCEDURE: Delays ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; Delay functions for proper timing interface with the LCD. ;------------------------------------------------------------------- LONGPAUSE ; Executes the PAUSE subroutine as stab COUNTER ; many times as the value in ACCB LOOK tst COUNTER ; indicates. beq FINISH ; Delay = ~COUNT value * 0.2msec dec COUNTER jsr PAUSE bra LOOK FINISH rts PAUSE ldy #$00FF ; Delay for ~0.2msec AGAIN dey ; Counts down the contents of the cpy #$0000 ; Y index register. bne AGAIN ; Delay = #counts/processing speed. rts ;------------------------------------------------------------------- ***************** User Data ***************** COUNTER RMB 1 ; reserve memory for delay counter STRING1 DB 'Press a button!' ; String for the top line FCB $00 STRING2 DB ' Excitting, Eh?' ; String for the lower line FCB $00 STRING3 DB ' ' ; String of blanks FCB $00