| CODE |
;********************************MACROS*********************************** ; PORTB is control lines in following order ; NC NC NC NC /CE WR RD C/D ; PORTC is data ; DDR* = 0 ==> input pin ; when used to read status, doesn't matter if pull up is active or not ;checks the status of the LCD display ;takes as input what a valid status is .MACRO statusi ; ldi temp2, 0b01010101 ; out PORTB, temp2 clr temp ;set PORTC to all inputs out DDRC, temp ; ser temp ; out PORTC, temp ;set pull ups, why the hell not??? statuswait: ldi temp, 0b00010101 out PORTB, temp ;set control lines in temp, PINC ;read data nop nop andi temp, @0 ldi temp1, 0b00011101 out PORTB, temp1 ;set control lines cpi temp, @0 ;compare brne statuswait ;if status check fails, try again ldi temp, 0b00011010;return chip to read status to avoid double writing (VERY bad) out PORTB, temp .ENDMACRO ;checks the status of the LCD display ;takes as input what a valid status is .MACRO status ; ldi temp2, 0b01010101 ; out PORTB, temp2 clr temp ;set PORTC to all inputs out DDRC, temp ; ser temp ; out PORTC, temp ;set pull ups, why the hell not??? statuswait: ldi temp, 0b00010101 out PORTB, temp ;set control lines in temp, PINC ;read data nop nop and temp, @0 ldi temp1, 0b00011101 out PORTB, temp1 ;set control lines cp temp, @0 ;compare brne statuswait ;if status check fails, try again ldi temp, 0b00011010;return chip to read status to avoid double writing (VERY bad) out PORTB, temp .ENDMACRO ;writes data to the LCD display ;takes as input the data to be written .MACRO writei ser temp ;set PORTC to all outputs out DDRC, temp ldi temp, @0 out PORTC, temp ;put data on PORTC ldi temp, 0b00010010 out PORTB, temp ;set control lines ldi temp, 0b00011010 out PORTB, temp ;bring /CE back up .ENDMACRO ;writes data to the LCD display ;takes as input the data to be written .MACRO write ser temp ;set PORTC to all outputs out DDRC, temp out PORTC, @0 ;put data on PORTC ldi temp, 0b00010010 out PORTB, temp ;set control lines ldi temp, 0b00011010 out PORTB, temp ;bring /CE back up .ENDMACRO ;writes a command to LCD display ;takes as input the command to be written .MACRO commandi ser temp ;set PORTC to all outputs out DDRC, temp ldi temp, @0 out PORTC, temp ;put command on PORTC ldi temp, 0b00010011 out PORTB, temp ;set control lines ldi temp, 0b00011011 out PORTB, temp;pulse /CE back up .ENDMACRO ;writes a command to LCD display ;takes as input the command to be written .MACRO command ser temp ;set PORTC to all outputs out DDRC, temp out PORTC, @0 ;put command on PORTC ldi temp, 0b00010011 out PORTB, temp ;set control lines ldi temp, 0b00011011 out PORTB, temp;pulse /CE back up .ENDMACRO ;***********************************16 bit math********************************************** ;adds two 16 bit numbers, takes in add1h, add1l, add2h, add2l .MACRO add16 add @1,@3 ;Add low bytes adc @0,@2 ;Add high bytes with carry .ENDMACRO ;compares two 16 bit numbers, takes in cp1h, cp1l, cp2h, cp2l .MACRO cp16 cp @1,@3 ;Compare low byte cpc @0,@2 ;Compare high byte with carry from ;previous operation .ENDMACRO ;add a 16 bit number to a 16 bit immediate, takes in addh, addl, addi .MACRO addi16 subi @1, low(-@2) ;Add low byte ( x -(-y)) = x + y sbci @0, high(-@2);Add high byte with carry .ENDMACRO ;compares a 16 bit number with an immediate, takes in cp1h, cp1l, cpi .MACRO cpi16 cpi @1, low(@2);Compare low byte ldi temp, high(@2); cpc @0, temp;Compare high byte .ENDMACRO ;subtract constant from 16 bit number, takes in subh, subl, subi .MACRO subi16 subi @1,low(@2);Subtract low bytes sbci @0,high(@2);Subtract high byte with carry .ENDMACRO ;---------------------------------------------------------------------------- .include "c:\avrtools\appnotes\8535def.inc" ;.device AT90S8535; specifies to the assembler which chip we are using .def pgmem =r0; for reading text from memory .def status =r1 ;0x000000 ::: lower mem (0) / upper mem (1) ::: erase (0) / write (1) .def AnaLo =r2; for reading the ADC .def AnaHi =r3; .def timeout =r4; delay for slowing the game down .def reload =r5; helper for delay in timer 0 .def save =r6; saves SREG .def speedctr =r7; assists in speeding up the ball .def mc16uL =r8;multiplicand low byte .def mc16uH =r9;multiplicand high byte .def mp16uL =r10;multiplier low byte .def mp16uH =r11;multiplier high byte .def m16u0 =r10;result byte 0 (LSB) .def m16u1 =r11;result byte 1 .def m16u2 =r12;result byte 2 .def m16u3 =r13;result byte 3 (MSB) .def mcnt16u =r16;loop counter (temp) .def drem24uL =r8 ; remainder .def drem24uH =r9 .def dres24uL =r10; result .def dres24uM =r11 .def dres24uH =r12 .def dv24uH =r14 .def dv24uL =r15; divisor .def dcnt24u =r16; loop counter .def temp =r16 ; temporary register .def ballx =r17; ball position .def bally =r18 .def balldx =r19; ball velocity .def balldy =r20 .def cnt =r21; counter (all-purpose) .def temp1 =r22; extra temps .def temp2 =r23; .def score0 =r24; player 0 score .def score1 =r25; player 1 score .def addrl =r26; XL .def addrh =r27; XH .def paddle0 =r28; YL .def paddle1 =r29; YH ; ZL ; ZH used by timer 1 .equ speakerbit =7 .equ GAMEDELAY =20;20 mS game delay .equ timer1on =0b00010001;used when compare match interrupt for timer1 .equ timer1off=0b00000001;is toggled .equ R =9960; multiplier for ADC measurements .include "c:\users\eam23_jgo2\macros.asm" .cseg .org $0000 rjmp RESET ;reset entry vector reti ;IRQ0 reti ;IRQ1 reti ;t2 compare reti ;t2 ovfl reti ;t1 cap rjmp t1AMatch;timer 1 compare match A - for sound reti ;t1 compare b reti ;t1 ovfl rjmp t0int;t0 overflow reti reti reti reti reti reti reti RESET: ; stack pointer ldi Temp, low(RAMEND) out SPL, Temp ldi Temp, high(RAMEND) out SPH, Temp ;set up timer 0 for 1 mSec ticks (slows down game) ldi temp, 3 ;prescale timer by 64 out TCCR0, temp ldi temp,256-62;preload timer since mov Reload, temp out TCNT0, Reload;62.5 x (64x.25) microSec = 1.0 mSec. ;set up timer 1 for compare match interrupt (plays sound) ldi temp, timer1off out TIMSK, temp ldi temp, 0b00001001 out TCCR1B, temp ; port A -> analog for two controllers ;set port B for LCD control and processor communication ldi temp, 0b10111111 out DDRB, temp clr temp out PORTB, temp ; port C -> data for LCD ; port D -> control buttons (start button), plus sound output on one pin. ldi temp, 0b10000000 out DDRD, temp clr temp out PORTD, temp ;turn off pullups sei ;Enable interrupts ;initialize LCD display graphics area starting at 0000h ; graphics home address = 0000h statusi 0x03 writei 0x00 statusi 0x03 writei 0x00 statusi 0x03 commandi 0x42 ; start next line 0x1e bytes later statusi 0x03 writei 30 statusi 0x03 writei 0x00 statusi 0x03 commandi 0x43 ;initialize LCD text area starting at 1400h statusi 0x03 writei 0x00 statusi 0x03 writei 0x14 statusi 0x03 commandi 0x40 statusi 0x03 writei 30 statusi 0x03 writei 0x00 statusi 0x03 commandi 0x41 ;set display mode to "or" statusi 0x03 commandi 0x80 ;set display mode statusi 0x03 commandi 0x9C ;clear display rcall clrallmem ; initialize variables ldi score0, 0 ldi score1, 0 clt ; beginning of game flag ; play opening music ldi temp, low(30) out OCR1AH, temp ldi temp, high(30) out OCR1AL, temp ldi ZL,low(40) ldi ZH,high(40) ldi temp,timer1on out TIMSK,temp start1: tst ZL brne start1 ldi temp, low(70) out OCR1AH, temp ldi temp, high(70) out OCR1AL, temp ldi ZL,low(90) ldi ZH,high(90) ldi temp,timer1on out TIMSK,temp start2: tst ZL brne start2 ldi temp, low(30) out OCR1AH, temp ldi temp, high(30) out OCR1AL, temp ldi ZL,low(70) ldi ZH,high(70) ldi temp,timer1on out TIMSK,temp start3: tst ZL brne start3 ldi temp, low(75) out OCR1AH, temp ldi temp, high(75) out OCR1AL, temp ldi ZL,low(50) ldi ZH,high(50) ldi temp,timer1on out TIMSK,temp start4: tst ZL brne start4 ldi temp, low(20) out OCR1AH, temp ldi temp, high(20) out OCR1AL, temp ldi ZL,low(100) ldi ZH,high(100) ldi temp,timer1on out TIMSK,temp start5: tst ZL brne start5 ldi temp, low(50) out OCR1AH, temp ldi temp, high(50) out OCR1AL, temp ldi ZL,low(60) ldi ZH,high(60) ldi temp,timer1on out TIMSK,temp start6: tst ZL brne start6 nextGame: ; starting ball position ldi ballx, 120 ldi bally, 120 ; initial ball speed in y direction ldi balldy, 1 ; speed increases every 4 paddle hits ldi temp, 4 mov speedctr, temp ; display info on screen and wait for buttonpress rcall writelabels gameLoop: ldi temp, GAMEDELAY mov timeout, temp rcall delay rcall checkControl0 rcall checkControl1 rcall eraseball rcall updatexy rcall drawball rjmp gameLoop moveto:; LCD helper subroutine ; move address pointer to location specified in addrl, addrh clr temp ;set PORTC to all inputs out DDRC, temp statuswait: ldi temp, 0b00010101 out PORTB, temp ;set control lines in temp, PINC ;read data nop nop andi temp, 3 ldi temp1, 0b00011101 out PORTB, temp1 ;set control lines cpi temp, 3 ;compare brne statuswait ;if status check fails, try again ldi temp, 0b00011010;return chip to read status to avoid double writing (VERY bad) out PORTB, temp ser temp ;set PORTC to all outputs out DDRC, temp out PORTC, addrl ;put data on PORTC ldi temp, 0b00010010 out PORTB, temp ;set control lines ldi temp, 0b00011010 out PORTB, temp ;bring /CE back up clr temp ;set PORTC to all inputs out DDRC, temp statuswait1: ldi temp, 0b00010101 out PORTB, temp ;set control lines in temp, PINC ;read data nop nop andi temp, 3 ldi temp1, 0b00011101 out PORTB, temp1 ;set control lines cpi temp, 3 ;compare brne statuswait1 ;if status check fails, try again ldi temp, 0b00011010;return chip to read status to avoid double writing (VERY bad) out PORTB, temp ser temp ;set PORTC to all outputs out DDRC, temp out PORTC, addrh ;put data on PORTC ldi temp, 0b00010010 out PORTB, temp ;set control lines ldi temp, 0b00011010 out PORTB, temp ;bring /CE back up clr temp ;set PORTC to all inputs out DDRC, temp statuswait2: ldi temp, 0b00010101 out PORTB, temp ;set control lines in temp, PINC ;read data nop nop andi temp, 3 ldi temp1, 0b00011101 out PORTB, temp1 ;set control lines cpi temp, 3 ;compare brne statuswait2 ;if status check fails, try again ldi temp, 0b00011010;return chip to read status to avoid double writing (VERY bad) out PORTB, temp ser temp ;set PORTC to all outputs out DDRC, temp ldi temp, 0x24 out PORTC, temp ;put command on PORTC ldi temp, 0b00010011 out PORTB, temp ;set control lines ldi temp, 0b00011011 out PORTB, temp ;pulse /CE back up ret drawBall: ; draws the ball on the screen at its current position ldi addrh, 0 ldi addrl, 30 ; each graphic line is 30 bytes long ; determine y direction (what row) ; multiply bally * 30 mov temp, bally rcall mpy8u ; determine x byte (right shift 3) mov cnt, ballx lsr cnt lsr cnt lsr cnt add addrl, cnt ;Add low bytes clr cnt adc addrh, cnt ;Add high bytes with carry ; move address pointer to ball location rcall moveto ; set bits around location mov cnt, ballx andi cnt, 0b00000111; find out the last three bits, which tell how ; far over within the current byte to place the ball cpi cnt, 0 breq drawBall0 cpi cnt, 1 breq drawBall1 cpi cnt, 2 breq drawBall2 cpi cnt, 3 breq drawBall3 cpi cnt, 4 breq drawBall4 cpi cnt, 5 breq drawBall5 cpi cnt, 6 breq drawBall6 rjmp drawBall7 drawBall1: rjmp drawBall1_2 drawBall2: rjmp drawBall2_2 drawBall3: rjmp drawBall3_2 drawBall4: rjmp drawBall4_2 drawBall5: rjmp drawBall5_2 drawBall6: rjmp drawBall6_2 drawBall0: ldi temp2, 0b01100000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11110000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11110000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b01100000 rcall status3 write temp2 rcall status3 commandi 0xC4 ret drawBall1_2: ldi temp2, 0b00110000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b01111000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b01111000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00110000 rcall status3 write temp2 rcall status3 commandi 0xC4 ret drawBall2_2: ldi temp2, 0b00011000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00111100 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00111100 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00011000 rcall status3 write temp2 rcall status3 commandi 0xC4 ret drawBall3_2: ldi temp2, 0b00001100 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00011110 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00011110 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00001100 rcall status3 write temp2 rcall status3 commandi 0xC4 ret drawBall4_2: ldi temp2, 0b00000110 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00001111 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00001111 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000110 rcall status3 write temp2 rcall status3 commandi 0xC4 ret drawBall5_2: ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte adiw addrl, 30 rcall moveto ldi temp2, 0b00000111 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte ldi temp2, 0b10000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000111 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte ldi temp2, 0b10000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte ret drawBall6_2: ldi temp2, 0b00000001 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte ldi temp2, 0b10000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000001 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte ldi temp2, 0b10000000 rcall status3 write temp2 rcall status3 commandi 0xC4 ret drawBall7: adiw addrl, 1 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 29 rcall moveto ldi temp2, 0b00000001 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte ldi temp2, 0b11100000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000001 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte ldi temp2, 0b11100000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 31 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 ret status3: ; gets a status from the LCD with a return code of 0x03 (ready for next command) clr temp ;set PORTC to all inputs out DDRC, temp statuswait_status3: ldi temp, 0b00010101 out PORTB, temp ;set control lines in temp, PINC ;read data nop nop andi temp, 3 ldi temp1, 0b00011101 out PORTB, temp1 ;set control lines cpi temp, 3 ;compare brne statuswait_status3 ;if status check fails, try again ldi temp, 0b00011010;return chip to read status to avoid double writing (VERY bad) out PORTB, temp ret eraseBall: ; counterpart to drawBall, erases the ball at its current location ldi addrh, 0 ldi addrl, 30 ; each graphic line is 30 bytes long ; determine y direction (what row) ; multiply bally * 30 mov temp, bally rcall mpy8u ; determine x byte (right shift 3) mov cnt, ballx lsr cnt lsr cnt lsr cnt add addrl, cnt ;Add low bytes clr cnt adc addrh, cnt ;Add high bytes with carry ; move address pointer to ball location rcall moveto ; set bits around location mov cnt, ballx andi cnt, 0b00000111; find out the last three bits, which tell how ; far over within the current byte to place the ball cpi cnt,5 brge eraseballhigh rjmp eraseballlow eraseballhigh: rjmp eraseballhigh2 eraseballlow: clr temp2 ;write all 0's to byte rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto clr temp2 ;write all 0's to byte rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto clr temp2 ;write all 0's to byte rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto clr temp2 ;write all 0's to byte rcall status3 write temp2 rcall status3 commandi 0xC4 ret eraseballhigh2: clr temp2 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte clr temp2 rcall status3 write temp2 rcall status3 commandi 0xC4; C0 - bump along to next byte adiw addrl, 30 rcall moveto clr temp2 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte clr temp2 rcall status3 write temp2 rcall status3 commandi 0xC4; C0 - bump along to next byte adiw addrl, 30 rcall moveto clr temp2 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte clr temp2 rcall status3 write temp2 rcall status3 commandi 0xC4; C0 - bump along to next byte adiw addrl, 30 rcall moveto clr temp2 rcall status3 write temp2 rcall status3 commandi 0xC0; C0 - bump along to next byte clr temp2 rcall status3 write temp2 rcall status3 commandi 0xC4; C0 - bump along to next byte ret ;******************************************** ;updatexy - updates ballx and bally according to balldx and balldy ; also checks for paddle hit ; also checks for wall bounce ; also checks for misses - ball fell off the end of the playing field. ; ****************************************** updatexy: ; first do y direction add bally,balldy cpi bally, 0 breq hit0 cpi bally, 250; if ball fell through 0 to 255 brcc hit0 cpi bally, 124 brcc hit124 rjmp updatex hit0: ;*turn on sound ldi temp, low(200) out OCR1AH, temp ldi temp, high(200) out OCR1AL, temp ldi ZL,low(10) ldi ZH,high(10) ldi temp,timer1on out TIMSK,temp neg bally ;just get two's comp of bally neg balldy rjmp updatex hit124: ;*turn on sound ldi temp, low(200) out OCR1AH, temp ldi temp, high(200) out OCR1AL, temp ldi ZL,low(10) ldi ZH,high(10) ldi temp,timer1on out TIMSK,temp subi bally,124;find difference with 127 neg bally ;and then subtract that from 127 subi bally,-124 neg balldy updatex: ; now update x direction add ballx, balldx cpi ballx, 240-8-4; check for paddle hit brcs skipPaddle1Check; branch if ballx < 232 sbrc balldx,7 rjmp skipPaddle1Check; ensure ball direction is correct mov temp, bally sub temp, paddle1 cpi temp, 16; paddle is 16 pixels long brcs hitxr skipPaddle1Check: cpi ballx,236;if it hits right wall, over 240 brcc p1miss cpi ballx, 8; check for paddle hit brcs paddle0Check cpi ballx, 5 brcs p0miss ret hitxr:; hit right paddle cpi temp, 4 brcs hitxr1 cpi temp, 12 brcs hitxr2 subi balldx, -1 rjmp hitxr2 hitxr1: subi balldx, -1 hitxr2: subi ballx,228;find difference with 240 neg ballx ;and then subtract that from 240 subi ballx,-228 rjmp updateend paddle0Check: mov temp, bally sub temp, paddle0 cpi temp, 16 brcs hitxl ret; miss paddle, keep ball moving, no bounce p1miss: sbrc balldx, 7; ensure ball direction is correct rjmp p0miss inc score0 rjmp screenflash; flash screen, play bad noise p0miss: sbrs balldx, 7; ensure ball direction is correct rjmp p1miss inc score1 rjmp screenflash; flash screen, play bad noise hitxl:;bally is close to 0 edge neg ballx subi ballx,-16 updateend:; but hit ball too ldi temp, low(50) out OCR1AH, temp ldi temp, high(50) out OCR1AL, temp ldi ZL,low(20) ldi ZH,high(20) ldi temp,timer1on out TIMSK,temp neg balldx dec speedctr breq incBalldx ret incBalldx: cpi balldx, 8 breq skipIncBalldx cpi balldx, -8 breq skipIncBalldx sbrs balldx, 7; if negative, skip next inc balldx sbrc balldx, 7 dec balldx ldi temp, 4 mov speedctr, temp skipIncBalldx: ret ;*********************** ;clears lcd memory clrallmem: ;set the address pointer to the beginning of memory statusi 0x03 writei 0x00 statusi 0x03 writei 0x00 statusi 0x03 commandi 0x24 ;Zero out counter ldi addrh,0 ldi addrl,0 ;set up autowrite statusi 0x03 commandi 0xB0 clrmemloop: ;inc counter addi16 addrh, addrl, 0x0001 ;write zero to memory statusi 0x08 writei 0x00 ;check loop status cpi16 addrh, addrl, 0x1680 brne clrmemloop ;return LCD controller to normal mode statusi 0x08 commandi 0xB2 ret checkControl0: ; checks the position of pot 0 ;set up analog converter to read channel zero ldi temp, 4 out ADMUX, temp rcall measure_resistance mov dres24uL, AnaLo mov dres24uM, AnaHi clr dres24uH ; divide by 130 ldi temp, 130 mov dv24uL, temp clr dv24uH rcall div24u rcall erasepaddle0 mov paddle0, dres24uL rcall drawpaddle0 ret checkControl1: ; checks the position of pot 1 ;set up analog converter to read channel three (channel one is dead?!) ldi temp, 6 out ADMUX, temp rcall measure_resistance mov dres24uL, AnaLo mov dres24uM, AnaHi clr dres24uH ldi temp, 130 mov dv24uL, temp clr dv24uH rcall div24u rcall erasepaddle1 mov paddle1, dres24uL rcall drawpaddle1 ret ;============================================= ;delay - subroutine waits for time equal to value in register timeout ;the register 'timeout' should be loaded before the call delay: tst timeout brne delay ret ;============================================= ;***** Timer 0 overflow interrupt handler ;timer 0 ISR (timer-zero overflow) ;Enters every 1.0 mSec t0int: in save, SREG out TCNT0, Reload; keeps clock ticking at 1 mSec dec timeout ;subtract another mSec noteyet:out SREG, save reti ;back to backgound tasks ;*********************************************************** ;Timer 1 interrupt (plays sound through the speaker) t1AMatch:;interrupt on compare match with value in OCR1A in save,SREG sbic PIND, speakerbit;toggle speaker output rjmp t1set sbi PORTD, speakerbit rjmp t1dec t1set: cbi PORTD, speakerbit t1dec: sbiw ZL,1 brne t1end ldi temp,timer1off; turn off the noize once we reach 0 on the Z counter out TIMSK,temp t1end: out SREG,save reti ; draw paddle routines drawpaddle0: ldi addrh, 0 ldi addrl, 30 ; each graphic line is 30 bytes long ; determine y (what row) ; multiply mov temp, paddle0 rcall mpy8u ; move address pointer to paddle location rcall moveto ldi temp2, 0b00000001 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000011 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b00000001 rcall status3 write temp2 rcall status3 commandi 0xC4 ret drawpaddle1: ldi addrh, 0 ldi addrl, 30 ; each graphic line is 30 bytes long ; determine y (what row) ; multiply mov temp, paddle1 rcall mpy8u adiw addrl, 29 ; move address pointer to paddle location rcall moveto ldi temp2, 0b10000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b11000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 rcall moveto ldi temp2, 0b10000000 rcall status3 write temp2 rcall status3 commandi 0xC4 ret ; erase paddle routines erasepaddle0: ldi addrh, 0 ldi addrl, 30 ; each graphic line is 30 bytes long ; determine y (what row) ; multiply mov temp, paddle0 rcall mpy8u ldi cnt, 16 eraseloop0: ; move address pointer to paddle location rcall moveto ldi temp2, 0b00000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 dec cnt brne eraseloop0 ret erasepaddle1: ldi addrh, 0 ldi addrl, 30 ; each graphic line is 30 bytes long ; determine y (what row) ; multiply mov temp, paddle1 rcall mpy8u ldi cnt, 16 adiw addrl, 29 eraseloop1: ; move address pointer to paddle location rcall moveto ldi temp2, 0b00000000 rcall status3 write temp2 rcall status3 commandi 0xC4 adiw addrl, 30 dec cnt brne eraseloop1 ret ; Helper for reading the ADC ; Code adapted from the Digital Voltmeter lab measure_resistance: ldi temp1, 0b11000101 ;start A to D conversion out ADCSR, temp1 await: in temp, ADCSR ;wait for A to D done andi temp, 0b01000000;by checking ADSC bit brne await ;this bit is cleared by the AtoD hardware in AnaLo, ADCL ;read the voltage in AnaHi, ADCH ldi temp,low(1250);put 1250 = 5V into denom mov dv24uL,temp ldi temp,high(1250) mov dv24uH,temp sub dv24uL,AnaLo ;find 1250 - Ana for resistance calculations sbc dv24uH,AnaHi ldi temp,low(R) ;multiplier = R mov mp16uL,temp ldi temp,high(R) mov mp16uH,temp mov mc16uL,AnaLo ;multiplicand = V mov mc16uH,AnaHi rcall mpy16u rcall div24u ;RV / vcc - v -> result is in r4,5 hopefully, r7 is 0 mov AnaLo,r10 ;mov result to AnaLo/Hi for printing to LCD mov AnaHi,r11 ret screenflash: ;** flashes the LCD after someone misses the ball ldi cnt,3 screenflash2: ;set the address pointer to the beginning of memory statusi 0x03 writei 0x00 statusi 0x03 writei 0x00 statusi 0x03 commandi 0x24 ;Zero out counter ldi addrh,0 ldi addrl,0 ;set up autowrite statusi 0x03 commandi 0xB0 screenflashloop: ;inc counter addi16 addrh, addrl, 0x0001 ; play noise out OCR1AH, addrl out OCR1AL, addrh ldi ZL,low(10) ldi ZH,high(10) ldi temp,timer1on out TIMSK,temp ;write zero to memory statusi 0x08 writei 0xFF ;check loop status cpi16 addrh, addrl, 0x1680 brne screenflashloop ;return LCD controller to normal mode statusi 0x08 commandi 0xB2 ldi temp, 100 mov timeout, temp rcall delay ;set the address pointer to the beginning of memory statusi 0x03 writei 0x00 statusi 0x03 writei 0x00 statusi 0x03 commandi 0x24 ;Zero out counter ldi addrh,0 ldi addrl,0 ;set up autowrite statusi 0x03 commandi 0xB0 screenflashloop2: ;inc counter addi16 addrh, addrl, 0x0001 ;write zero to memory statusi 0x08 writei 0x00 ;check loop status cpi16 addrh, addrl, 0x1680 brne screenflashloop2 ;return LCD controller to normal mode statusi 0x08 commandi 0xB2 ldi temp, 100 mov timeout,temp rcall delay dec cnt tst cnt breq screenflashend rjmp screenflash2 screenflashend: rjmp nextGame writelabels: ; Writes labels on the screen before each new game ;set pointer to begin writing sbrc score0, 2 rjmp p0Win sbrc score1, 2 rjmp p1Win brtc firstgame sbrs balldx, 7 rjmp p1msg ldi R31, high(P0*2) ldi R30, low(P0*2) rjmp printMsg p1msg: ldi R31, high(P1*2) ldi R30, low(P1*2) rjmp printMsg firstgame: set; turn off first game flag ldi R31, high(MSG*2) ldi R30, low(MSG*2) printMsg: ldi addrl, low(0x141E) ldi addrh, high(0x141E) rcall status3 write addrl rcall status3 write addrh rcall status3 commandi 0x24 rcall writepgmem ; move to print scores ldi addrl, low(0x15c2) ldi addrh, high(0x15c2) rcall status3 write addrl rcall status3 write addrh rcall status3 commandi 0x24 mov temp2, score0 ori temp2, 0b00010000 rcall status3 write temp2 rcall status3 commandi 0xC0 ; move to print scores ldi addrl, low(0x15df) Build your own community today with the largest message board hosting company. |