; Simulate one of those 8 Ball things ; Put message out the serial port ; ; Charles R. Ott ; June 9, 1998 .nolist ;Suppress listing of include file .include "2313def.inc" ;Define chip particulars .list ;***** Global register variables .def wreg =R20 ;General use working register .def sav1 =R21 ;Used to save stuff .def sav2 =R22 ;Ditto .def count =R23 ;Used to count things ;***** Multiply Subroutine Register Variables .def mc8u =r16 ;multiplicand .def mp8u =r17 ;multiplier .def m8uL =r17 ;result Low byte .def m8uH =r18 ;result High byte .def mcnt8u =r19 ;loop counter ;***** Other equates .equ lcdrs =PD6 ;LCD rs pin connected to PD6 .equ lcdrw =PD5 ;LCD r/w pin connected to PD5 .equ lcde =PD4 ;LCD e pin connected to PD4 ; Timer/Counter prescaler values .equ TSTOP =0 ;Stop Timer/Counter .equ TCK1 =1 ;Timer/Counter runs from CK .equ TCK8 =2 ;Timer/Counter runs from CK / 8 .equ TCK64 =3 ;Timer/Counter runs from CK / 64 .equ TCK256 =4 ;Timer/Counter runs from CK / 256 .equ TCK1024 =5 ;Timer/Counter runs from CK / 1024 .equ TEXF =6 ;Timer/Counter runs from external falling edge .equ TEXR =7 ;Timer/Counter runs from external rising edge .equ BAUD =25 ;9600 bps at 4.00 MHz. .equ DISPWIDTH=40 ;Width of display .cseg ; Interrupt vectors .org 0 rjmp reset ;Reset Vector ; Main program entry point on reset reset: ldi wreg,RAMEND ;Init Stack Pointer out SPL,wreg ldi wreg,0x00 ;Make port B all inputs out PORTB,wreg out DDRB,wreg ldi wreg,TSTOP ;Timer 0 off (just in case) out TCCR0,wreg ;Stop timer ldi wreg,0 ;Disable Timer 0 interrupt out TIMSK,wreg ldi wreg,TCK1 ;Run timer with clk / 1 out TCCR1B,wreg ldi wreg,BAUD out UBRR,wreg ;Set baud rate generator ldi wreg,0b00001000 out UCR,wreg ;Enable UART tx w/o interrupt ; Main program loop main: ldi ZH,high(msg0*2) ;Print sign on message ldi ZL,low(msg0*2) ;Init Z-pointer rcall putcenter pbwait: sbic PINB,7 ;Wait for button press rjmp pbwait in wreg,TCNT1L ;Read timer 1 low byte andi wreg,0x1F mov mc8u,wreg ;Put into multiplicand ldi mp8u,10 ;Multiplier is 10 rcall mpy8u ;Do the math lsr m8uH ;Divide result by 16 ror m8uL lsr m8uH ror m8uL lsr m8uH ror m8uL lsr m8uH ror m8uL mov count,m8uL ;Result should now be 0 to 19 ldi ZH,high(msgtable) ;Point to table of messages ldi ZL,low(msgtable) inc count ;Preincrement counter for add mloop: dec count breq mdone adiw ZL,1 ;Multiply pointer by count rjmp mloop mdone: lsl ZL ;Multiply pointer by 2 rol ZH lpm ;Get high byte mov wreg,R0 ;Save it adiw ZL,1 ;Increment Z-pointer lpm mov ZH,R0 ;Point to actual message mov ZL,wreg lsl ZL ;Multiply pointer by 2 rol ZH rcall putcenter ;Show centered on display debounce: sbis PINB,7 ;Wait for button release rjmp debounce rjmp pbwait ;Do it forever..... ; Put centered string pointed to by Z putcenter: ldi wreg,21 rcall putchar ldi count,0 ;Zero counter mov sav1,ZH ;Save pointer mov sav2,ZL puts1: lpm tst R0 breq puts2 adiw ZL,1 inc count rjmp puts1 puts2: ldi wreg,DISPWIDTH sub wreg,count mov count,wreg lsr count puts3: breq puts4 ldi wreg,' ' rcall putchar dec count rjmp puts3 puts4: mov ZH,sav1 mov ZL,sav2 ; Put string pointed to by Z puts: lpm ;Get next character from ROM tst R0 ;See if at end of message breq putx ;If so, quit mov wreg,R0 ;Get character rcall putchar putnext: adiw ZL,1 ;Increment Z-pointer rjmp puts ;Loop for more putx: ret putchar: sbis USR,UDRE ;Is UART transmitter ready? rjmp putchar ;If not, wait out UDR,wreg ;Put character to UART cpi wreg,' ' ;See if character was a space brne delay ;If not, delay for effect ret delay: ldi R24,0 del1: ldi R25,0 del2: dec R25 brne del2 dec R24 brne del1 ret ; "mpy8u" - 8x8 Bit Unsigned Multiplication ; From Atmel app notes mpy8u: clr m8uH ;clear result High byte ldi mcnt8u,8 ;init loop counter lsr mp8u ;rotate multiplier m8u_1: brcc m8u_2 ;carry set add m8uH,mc8u ; add multiplicand to result High byte m8u_2: ror m8uH ;rotate right result High byte ror m8uL ;rotate right result L byte and multiplier dec mcnt8u ;decrement loop counter brne m8u_1 ;if not done, loop more ret ; Table of pointers to messages msgtable: .dw msg1,msg2,msg3,msg4,msg5,msg6,msg7,msg8,msg9,msg10 .dw msg11,msg12,msg13,msg14,msg15,msg16,msg17,msg18,msg19,msg20 ; Messages to display msg0: .db "Magic 8 Ball, Press Switch 7",0 msg1: .db "Outlook Good",0 msg2: .db "Outlook Not So Good",0 msg3: .db "My Reply Is No",0 msg4: .db "Don't Count On It",0 msg5: .db "You May Rely On It",0 msg6: .db "Ask Again Later",0 msg7: .db "Most Likely",0 msg8: .db "Cannot Predict Now",0 msg9: .db "Yes",0 msg10: .db "Yes Definately",0 msg11: .db "Better Not Tell You Now",0 msg12: .db "It Is Certain",0 msg13: .db "Very Doubtful",0 msg14: .db "It Is Decidedly So",0 msg15: .db "Concentrate and Ask Again",0 msg16: .db "Signs Point to Yes",0 msg17: .db "My Sources Say No",0 msg18: .db "Without a Doubt",0 msg19: .db "Reply Hazy, Try Again",0 msg20: .db "As I See It, Yes",0