Waits for joystick to move, then beeps and displays the direction the joystick was moved on the LCD Display.
;------------------------------------------;
; JOY_TESTER ;
; ========== ;
; ;
; TEST THE JOYSTICK ; ;
; AUTHOR: DANIEL J, DOREY AKA RETRODAN ;
; 19-OCT-09: CREATED LAST UPDATE:19-OCT-09 ;
;------------------------------------------;
.NOLIST
.INCLUDE "M169DEF.INC" ;BUTTERFLY DEFS
.LIST
;---------------------------------:
; RENAME/DEFINE WORKING REGISTERS ;
;---------------------------------;
.SET CHR6BUF = 2 ;6 CHAR BUFFER IS [R2,R3,R4,R5,R6,R7]
.DEF ZERO = R8
.DEF T1 = R11
.DEF T2 = R12
.DEF A = R16 ;R16:R31 CAN BE LOADED IMMEDIATE (LDI)
.DEF AH = R17
.DEF B = R18
.DEF C = R19
.DEF D = R20
.DEF I = R21
.DEF J = R22
.DEF K = R23
.DEF N = R24
.SET BLANK_CHAR=SPACE-LCD_TABLE
.ORG $0000
RJMP ON_RESET
;-----------------;
; INITIALIZATIONS ;
;-----------------;
ON_RESET:
CLR ZERO
LDI A,HIGH(RAMEND) ;SETUP THE STACK POINTER
OUT SPH,A ;AT TOP OF MEMORY AND
LDI A,LOW(RAMEND) ;GROW DOWNWARDS
OUT SPL,A
SER A ;INIT PORTS B&E FOR INPUT
OUT PORTB,A
OUT PORTE,A
RCALL LCD_INIT ;INITIALIZE LCD
RCALL LCD_CLR ;CLEAR LCD SEGMENTS
;-----------;
; MAIN LOOP ;
;-----------;
MAIN:
LOOP: SBIS PINB,4
RJMP JOYMID
SBIS PINB,6 ;JOYSTICK UP
RJMP JOYUP
SBIS PINB,7 ;JOYSTICK DOWN
RJMP JOYDOWN
SBIS PINE,2 ;JOYSTICK LEFT
RJMP JOYLEFT
SBIS PINE,3 ;JOYSTICK RIGHT
RJMP JOYRIGHT
NOJOY: LDI ZL,LOW(MESWAIT*2) ;SET A POINTER TO MESSAGE
LDI ZH,HIGH(MESWAIT*2)
RJMP SHOWMESS
JOYMID: LDI ZL,LOW(MESMID*2) ;SET A POINTER TO MESSAGE
LDI ZH,HIGH(MESMID*2)
RJMP BPMESS
JOYUP:LDI ZL,LOW(MESUP*2) ;SET A POINTER TO MESSAGE
LDI ZH,HIGH(MESUP*2)
RJMP BPMESS
JOYDOWN:LDI ZL,LOW(MESDOWN*2) ;SET A POINTER TO MESSAGE
LDI ZH,HIGH(MESDOWN*2)
RJMP BPMESS
JOYLEFT:LDI ZL,LOW(MESLEFT*2) ;SET A POINTER TO MESSAGE
LDI ZH,HIGH(MESLEFT*2)
RJMP BPMESS
JOYRIGHT:
LDI ZL,LOW(MESRIGHT*2) ;SET A POINTER TO MESSAGE
LDI ZH,HIGH(MESRIGHT*2)
BPMESS:RCALL WHIT
SHOWMESS:
RCALL SHOWBUF ;SHOW MESSAGE
RCALL DELAY ;WAIT
DONE: RJMP LOOP
MESWAIT:.DB "PRESS "
MESMID: .DB "CENTRE"
MESUP: .DB " UP "
MESDOWN:.DB " DOWN "
MESLEFT:.DB " LEFT "
MESRIGHT:.DB "RIGHT "
;=====================[ SUBROUTINES ]=========================
;-----------------------------------------------;
; NO RESTORE WHIT ROUTINE, USES THE R0 REGISTER ;
;-----------------------------------------------;
WHIT: CLR R0
SBI DDRB,5 ;SET PORTB-BIT5 FOR OUTPUT
WHLUPE: SBI PORTB,5 ;SET PORTB-BIT5
RCALL WPAUSE ;WAIT
CBI PORTB,5 ;CLEAR BORTB-BIT5
RCALL WPAUSE ;WAIT
DEC R0
BRNE WHLUPE ;LOOP AROUND
RET
WPAUSE: PUSH R0 ;PAUSE TWEEN PULSES
WPLUPE: DEC R0 ;IE DETERMINS FREQ
BRNE WPLUPE
POP R0
RET
;-------------------------------;
; COPIES TEXT TO DISPLAY BUFFER ;
; MUST LOAD (Z) FIRST ;
;-------------------------------;
SHOWBUF:LPM A,Z+
MOV R7,A
LPM A,Z+
MOV R6,A
LPM A,Z+
MOV R5,A
LPM A,Z+
MOV R4,A
LPM A,Z+
MOV R3,A
LPM A,Z+
MOV R2,A
PUSH A
RCALL DISPN
POP A
RET
;-----------------------------------------------;
; DISPN - DISPLAY THE NUMBER IN R7:R2 REGISTERS ;
; NOTE CHR6BUF MUST BE POINTING 6 CHAR BUFFER ;
; APR/06 VERSION II WITH ASCII XLATION ;
;-----------------------------------------------;
DISPN: LDI XL,LOW(CHR6BUF) ;POINTS BUFFER-6
LDI XH,HIGH(CHR6BUF)
;-------------------------;
; ENTER HERE IF XH:XL SET ;
;-------------------------;
LCD_DSP: LDI N,6 ;SIX CHARS
LDI B,$F0 ;BITMASK
DSPNXT: LD A,X+ ;FETCH THE CHAR TO DISP
CPI A,' ' ;SPACE?
BRNE NOSPC ;SPACE XLATION
LDI A,BLANK_CHAR
NOSPC:
CPI A,97 ;CHARACTER XLATION
BRLO NOSMLET ;SMALL LETTERS?
SUBI A,$20 ;FOLD#1 a=>A
NOSMLET: CPI A,64 ;CAP LETTERS
BRLO NOBGLET ;
SUBI A,$37 ;FOLD#2 A=>10
NOBGLET: CPI A,47 ;ASCII NUMBERS
BRLO NOANUM ;
SUBI A,$30 ;FOLD#3 "0"=>0
NOANUM: LSL A ;POINT Z INTO TABLE
LDI ZL,LOW(LCD_TABLE*2)
LDI ZH,HIGH(LCD_TABLE*2)
ADD ZL,A ;OFFSET INTO
ADC ZH,ZERO ;CHARACTER TABLE
LDI YL,LOW(LCDDR1)-1 ;(=251)POINTS TO
CLR YH ;LCD SEGMENTS
MOV A,N ;USE COUNTER
DEC A
LSR A ;AS OFFSET TO
ADD YL,A ;SEGMENTS
SET
LDI I,4
DISPLUP: CPI YL,LOW(LCDDR8) ;PAST CHECK POINT?
BRLO NOZINC ;PAST 2ND READ?
BRTC NOZINC ;SHOULD WE INCZ?
ADIW ZH:ZL,1 ;INCZ AFTER 2ND READ
CLT ;STOP FURTHER INCZ
NOZINC: LPM A,Z ;LOAD SEGMENT DATA
SBRS I,0 ;USE BIT0
SWAP A ;SWAP ON EVEN SEGS
SBRC N,0 ;USE BIT0
SWAP A ;SWAP ON EVEN DIGITS
POTRIP: AND A,B ;MASK NEEDED INFO
COM B ;INVERT MASK
LD C,Y ;READ-IN SEGMENT
AND C,B ;CLEAR A SPOT
OR A,C ;SHOVE-IN NEW
ST Y,A ;WRITE-BACK
COM B ;RE-INVERT MASK
ADIW YH:YL,5 ;NEXT SEG
DEC I
BRNE DISPLUP ;DONE 4 SEGS?
SKPNUM: COM B ;INVERT BIT-MASK
DEC N ;DONE 6 DIGITS?
NOINC: BRNE DSPNXT
RET
;---------------------------;
; CLEAR ALL SEGMENTS ON LCD ;
;---------------------------;
LCD_CLR: LDI YL,LOW(LCDDR0)
CLR YH
CLRLUPE: ST Y+,ZERO
CPI YL,LCDDR18+1
BRNE CLRLUPE
RET
;-------------------------------;
; INITIALIZE LCD DISP REGISTERS ;
;-------------------------------;
LCD_INIT: PUSH A
LDI A,$B7 ;183 (1<<LCDCS) | (3<<LCDMUX0) | (7<<LCDPM0)
STS LCDCRB, A ;ENABLE ALL SEGEMENTS
LDI A,7 ;(0<<LCDPS0) | (7<<LCDCD0)
STS LCDFRR, A ;SET PRESCALER TO 32KHz
LDI A,$0E ;14 (1<<LCDCC3) | (1<<LCDCC2) | (1<<LCDCC1)
STS LCDCCR, A ;SET THE CONTRAST
LDI A,$C0 ;192(1<<LCDEN) | (1<<LCDAB)
STS LCDCRA, A ;ENABLE THE LCD
POP A
RET
;-----------------------------------;
; PAUSE/DELAY ROUTINE ;
; USES R0:R1 - NOT RESTORED ;
; WARNING R0:R1 ARE NOT INITIALIZED ;
; USES A - RESTORED ;
;-----------------------------------;
PAUSE:
DELAY: PUSH A
LDI A,8
DLUPE: DEC R0
BRNE DLUPE
DEC R1
BRNE DLUPE
DEC A
BRNE DLUPE
POP A
RET
;-----------------------------------------------------------;
; RETRO DAN'S IMPROVED LCD CHARACTER TABLE V1.2 ; ;
;-----------------------------------------------------------;
LCD_TABLE:
; --mpndlegcjfhbk--a <------> LCD SEGMENTS
.DW 0b0001010101010001 ;ZERO
.DW 0b0010000010000000 ;1
.DW 0b0001111000010001 ;2
.DW 0b0001101100010001 ;3
.DW 0b0000101101010000 ;4
.DW 0b0001101101000001 ;5
.DW 0b0001111101000001 ;6
.DW 0b0000000101010001 ;7
.DW 0b0001111101010001 ;8
.DW 0b0001101101010001 ;9
.DW 0b0000111101010001 ;A
.DW 0b0011100110010001 ;B -----a-----
.DW 0b0001010001000001 ;C | \ | / |
.DW 0b0011000110010001 ;D f h j k b
.DW 0b0001111001000001 ;E | \ | / |
.DW 0b0000111001000001 ;F --g-- --l--
.DW 0b0001110101000001 ;G | / | \ |
.DW 0b0000111101010000 ;H e p n m c
.DW 0b0010000010000000 ;I | / | \ |
.DW 0b0001010100010000 ;J -----d-----
.DW 0b1000011001001000 ;K
.DW 0b0001010001000000 ;L
.DW 0b0000010101111000 ;M
.DW 0b1000010101110000 ;N
.DW 0b0001010101010001 ;0
.DW 0b0000111001010001 ;P
.DW 0b1001010101010001 ;Q
.DW 0b1000111001010001 ;R
.DW 0b0001101101000001 ;S
.DW 0b0010000010000001 ;T
.DW 0b0001010101010000 ;U
.DW 0b1000000100110000 ;V
.DW 0b1100010101010000 ;W
.DW 0b1100000000101000 ;X
.DW 0b0010000000101000 ;Y
.DW 0b0101000000001001 ;Z
.DW 0b0001010001000001 ;[
.DW 0b1000000000100000 ;\
.DW 0b0001000100010001 ;]
.DW 0b0000000001100000 ;^
.DW 0b0001000000000000 ;_
.DW 0b0000000000001000 ;'
.DW 0b1110101010101000 ;*
.DW 0b0010101010000000 ;+
SPACE:.DW 0 ;(SPACE) ;
.DW 0b0000101000000000 ;-
.DW 0b0100000000000000 ;.
.DW 0b0100000000001000 ;/
.DW 0b1000000000001000 ;<
.DW 0b0001101000000000 ;=
.DW 0b0100000000100000 ;>