<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://pauljmac.com/projects/index.php?action=history&amp;feed=atom&amp;title=Ping_Pong_Scoreboard</id>
	<title>Ping Pong Scoreboard - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://pauljmac.com/projects/index.php?action=history&amp;feed=atom&amp;title=Ping_Pong_Scoreboard"/>
	<link rel="alternate" type="text/html" href="https://pauljmac.com/projects/index.php?title=Ping_Pong_Scoreboard&amp;action=history"/>
	<updated>2026-04-21T13:59:42Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.42.3</generator>
	<entry>
		<id>https://pauljmac.com/projects/index.php?title=Ping_Pong_Scoreboard&amp;diff=9&amp;oldid=prev</id>
		<title>Paul: Created page with &quot;== Updates == &lt;section begin=updates /&gt;*New! Ping Pong Scoreboard! --Paul 13:16, 10 January 2008 (EST)&lt;section end=updates /&gt; &lt;section begin=oldnews /&gt; &lt;section end=oldnews /&gt;  ==Abstract== This device is intended to make score keeping easier and more spectator friendly for the game of ping pong. It consists of 2 double digit 7-0segment displays, 1 display for each player. Each display has 5 LEDs that are used to indicate the player’s current serve. The d...&quot;</title>
		<link rel="alternate" type="text/html" href="https://pauljmac.com/projects/index.php?title=Ping_Pong_Scoreboard&amp;diff=9&amp;oldid=prev"/>
		<updated>2024-12-08T16:07:16Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;== Updates == &amp;lt;section begin=updates /&amp;gt;*New! Ping Pong Scoreboard! --&lt;a href=&quot;/projects/index.php?title=User:Paul&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;User:Paul (page does not exist)&quot;&gt;Paul&lt;/a&gt; 13:16, 10 January 2008 (EST)&amp;lt;section end=updates /&amp;gt; &amp;lt;section begin=oldnews /&amp;gt; &amp;lt;section end=oldnews /&amp;gt;  ==Abstract== This device is intended to make score keeping easier and more spectator friendly for the game of ping pong. It consists of 2 double digit 7-0segment displays, 1 display for each player. Each display has 5 LEDs that are used to indicate the player’s current serve. The d...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Updates ==&lt;br /&gt;
&amp;lt;section begin=updates /&amp;gt;*New! Ping Pong Scoreboard! --[[User:Paul|Paul]] 13:16, 10 January 2008 (EST)&amp;lt;section end=updates /&amp;gt;&lt;br /&gt;
&amp;lt;section begin=oldnews /&amp;gt;&lt;br /&gt;
&amp;lt;section end=oldnews /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
This device is intended to make score keeping easier and more spectator friendly for the game of ping pong. It consists of 2 double digit 7-0segment displays, 1 display for each player. Each display has 5 LEDs that are used to indicate the player’s current serve. The device can operate in the old 21 point style game or the new 11 point style game. The game mode is selected using the Game Mode switch.  After selecting the desired game mode the user should reset the board to register the change. The device has a cord that links 3 buttons to the main score board. The 3 buttons are intended to be taped to the underside of one of the player’s court. This allows 1 player to control the score without interfering with the playing field. The 3 buttons are P1 score, P2 Score and Undo. P1 and P2 score are used to give the respective player a point for winning a rally. The Undo button is to correct a miss used button.  The undo is only 1 level deep, meaning it can only undo your last action. The scoreboard will automatically calculate whose serve it is and display it on the LEDs. The scoreboard even works when the game becomes Duce and a player must win by 2 and serve alternates every round. When a player reaches a winning condition the scoreboard will flash indicating the game is over. After a game is over the scoreboard should be reset to continue with a new game.&lt;br /&gt;
&lt;br /&gt;
The PIC I used may seem like a strange selection but honestly the only reason I chose it was because I had extras lying around. Normally I wouldn&amp;#039;t use an IC as expensive as the MAX7221 ($10!) but again I had one lying around.&lt;br /&gt;
&lt;br /&gt;
== Parts ==&lt;br /&gt;
&amp;lt;table border=0 cellpadding=0 cellspacing=0 width=267 style=&amp;#039;border-collapse:&lt;br /&gt;
 collapse;table-layout:fixed;width:200pt&amp;#039;&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=21 style=&amp;#039;height:15.75pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=21 class=xl66 width=203 style=&amp;#039;height:15.75pt;width:152pt&amp;#039;&amp;gt;Part&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl67 width=64 style=&amp;#039;border-left:none;width:48pt&amp;#039;&amp;gt;QTY&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl71 style=&amp;#039;height:15.0pt;border-top:none&amp;#039;&amp;gt;NO momentary&lt;br /&gt;
  buttons&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;4&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;SPST switch&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;5&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;10K resistors&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;6&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;20MHZ Crystal&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;27pF ceramic caps&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;10uF cap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;1uF cap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;double digit 7-segment&lt;br /&gt;
  displays&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;LEDs&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;10&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;PIC16F872&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;MAX7221&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;6 pos male ICSP header&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;signal diode 1N4148&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td height=20 class=xl72 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;2n3904 npn&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td class=xl68&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;mso-height-source:userset;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td rowspan=3 height=61 class=xl73 width=203 style=&amp;#039;border-bottom:1.0pt solid black;&lt;br /&gt;
  height:45.75pt;width:152pt&amp;#039;&amp;gt;current limiting resistor dependent on your&lt;br /&gt;
  7-segment displays&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td rowspan=3 class=xl69 style=&amp;#039;border-bottom:1.0pt solid black&amp;#039;&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=20 style=&amp;#039;height:15.0pt&amp;#039;&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr height=21 style=&amp;#039;height:15.75pt&amp;#039;&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tr height=0 style=&amp;#039;display:none&amp;#039;&amp;gt;&lt;br /&gt;
  &amp;lt;td width=203 style=&amp;#039;width:152pt&amp;#039;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td width=64 style=&amp;#039;width:48pt&amp;#039;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Schematic ==&lt;br /&gt;
[[Image:PingPongScoreboard.png|500px]]&lt;br /&gt;
&lt;br /&gt;
[http://pauljmac.com/projects/images/e/ec/PingPongSchem.zip EAGLE schem]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
Full MPLAB project here: [http://pauljmac.com/projects/images/3/35/PingPong1.zip]&lt;br /&gt;
&lt;br /&gt;
Spelling not guaranteed in code. :-)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
;                                                                     *&lt;br /&gt;
;    Filename:	    main.asm                                          *&lt;br /&gt;
;    Date: 01/08/08                                                   *&lt;br /&gt;
;    File Version: 1.0                                                *&lt;br /&gt;
;                                                                     *&lt;br /&gt;
;    Author: Paul Mac                                                 *&lt;br /&gt;
;            me@pauljmac.com                                          * &lt;br /&gt;
;            http://pauljmac.com                                      *&lt;br /&gt;
;            Copyright Paul Mac 2008. Some Rights Reserved.           *&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
;                                                                     *&lt;br /&gt;
;    Files required:  P16872.INC                                      *&lt;br /&gt;
;                                                                     *&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
;                                                                     *&lt;br /&gt;
;    Notes: This is a program used to keep score of a Ping-Pong game. *&lt;br /&gt;
;   It uses a 16F872 and a MAX7221 7-segment driver with 4 displays.  *&lt;br /&gt;
;   The tracker also keeps score of whose serve it is and can even    *&lt;br /&gt;
;   commutate serve/score while in Duce. The Mode Switch is used to   *&lt;br /&gt;
;   tell the program weather to run an old style 21 point game or a   *&lt;br /&gt;
;   new 11 point style game. The game mode switch is read after a     *&lt;br /&gt;
;   reset. The &amp;quot;main controls&amp;quot; consists of 3 buttons: P1, P2 and Undo *&lt;br /&gt;
;   P1 and P2 is used to increment the scores while undo is, well,    * &lt;br /&gt;
;   UNDO! The undo button is for if you just hit the wrong player     *&lt;br /&gt;
;   button and need to undo it. The undo is only 1 level deep.        *&lt;br /&gt;
;   Meaning you can only undo your last	incorrect score increment.    *&lt;br /&gt;
;   There’s no 3 or 4 undo’s here, it’s not MS word.                  *&lt;br /&gt;
;   When a player reaches the winning point the scoreboard            *	&lt;br /&gt;
;   will flash indicating the games over. Score can continue after    *&lt;br /&gt;
;   a winning game condition, but the score board may do some funky   *&lt;br /&gt;
;   things, as its not intended to still be used after a winning game *&lt;br /&gt;
;   condition. The Scoreboard should be reset after a winning game.   *&lt;br /&gt;
;                                                                     *&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
; This work is licensed under the Creative Commons                    *&lt;br /&gt;
; Attribution-Noncommercial-Share Alike 3.0 United States License.    *&lt;br /&gt;
; To view a copy of this license, visit                               *&lt;br /&gt;
; http://creativecommons.org/licenses/by-nc-sa/3.0/us/ or send a      *&lt;br /&gt;
; letter to Creative Commons, 171 Second Street, Suite 300,           *&lt;br /&gt;
; San Francisco, California, 94105, USA.                              *&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	list      p=16f872            ; list directive to define processor&lt;br /&gt;
	#include &amp;lt;p16f872.inc&amp;gt;        ; processor specific variable definitions&lt;br /&gt;
	&lt;br /&gt;
	__CONFIG _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _BODEN_OFF &amp;amp; _PWRTE_ON &amp;amp; _HS_OSC &amp;amp; _WRT_ENABLE_ON &amp;amp; _LVP_OFF &amp;amp; _CPD_OFF&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;***** VARIABLE DEFINITIONS&lt;br /&gt;
	cblock 0x20&lt;br /&gt;
	p1s, p2s, serve, p1score, p2score, u1,u2, displaydelay, displaydelay1, toggle&lt;br /&gt;
	bin, hundreds, tens_and_ones&lt;br /&gt;
	p1button, p2button, undobutton, two, temp, gameover, gameovertoggle, gameovercounter&lt;br /&gt;
	d1,d2,d3&lt;br /&gt;
	endc&lt;br /&gt;
	&lt;br /&gt;
#define	CS	PORTC,7&lt;br /&gt;
#define	SL1	PORTC,2&lt;br /&gt;
#define	SL2	PORTA,5&lt;br /&gt;
#define	P1B	PORTA,0&lt;br /&gt;
#define	P2B	PORTA,1&lt;br /&gt;
#define	UndoB	PORTA,2&lt;br /&gt;
#define	Mode	PORTA,3&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;**********************************************************************&lt;br /&gt;
	ORG     0x000             ; processor reset vector&lt;br /&gt;
	clrf    PCLATH            ; ensure page bits are cleared&lt;br /&gt;
 	goto    main              ; go to beginning of program&lt;br /&gt;
&lt;br /&gt;
	ORG 	0x020&lt;br /&gt;
	ORG 	0x020&lt;br /&gt;
main&lt;br /&gt;
	BANKSEL	PORTA&lt;br /&gt;
	clrf	PORTA&lt;br /&gt;
	clrf	PORTB&lt;br /&gt;
	clrf	PORTC&lt;br /&gt;
	BANKSEL	TRISA&lt;br /&gt;
	clrf	TRISA&lt;br /&gt;
	clrf	TRISB&lt;br /&gt;
	clrf	TRISC&lt;br /&gt;
	movlw	b&amp;#039;00000110&amp;#039;		;turnning off analog inputs&lt;br /&gt;
	BANKSEL ADCON1&lt;br /&gt;
	movwf	ADCON1&lt;br /&gt;
	movlw	b&amp;#039;00001111&amp;#039;		;setting buttons to input&lt;br /&gt;
	BANKSEL	TRISA&lt;br /&gt;
	movwf	TRISA&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;		;the server indicator LEDs&lt;br /&gt;
	movwf	TRISB&lt;br /&gt;
	movlw	b&amp;#039;00010000&amp;#039;&lt;br /&gt;
	movwf	TRISC&lt;br /&gt;
	BANKSEL	p1score&lt;br /&gt;
	clrf	p1score&lt;br /&gt;
	clrf	p2score&lt;br /&gt;
	clrf	p1s&lt;br /&gt;
	clrf	p2s&lt;br /&gt;
	clrf	serve&lt;br /&gt;
	clrf	p1button&lt;br /&gt;
	clrf	p2button&lt;br /&gt;
	clrf	undobutton&lt;br /&gt;
	clrf	gameover&lt;br /&gt;
	banksel	displaydelay1&lt;br /&gt;
	movlw	0xFF&lt;br /&gt;
	movwf	displaydelay1&lt;br /&gt;
	movwf	displaydelay&lt;br /&gt;
	movlw	0x02&lt;br /&gt;
	movwf	two&lt;br /&gt;
	movlw	0x19	;25&lt;br /&gt;
	movwf	gameovercounter&lt;br /&gt;
	banksel	PORTC&lt;br /&gt;
	bsf		CS			;the CS pin for the 7221&lt;br /&gt;
	movlw	0xC0&lt;br /&gt;
	banksel	SSPSTAT&lt;br /&gt;
	movwf	SSPSTAT&lt;br /&gt;
	movlw	0x20		;setup SPI&lt;br /&gt;
	banksel	SSPCON&lt;br /&gt;
	movwf	SSPCON&lt;br /&gt;
	movlw	0x0F		;put the MAX7221 into normal mode&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bcf		CS		;Chip Select the MAX&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	movlw	0x00		;normal mode&lt;br /&gt;
	call 	SendSPI&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bsf		CS		;unchip select the MAX&lt;br /&gt;
	movlw	0x0C		;Shutdown register&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bcf		CS		;&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	movlw	0x01		;normal operation&lt;br /&gt;
	call 	SendSPI&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bsf		CS		;&lt;br /&gt;
	movlw	0x0A		;Intensity register&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bcf		CS		;&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	movlw	0x0F		;Max on&lt;br /&gt;
	call 	SendSPI&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bsf		CS		;&lt;br /&gt;
	movlw	0x0B		;Scan-Limit register&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bcf		CS		;&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	movlw	0x03		;4 digits&lt;br /&gt;
	call 	SendSPI&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bsf		CS		;&lt;br /&gt;
	movlw	0x09		;decode mode register&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bcf		CS		;&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	movlw	0xFF		;all decode&lt;br /&gt;
	call 	SendSPI&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bsf		CS		;&lt;br /&gt;
	call	ClearSegs&lt;br /&gt;
	btfss	Mode			;test the mode switch. if its low its 21 point game, if high 11 point game&lt;br /&gt;
	goto	new_type&lt;br /&gt;
	goto	old_type&lt;br /&gt;
old_type				;begin the 21 point style play. Waiting for the user to select who has first serve.&lt;br /&gt;
	movlw	1&lt;br /&gt;
	BANKSEL	serve&lt;br /&gt;
	movwf	serve&lt;br /&gt;
	call	PollButtons&lt;br /&gt;
	btfsc	p1button,0			;poll the player 1 button&lt;br /&gt;
	goto	loadp1&lt;br /&gt;
	btfsc	p2button,0			;poll the player 2 button&lt;br /&gt;
	goto	loadp2&lt;br /&gt;
	goto	old_type		;loop, lol forgot this the first time	&lt;br /&gt;
PollButtons&lt;br /&gt;
	BANKSEL	PORTA&lt;br /&gt;
	btfss	P1B			;poll the player 1 button&lt;br /&gt;
	call	Player1Button&lt;br /&gt;
	btfss	P2B			;poll the player 2 button&lt;br /&gt;
	call	Player2Button&lt;br /&gt;
	btfss	UndoB&lt;br /&gt;
	call	UndoButton&lt;br /&gt;
	return&lt;br /&gt;
Player1Button&lt;br /&gt;
	btfss	P1B&lt;br /&gt;
	bsf		p1button,0&lt;br /&gt;
Player1Button_Test&lt;br /&gt;
	btfsc	P1B&lt;br /&gt;
	goto	Player1Button_Return&lt;br /&gt;
	goto	Player1Button_Test&lt;br /&gt;
Player1Button_Return&lt;br /&gt;
	call	Twenty_mS_Delay&lt;br /&gt;
	return&lt;br /&gt;
Player2Button&lt;br /&gt;
	btfss	P2B&lt;br /&gt;
	bsf		p2button,0&lt;br /&gt;
Player2Button_Test&lt;br /&gt;
	btfsc	P2B&lt;br /&gt;
	goto	Player2Button_Return&lt;br /&gt;
	goto	Player2Button_Test&lt;br /&gt;
Player2Button_Return&lt;br /&gt;
	call	Twenty_mS_Delay&lt;br /&gt;
	return&lt;br /&gt;
UndoButton&lt;br /&gt;
	btfss	UndoB&lt;br /&gt;
	bsf		undobutton,0&lt;br /&gt;
UndoButton_Test&lt;br /&gt;
	btfsc	UndoB&lt;br /&gt;
	goto	UndoButton_Return&lt;br /&gt;
	goto	UndoButton_Test&lt;br /&gt;
UndoButton_Return&lt;br /&gt;
	call	Twenty_mS_Delay&lt;br /&gt;
	return	&lt;br /&gt;
loadp1&lt;br /&gt;
	bsf		p1s,0			;set p1s bit 0 indicateing they are current server&lt;br /&gt;
	goto	Startold&lt;br /&gt;
loadp2&lt;br /&gt;
	bsf		p2s,0			;set p2s bit 0 indicateing they are current server&lt;br /&gt;
	goto	Startold&lt;br /&gt;
ClearButtons&lt;br /&gt;
	bcf		p1button,0&lt;br /&gt;
	bcf		p2button,0&lt;br /&gt;
	bcf		undobutton,0&lt;br /&gt;
	return&lt;br /&gt;
Startold&lt;br /&gt;
	call 	ClearButtons&lt;br /&gt;
	call	DisplayRoutine&lt;br /&gt;
	call    PollButtons&lt;br /&gt;
	movlw	0x15&lt;br /&gt;
	subwf	p1score,w&lt;br /&gt;
	btfsc	STATUS,Z		;test the Zero flag. It will be set if the score is 21	&lt;br /&gt;
	bsf		gameover,0		;set game over mode&lt;br /&gt;
	movlw	0x15&lt;br /&gt;
	subwf	p2score,w&lt;br /&gt;
	btfsc	STATUS,Z		;test the Zero flag. It will be set if the score is 21		&lt;br /&gt;
	bsf		gameover,0		;set game over mode&lt;br /&gt;
	btfsc	p1button,0			;test p1 button for a p1score++&lt;br /&gt;
	call	Addp1&lt;br /&gt;
	btfsc	p2button,0			;test p2 button for a p2score++&lt;br /&gt;
	call	Addp2&lt;br /&gt;
	btfsc	undobutton,0		;test undo button&lt;br /&gt;
	call 	Undo&lt;br /&gt;
	movlw	0x14				;setup to see if the serve # is more than 20&lt;br /&gt;
	subwf	p1score,w		;subtract 20&lt;br /&gt;
	btfss	STATUS,Z		;test the Zero flag. It will be clear if the serve is less than 20	&lt;br /&gt;
	goto	Startold&lt;br /&gt;
	movlw	0x14				;setup to see if the serve # is more than 20&lt;br /&gt;
	subwf	p2score,w		;subtract 20&lt;br /&gt;
	btfss	STATUS,Z		;test the carry flag. It will be clear if the serve is less than 20	&lt;br /&gt;
	goto	Startold&lt;br /&gt;
	goto	Duce&lt;br /&gt;
Duce&lt;br /&gt;
	call	ClearButtons&lt;br /&gt;
	call    PollButtons&lt;br /&gt;
	btfsc	p1button,0			;test p1 button for a p1score++&lt;br /&gt;
	call	Addp1Duce&lt;br /&gt;
	btfsc	p2button,0			;test p2 button for a p2score++&lt;br /&gt;
	call	Addp2Duce&lt;br /&gt;
	btfsc	undobutton,0		;test undo button&lt;br /&gt;
	call 	UndoDuce&lt;br /&gt;
	call	DisplayRoutine&lt;br /&gt;
	call	TestDuceGameOver&lt;br /&gt;
	goto	Duce	&lt;br /&gt;
UndoDuce&lt;br /&gt;
	call	GameOverOn&lt;br /&gt;
	movfw	p1score			;add p1 and p2 score to see if its 20&lt;br /&gt;
	addwf	p2score,w&lt;br /&gt;
	banksel	temp&lt;br /&gt;
	movwf	temp&lt;br /&gt;
	movlw	0x28&lt;br /&gt;
	subwf	temp,w&lt;br /&gt;
	btfss	STATUS,Z		;test the carry flag. It will be clear if the serve is less than 20	&lt;br /&gt;
	goto	UndoDuce1&lt;br /&gt;
	movlw	0x06&lt;br /&gt;
	movwf	serve&lt;br /&gt;
	banksel	p1s&lt;br /&gt;
	comf	p1s,f&lt;br /&gt;
	comf	p2s,f&lt;br /&gt;
	goto	UndoReturn&lt;br /&gt;
UndoReturn&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	btfsc	u1,0			;see if the last point awarded was to p1&lt;br /&gt;
	call	UndoP1Return			;if it was do this &lt;br /&gt;
	btfsc	u2,0			;see if the last point awarded was to p2&lt;br /&gt;
	call	UndoP2Return&lt;br /&gt;
	goto	Startold&lt;br /&gt;
UndoP1Return&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p1score&lt;br /&gt;
	decf	p1score,f		;--p1score&lt;br /&gt;
	decf	serve,f			;--serve&lt;br /&gt;
	btfsc	STATUS,Z		;if Z flag is set that means that serve was at 1 and needs to be reset to 5&lt;br /&gt;
	call	UndoServe&lt;br /&gt;
	bcf		u1,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoP2Return&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p1score&lt;br /&gt;
	decf	p2score,f		;--p1score&lt;br /&gt;
	decf	serve,f			;--serve&lt;br /&gt;
	btfsc	STATUS,Z		;if Z flag is set that means that serve was at 1 and needs to be reset to 5&lt;br /&gt;
	call	UndoServe&lt;br /&gt;
	bcf		u2,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoDuce1&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	btfsc	u1,0			;see if the last point awarded was to p1&lt;br /&gt;
	call	UndoP1Duce		;if it was do this &lt;br /&gt;
	btfsc	u2,0			;see if the last point awarded was to p2&lt;br /&gt;
	call	UndoP2Duce&lt;br /&gt;
	return&lt;br /&gt;
UndoP1Duce&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p1score&lt;br /&gt;
	decf	p1score,f		;--p1score&lt;br /&gt;
	call	UndoServeDuce&lt;br /&gt;
	bcf		u1,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoP2Duce&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p2score&lt;br /&gt;
	decf	p2score,f		;--p2score&lt;br /&gt;
	call	UndoServeDuce&lt;br /&gt;
	bcf		u2,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoServeDuce&lt;br /&gt;
	comf	p1s,f&lt;br /&gt;
	comf	p2s,f&lt;br /&gt;
	return	&lt;br /&gt;
TestDuceGameOver&lt;br /&gt;
	banksel	p1score&lt;br /&gt;
	movfw	p1score&lt;br /&gt;
	subwf	p2score,w&lt;br /&gt;
	call	TestTwo&lt;br /&gt;
	banksel	p1score	&lt;br /&gt;
	movfw	p2score&lt;br /&gt;
	subwf	p1score,w&lt;br /&gt;
	call	TestTwo&lt;br /&gt;
	return&lt;br /&gt;
TestTwo&lt;br /&gt;
	banksel	two&lt;br /&gt;
	subwf	two,w			;subtract 2 and test X flag&lt;br /&gt;
	btfsc	STATUS,Z		;test the carry flag. It will be clear if the serve is less than 20	&lt;br /&gt;
	bsf		gameover,0&lt;br /&gt;
	return&lt;br /&gt;
Addp1Duce&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	bsf		u1,0			;set u1 indicateing that p1 was the last person to reviece a point (for undo button)&lt;br /&gt;
	bcf		u2,0			;clear u2 undo register sence u1 is being set now&lt;br /&gt;
	incf	p1score,f		;incrament p1score&lt;br /&gt;
	comf	p1s,f&lt;br /&gt;
	comf	p2s,f&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2	&lt;br /&gt;
	return					;return to the main game loop&lt;br /&gt;
Addp2Duce&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	bsf		u2,0			;set u2 indicateing that p2 was the last person to reviece a point (for undo button)&lt;br /&gt;
	bcf		u1,0			;clear u1 undo register sence u2 is being set now&lt;br /&gt;
	incf	p2score,f		;incrament p1score&lt;br /&gt;
	comf	p1s,f&lt;br /&gt;
	comf	p2s,f&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return	&lt;br /&gt;
Addp1&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	bsf		u1,0			;set u1 indicateing that p1 was the last person to reviece a point (for undo button)&lt;br /&gt;
	bcf		u2,0			;clear u2 undo register sence u1 is being set now&lt;br /&gt;
	incf	p1score,f		;incrament p1score&lt;br /&gt;
	incf	serve,f			;++ serve&lt;br /&gt;
	movlw	0x06			;setup to see if the serve # is more than 5&lt;br /&gt;
	subwf	serve,w			;subtract 6 from Serve&lt;br /&gt;
	btfsc	STATUS,C		;test the carry flag. It will be clear if Serve is less than 6&lt;br /&gt;
	call 	SwitchServe&lt;br /&gt;
	return					;return to the main game loop.	&lt;br /&gt;
Addp2&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	bsf		u2,0			;set u2 indicateing that p2 was the last person to reviece a point (for undo button)&lt;br /&gt;
	bcf		u1,0			;clear u1 undo register sence u2 is being set now&lt;br /&gt;
	incf	p2score,f		;incrament p1score&lt;br /&gt;
	incf	serve,f			&lt;br /&gt;
	movlw	0x06			;setup to see if the serve # is more than 5&lt;br /&gt;
	subwf	serve,w			;subtract 6 from Serve&lt;br /&gt;
	btfsc	STATUS,C		;test the carry flag. It will be clear if Serve is less than 6&lt;br /&gt;
	call 	SwitchServe&lt;br /&gt;
	return					;return to the main game loop.&lt;br /&gt;
Undo&lt;br /&gt;
	call	GameOverOn&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	btfsc	u1,0			;see if the last point awarded was to p1&lt;br /&gt;
	call	UndoP1			;if it was do this &lt;br /&gt;
	btfsc	u2,0			;see if the last point awarded was to p2&lt;br /&gt;
	call	UndoP2&lt;br /&gt;
	return&lt;br /&gt;
UndoP1&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p1score&lt;br /&gt;
	decf	p1score,f		;--p1score&lt;br /&gt;
	decf	serve,f			;--serve&lt;br /&gt;
	btfsc	STATUS,Z		;if Z flag is set that means that serve was at 1 and needs to be reset to 5&lt;br /&gt;
	call	UndoServe&lt;br /&gt;
	bcf		u1,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoP2&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p1score&lt;br /&gt;
	decf	p2score,f		;--p1score&lt;br /&gt;
	decf	serve,f			;--serve&lt;br /&gt;
	btfsc	STATUS,Z		;if Z flag is set that means that serve was at 1 and needs to be reset to 5&lt;br /&gt;
	call	UndoServe&lt;br /&gt;
	bcf		u2,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoServe&lt;br /&gt;
	movlw	0x05&lt;br /&gt;
	movwf	serve&lt;br /&gt;
	comf	p1s,f&lt;br /&gt;
	comf	p2s,f&lt;br /&gt;
	return	&lt;br /&gt;
SwitchServe&lt;br /&gt;
	comf	p1s,f			;compliment p1s&lt;br /&gt;
	comf	p2s,f			;compliment p2s&lt;br /&gt;
	bcf		SL1			;turn OFF p1 server leds&lt;br /&gt;
	bcf		SL2			;turn OFF p2 server leds&lt;br /&gt;
	movlw	0x01			;reset the serve register &lt;br /&gt;
	banksel	serve&lt;br /&gt;
	movwf	serve	&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f	&lt;br /&gt;
	return	&lt;br /&gt;
DisplayRoutine&lt;br /&gt;
		;counter&lt;br /&gt;
	call	Two_mS_Delay&lt;br /&gt;
	banksel	displaydelay&lt;br /&gt;
	decfsz	displaydelay,f	;dec the display delay counter&lt;br /&gt;
	goto	Skip	&lt;br /&gt;
DisplayDelay1&lt;br /&gt;
	decfsz	displaydelay1,f&lt;br /&gt;
	goto	DisplayDelay1&lt;br /&gt;
	comf	toggle,f&lt;br /&gt;
	goto	Skip&lt;br /&gt;
Skip&lt;br /&gt;
	btfss	toggle,0&lt;br /&gt;
	goto	Normal_LED_Display&lt;br /&gt;
	goto	Toggle_LED_Display	&lt;br /&gt;
ResetToggler&lt;br /&gt;
	banksel	displaydelay1&lt;br /&gt;
	movlw	0xFF&lt;br /&gt;
	movwf	displaydelay1&lt;br /&gt;
	movwf	displaydelay&lt;br /&gt;
	bcf		gameover,0&lt;br /&gt;
	return&lt;br /&gt;
Normal_LED_Display&lt;br /&gt;
	btfsc	p1s,0			;test the p1 serve register, if its clear skip next&lt;br /&gt;
	bsf		SL1			;turn on p1 server leds&lt;br /&gt;
	btfsc	p2s,0			;test p2 serve register, if its clear (it shouldnet be at this point) skip.&lt;br /&gt;
	bsf		SL2			;turn on p2 server leds&lt;br /&gt;
	movlw	HIGH LookupServe	;got to preload the high bites into PCLATH for this lookup to work&lt;br /&gt;
	movwf	PCLATH&lt;br /&gt;
	banksel	serve&lt;br /&gt;
	movfw	serve			;move the current serve # to W&lt;br /&gt;
	call	LookupServe		;lookup the bit pattern&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	iorwf	PORTB,f			;OR the bit pattern with PORTB to display the correct LEDS&lt;br /&gt;
	goto	DisplayScores&lt;br /&gt;
Toggle_LED_Display&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;		;clear portb before we start this&lt;br /&gt;
	banksel PORTB			;&lt;br /&gt;
	andwf	PORTB,f			;&lt;br /&gt;
	btfsc	p1s,0			;test the p1 serve register, if its clear skip next&lt;br /&gt;
	bsf		SL1			;turn on p1 server leds&lt;br /&gt;
	btfsc	p2s,0			;test p2 serve register, if its clear (it shouldnet be at this point) skip.&lt;br /&gt;
	bsf		SL2			;turn on p2 server leds&lt;br /&gt;
	movlw	HIGH LookupServe	;got to preload the high bites into PCLATH for this lookup to work&lt;br /&gt;
	movwf	PCLATH&lt;br /&gt;
	banksel	serve&lt;br /&gt;
	decf	serve,w			;subtract 1 and put the result in W&lt;br /&gt;
	call	LookupServe		;lookup the bit pattern&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	iorwf	PORTB,f			;OR the bit pattern with PORTB to display the correct LEDS&lt;br /&gt;
	goto	DisplayScores&lt;br /&gt;
DisplayScores&lt;br /&gt;
		;player 1 digits&lt;br /&gt;
	movf	p1score,w		;move p1score to w&lt;br /&gt;
	movwf	bin				;move the p1score to bin for BCD computation&lt;br /&gt;
	call	binary_to_bcd&lt;br /&gt;
	movlw	0x01			;select the first digit to display&lt;br /&gt;
	bcf		CS&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	movf	tens_and_ones,w	;move tens_and_ones to W&lt;br /&gt;
	andlw	b&amp;#039;00001111&amp;#039;		;mask the crap and now ones is in W&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	bsf		CS&lt;br /&gt;
	movlw	0x02			;select the 2nd digit to display&lt;br /&gt;
	bcf		CS&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	swapf	tens_and_ones,w	;swap the nibbles in tens_and_ones and put it in W&lt;br /&gt;
	andlw	b&amp;#039;00001111&amp;#039;		;mask the crap and now tens is in W&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	bsf		CS&lt;br /&gt;
		;Do it all again for player 2 digits&lt;br /&gt;
	movf	p2score,w		;move p1score to w&lt;br /&gt;
	movwf	bin				;move the p1score to bin for BCD computation&lt;br /&gt;
	call	binary_to_bcd&lt;br /&gt;
	movlw	0x03			;select the first digit to display&lt;br /&gt;
	bcf		CS&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	movf	tens_and_ones,w	;move tens_and_ones to W&lt;br /&gt;
	andlw	b&amp;#039;00001111&amp;#039;		;mask the crap and now ones is in W&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	bsf		CS&lt;br /&gt;
	movlw	0x04			;select the 2nd digit to display&lt;br /&gt;
	bcf		CS&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	swapf	tens_and_ones,w	;swap the nibbles in tens_and_ones and put it in W&lt;br /&gt;
	andlw	b&amp;#039;00001111&amp;#039;		;mask the crap and now tens is in W&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	bsf		CS&lt;br /&gt;
	banksel gameover&lt;br /&gt;
	btfss	gameover,0&lt;br /&gt;
	return	;return the call if its not gameover mode&lt;br /&gt;
	call	Twenty_mS_Delay&lt;br /&gt;
	banksel	gameover&lt;br /&gt;
	decfsz	gameovercounter,f&lt;br /&gt;
	return	;return the call after the dec above&lt;br /&gt;
	banksel	gameovertoggle&lt;br /&gt;
	btfsc	gameovertoggle,0&lt;br /&gt;
	goto	GameOverOn&lt;br /&gt;
	goto	GameOverOff&lt;br /&gt;
GameOverOff&lt;br /&gt;
	bsf		gameovertoggle,0	&lt;br /&gt;
	movlw	0x0C		;Shutdown register&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bcf		CS		;&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	movlw	0x00		;shutdown mode&lt;br /&gt;
	call 	SendSPI&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bsf		CS		;&lt;br /&gt;
	movlw	0x19	;25&lt;br /&gt;
	movwf	gameovercounter&lt;br /&gt;
	return&lt;br /&gt;
GameOverOn	&lt;br /&gt;
	bcf		gameovertoggle,0	&lt;br /&gt;
	movlw	0x0C		;Shutdown register&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bcf		CS		;&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	movlw	0x01		;normal mode&lt;br /&gt;
	call 	SendSPI&lt;br /&gt;
	BANKSEL	PORTC&lt;br /&gt;
	bsf		CS		;&lt;br /&gt;
	movlw	0x19	;25&lt;br /&gt;
	movwf	gameovercounter&lt;br /&gt;
	return	&lt;br /&gt;
ClearSegs&lt;br /&gt;
	bcf		CS&lt;br /&gt;
	movlw	0x01			;initilize the 7segs by clearing all the digits&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	movlw	0x00&lt;br /&gt;
	call 	SendSPI&lt;br /&gt;
	bsf		CS&lt;br /&gt;
	bcf		CS&lt;br /&gt;
	movlw 	0x02&lt;br /&gt;
	call 	SendSPI&lt;br /&gt;
	movlw	0x00&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	bsf		CS&lt;br /&gt;
	bcf		CS&lt;br /&gt;
	movlw	0x03&lt;br /&gt;
	call 	SendSPI&lt;br /&gt;
	movlw 	0x00&lt;br /&gt;
	call 	SendSPI&lt;br /&gt;
	bsf		CS&lt;br /&gt;
	bcf		CS&lt;br /&gt;
	movlw	0x04&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	movlw	0x00&lt;br /&gt;
	call	SendSPI&lt;br /&gt;
	bsf		CS&lt;br /&gt;
	return&lt;br /&gt;
SendSPI						;This rutine will hold the MCU untill transmission is over. &lt;br /&gt;
	BANKSEL	SSPBUF			;If you want to load up the SSPBUF and GTFO dont use this.&lt;br /&gt;
	movwf	SSPBUF&lt;br /&gt;
wait1&lt;br /&gt;
	BANKSEL	SSPSTAT&lt;br /&gt;
	btfss	SSPSTAT,BF		;test to make sure its set indicateing the transmission is over&lt;br /&gt;
	goto	wait1			;when its over continue&lt;br /&gt;
	bcf		SSPSTAT,BF		;and clear the intrupt&lt;br /&gt;
	banksel	PORTA			; just get back to bank 0&lt;br /&gt;
	return&lt;br /&gt;
&lt;br /&gt;
;==================================================================&lt;br /&gt;
; 11 point style game&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
new_type				;begin the 11 point style play. Waiting for the user to select who has first serve.&lt;br /&gt;
	movlw	1&lt;br /&gt;
	BANKSEL	serve&lt;br /&gt;
	movwf	serve&lt;br /&gt;
	call	PollButtons&lt;br /&gt;
	btfsc	p1button,0			;poll the player 1 button&lt;br /&gt;
	goto	loadp1_new&lt;br /&gt;
	btfsc	p2button,0			;poll the player 2 button&lt;br /&gt;
	goto	loadp2_new&lt;br /&gt;
	goto	new_type		;loop, lol forgot this the first time&lt;br /&gt;
loadp1_new&lt;br /&gt;
	bsf		p1s,0			;set p1s bit 0 indicateing they are current server&lt;br /&gt;
	goto	Startnew&lt;br /&gt;
loadp2_new&lt;br /&gt;
	bsf		p2s,0			;set p2s bit 0 indicateing they are current server&lt;br /&gt;
	goto	Startnew		&lt;br /&gt;
Startnew&lt;br /&gt;
	call 	ClearButtons&lt;br /&gt;
	call	DisplayRoutine&lt;br /&gt;
	movlw	0x0B			;11&lt;br /&gt;
	subwf	p1score,w&lt;br /&gt;
	btfsc	STATUS,Z		;test the Zero flag. It will be set if the score is 11	&lt;br /&gt;
	bsf		gameover,0&lt;br /&gt;
	movlw	0x0B			;11&lt;br /&gt;
	subwf	p2score,w&lt;br /&gt;
	btfsc	STATUS,Z		;test the Zero flag. It will be set if the score is 11		&lt;br /&gt;
	bsf		gameover,0	&lt;br /&gt;
	call    PollButtons&lt;br /&gt;
	btfsc	p1button,0			;test p1 button for a p1score++&lt;br /&gt;
	call	Addp1_new&lt;br /&gt;
	btfsc	p2button,0			;test p2 button for a p2score++&lt;br /&gt;
	call	Addp2_new&lt;br /&gt;
	btfsc	undobutton,0			;test undo button&lt;br /&gt;
	call 	Undo_new&lt;br /&gt;
	movlw	0x0A				;setup to see if the serve # is more than 10&lt;br /&gt;
	subwf	p1score,w		;subtract 10&lt;br /&gt;
	btfss	STATUS,Z		;test the Zero flag. It will be clear if the serve is less than 10	&lt;br /&gt;
	goto	Startnew&lt;br /&gt;
	movlw	0x0A				;setup to see if the serve # is more than 10&lt;br /&gt;
	subwf	p2score,w		;subtract 10&lt;br /&gt;
	btfss	STATUS,Z		;test the carry flag. It will be clear if the serve is less than 10	&lt;br /&gt;
	goto	Startnew&lt;br /&gt;
	goto	Duce_new&lt;br /&gt;
Duce_new&lt;br /&gt;
	call	ClearButtons&lt;br /&gt;
	call    PollButtons&lt;br /&gt;
	btfsc	p1button,0			;test p1 button for a p1score++&lt;br /&gt;
	call	Addp1Duce_new&lt;br /&gt;
	btfsc	p2button,0			;test p2 button for a p2score++&lt;br /&gt;
	call	Addp2Duce_new&lt;br /&gt;
	btfsc	undobutton,0		;test undo button&lt;br /&gt;
	call 	UndoDuce_new&lt;br /&gt;
	call	DisplayRoutine&lt;br /&gt;
	call	TestDuceGameOver_new&lt;br /&gt;
	goto	Duce_new&lt;br /&gt;
UndoDuce_new&lt;br /&gt;
	call	GameOverOn&lt;br /&gt;
	movfw	p1score			;add p1 and p2 score to see if its 20&lt;br /&gt;
	addwf	p2score,w&lt;br /&gt;
	banksel	temp&lt;br /&gt;
	movwf	temp&lt;br /&gt;
	movlw	0x14			;20&lt;br /&gt;
	subwf	temp,w&lt;br /&gt;
	btfss	STATUS,Z		;test the carry flag. It will be clear if the serve is less than 20	&lt;br /&gt;
	goto	UndoDuce1_new&lt;br /&gt;
	movlw	0x03&lt;br /&gt;
	movwf	serve&lt;br /&gt;
	banksel	p1s&lt;br /&gt;
	comf	p1s,f&lt;br /&gt;
	comf	p2s,f&lt;br /&gt;
	goto	UndoReturn_new&lt;br /&gt;
UndoReturn_new&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	btfsc	u1,0			;see if the last point awarded was to p1&lt;br /&gt;
	call	UndoP1Return_new			;if it was do this &lt;br /&gt;
	btfsc	u2,0			;see if the last point awarded was to p2&lt;br /&gt;
	call	UndoP2Return_new&lt;br /&gt;
	goto	Startnew&lt;br /&gt;
UndoP1Return_new&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p1score&lt;br /&gt;
	decf	p1score,f		;--p1score&lt;br /&gt;
	decf	serve,f			;--serve&lt;br /&gt;
	btfsc	STATUS,Z		;if Z flag is set that means that serve was at 1 and needs to be reset to 2 &lt;br /&gt;
	call	UndoServe_new&lt;br /&gt;
	bcf		u1,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoP2Return_new&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p1score&lt;br /&gt;
	decf	p2score,f		;--p1score&lt;br /&gt;
	decf	serve,f			;--serve&lt;br /&gt;
	btfsc	STATUS,Z		;if Z flag is set that means that serve was at 1 and needs to be reset to 5&lt;br /&gt;
	call	UndoServe_new&lt;br /&gt;
	bcf		u2,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoDuce1_new&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	btfsc	u1,0			;see if the last point awarded was to p1&lt;br /&gt;
	call	UndoP1Duce_new		;if it was do this &lt;br /&gt;
	btfsc	u2,0			;see if the last point awarded was to p2&lt;br /&gt;
	call	UndoP2Duce_new&lt;br /&gt;
	return&lt;br /&gt;
UndoP1Duce_new&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p1score&lt;br /&gt;
	decf	p1score,f		;--p1score&lt;br /&gt;
	call	UndoServeDuce_new&lt;br /&gt;
	bcf		u1,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoP2Duce_new&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p2score&lt;br /&gt;
	decf	p2score,f		;--p2score&lt;br /&gt;
	call	UndoServeDuce_new&lt;br /&gt;
	bcf		u2,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoServeDuce_new&lt;br /&gt;
	comf	p1s,f&lt;br /&gt;
	comf	p2s,f&lt;br /&gt;
	return&lt;br /&gt;
TestDuceGameOver_new&lt;br /&gt;
	banksel	p1score&lt;br /&gt;
	movfw	p1score&lt;br /&gt;
	subwf	p2score,w&lt;br /&gt;
	call	TestTwo_new&lt;br /&gt;
	banksel	p1score	&lt;br /&gt;
	movfw	p2score&lt;br /&gt;
	subwf	p1score,w&lt;br /&gt;
	call	TestTwo_new&lt;br /&gt;
	return&lt;br /&gt;
TestTwo_new&lt;br /&gt;
	banksel	two&lt;br /&gt;
	subwf	two,w			;subtract 2 and test X flag&lt;br /&gt;
	btfsc	STATUS,Z		;test the carry flag. It will be clear if the serve is less than 20	&lt;br /&gt;
	bsf		gameover,0&lt;br /&gt;
	return&lt;br /&gt;
Addp1Duce_new&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	bsf		u1,0			;set u1 indicateing that p1 was the last person to reviece a point (for undo button)&lt;br /&gt;
	bcf		u2,0			;clear u2 undo register sence u1 is being set now&lt;br /&gt;
	incf	p1score,f		;incrament p1score&lt;br /&gt;
	comf	p1s,f&lt;br /&gt;
	comf	p2s,f&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2	&lt;br /&gt;
	return					;return to the main game loop&lt;br /&gt;
Addp2Duce_new&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	bsf		u2,0			;set u2 indicateing that p2 was the last person to reviece a point (for undo button)&lt;br /&gt;
	bcf		u1,0			;clear u1 undo register sence u2 is being set now&lt;br /&gt;
	incf	p2score,f		;incrament p1score&lt;br /&gt;
	comf	p1s,f&lt;br /&gt;
	comf	p2s,f&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return	&lt;br /&gt;
Addp1_new&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	bsf		u1,0			;set u1 indicateing that p1 was the last person to reviece a point (for undo button)&lt;br /&gt;
	bcf		u2,0			;clear u2 undo register sence u1 is being set now&lt;br /&gt;
	incf	p1score,f		;incrament p1score&lt;br /&gt;
	incf	serve,f			;++ serve&lt;br /&gt;
	movlw	0x03			;setup to see if the serve # is more than 2&lt;br /&gt;
	subwf	serve,w			;subtract 3 from Serve&lt;br /&gt;
	btfsc	STATUS,C		;test the carry flag. It will be clear if Serve is less than 3&lt;br /&gt;
	call 	SwitchServe_new&lt;br /&gt;
	return					;return to the main game loop.&lt;br /&gt;
Addp2_new&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	bsf		u2,0			;set u2 indicateing that p2 was the last person to reviece a point (for undo button)&lt;br /&gt;
	bcf		u1,0			;clear u1 undo register sence u2 is being set now&lt;br /&gt;
	incf	p2score,f		;incrament p1score&lt;br /&gt;
	incf	serve,f			&lt;br /&gt;
	movlw	0x03			;setup to see if the serve # is more than 2&lt;br /&gt;
	subwf	serve,w			;subtract 3 from Serve&lt;br /&gt;
	btfsc	STATUS,C		;test the carry flag. It will be clear if Serve is less than 3&lt;br /&gt;
	call 	SwitchServe_new&lt;br /&gt;
	return					;return to the main game loop.&lt;br /&gt;
Undo_new&lt;br /&gt;
	call	GameOverOn&lt;br /&gt;
	call	ResetToggler&lt;br /&gt;
	bcf		toggle,0&lt;br /&gt;
	btfsc	u1,0			;see if the last point awarded was to p1&lt;br /&gt;
	call	UndoP1_new			;if it was do this &lt;br /&gt;
	btfsc	u2,0			;see if the last point awarded was to p2&lt;br /&gt;
	call	UndoP2_new&lt;br /&gt;
	return&lt;br /&gt;
UndoP1_new&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p1score&lt;br /&gt;
	decf	p1score,f		;--p1score&lt;br /&gt;
	decf	serve,f			;--serve&lt;br /&gt;
	btfsc	STATUS,Z		;if Z flag is set that means that serve was at 1 and needs to be reset to 2&lt;br /&gt;
	call	UndoServe_new&lt;br /&gt;
	bcf		u1,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoP2_new&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f&lt;br /&gt;
	banksel p1score&lt;br /&gt;
	decf	p2score,f		;--p1score&lt;br /&gt;
	decf	serve,f			;--serve&lt;br /&gt;
	btfsc	STATUS,Z		;if Z flag is set that means that serve was at 1 and needs to be reset to 2&lt;br /&gt;
	call	UndoServe_new&lt;br /&gt;
	bcf		u2,0			;clear the p1 undo register to prevent a loop&lt;br /&gt;
	bcf		SL1&lt;br /&gt;
	bcf		SL2&lt;br /&gt;
	return&lt;br /&gt;
UndoServe_new&lt;br /&gt;
	movlw	0x02&lt;br /&gt;
	movwf	serve&lt;br /&gt;
	comf	p1s,f&lt;br /&gt;
	comf	p2s,f&lt;br /&gt;
	return&lt;br /&gt;
SwitchServe_new&lt;br /&gt;
	comf	p1s,f			;compliment p1s&lt;br /&gt;
	comf	p2s,f			;compliment p2s&lt;br /&gt;
	bcf		SL1			;turn OFF p1 server leds&lt;br /&gt;
	bcf		SL2			;turn OFF p2 server leds&lt;br /&gt;
	movlw	0x01			;reset the serve register &lt;br /&gt;
	banksel	serve&lt;br /&gt;
	movwf	serve	&lt;br /&gt;
	movlw	b&amp;#039;11001000&amp;#039;&lt;br /&gt;
	banksel PORTB&lt;br /&gt;
	andwf	PORTB,f	&lt;br /&gt;
	return	&lt;br /&gt;
	&lt;br /&gt;
;----------------------------------------------------------------&lt;br /&gt;
;end of the good stuff. everything else is routines&lt;br /&gt;
&lt;br /&gt;
binary_to_bcd&lt;br /&gt;
	CLRF	hundreds &lt;br /&gt;
	SWAPF	bin,w 			;w  = A0*16+A1&lt;br /&gt;
	ADDWF	bin,w 			;w  = A0+A1&lt;br /&gt;
	ANDLW	b&amp;#039;00001111&amp;#039; 	;w  = A0+A1 % 16&lt;br /&gt;
	SKPNDC 					;if A0+A1 &amp;gt; 16&lt;br /&gt;
	ADDLW	0x16 			;w  += 16&lt;br /&gt;
	SKPNDC 					;if w % 16 &amp;gt; 10&lt;br /&gt;
	ADDLW	0x06 			;w  += 6&lt;br /&gt;
	ADDLW 	0x06 			;w  += 6&lt;br /&gt;
	SKPDC 					;if w &amp;lt; 10&lt;br /&gt;
	ADDLW	-0x06 			;w  -= 6&lt;br /&gt;
&lt;br /&gt;
	BTFSC	bin,4 &lt;br /&gt;
	ADDLW	0x16 - 1 + 0x6 &lt;br /&gt;
	SKPDC &lt;br /&gt;
	ADDLW	-0x06 &lt;br /&gt;
&lt;br /&gt;
	BTFSC	bin,5 &lt;br /&gt;
	ADDLW	0x30 &lt;br /&gt;
	&lt;br /&gt;
	BTFSC	bin,6 &lt;br /&gt;
	ADDLW	0x60 &lt;br /&gt;
&lt;br /&gt;
	BTFSC	bin,7 &lt;br /&gt;
	ADDLW	0x20 &lt;br /&gt;
&lt;br /&gt;
	ADDLW	0x60 &lt;br /&gt;
	RLF		hundreds,f &lt;br /&gt;
	BTFSS	hundreds, 0 &lt;br /&gt;
	ADDLW 	-0x60 &lt;br /&gt;
&lt;br /&gt;
	MOVWF	tens_and_ones &lt;br /&gt;
	BTFSC	bin,7 &lt;br /&gt;
	INCF	hundreds,f &lt;br /&gt;
	&lt;br /&gt;
	return&lt;br /&gt;
Half_Second_Delay&lt;br /&gt;
			;2499992 cycles&lt;br /&gt;
	movlw	0x15&lt;br /&gt;
	movwf	d1&lt;br /&gt;
	movlw	0x74&lt;br /&gt;
	movwf	d2&lt;br /&gt;
	movlw	0x06&lt;br /&gt;
	movwf	d3&lt;br /&gt;
Half_Second_Delay_0&lt;br /&gt;
	decfsz	d1, f&lt;br /&gt;
	goto	$+2&lt;br /&gt;
	decfsz	d2, f&lt;br /&gt;
	goto	$+2&lt;br /&gt;
	decfsz	d3, f&lt;br /&gt;
	goto	Half_Second_Delay_0&lt;br /&gt;
&lt;br /&gt;
			;4 cycles&lt;br /&gt;
	goto	$+1&lt;br /&gt;
	goto	$+1&lt;br /&gt;
&lt;br /&gt;
			;4 cycles (including call)&lt;br /&gt;
	return	&lt;br /&gt;
Twenty_mS_Delay&lt;br /&gt;
			;99993 cycles&lt;br /&gt;
	movlw	0x1E&lt;br /&gt;
	movwf	d1&lt;br /&gt;
	movlw	0x4F&lt;br /&gt;
	movwf	d2&lt;br /&gt;
Twenty_mS_Delay_0&lt;br /&gt;
	decfsz	d1, f&lt;br /&gt;
	goto	$+2&lt;br /&gt;
	decfsz	d2, f&lt;br /&gt;
	goto	Twenty_mS_Delay_0&lt;br /&gt;
&lt;br /&gt;
			;3 cycles&lt;br /&gt;
	goto	$+1&lt;br /&gt;
	nop&lt;br /&gt;
&lt;br /&gt;
			;4 cycles (including call)&lt;br /&gt;
	return&lt;br /&gt;
&lt;br /&gt;
Two_mS_Delay&lt;br /&gt;
			;9993 cycles&lt;br /&gt;
	movlw	0xCE&lt;br /&gt;
	movwf	d1&lt;br /&gt;
	movlw	0x08&lt;br /&gt;
	movwf	d2&lt;br /&gt;
Two_mS_Delay_0&lt;br /&gt;
	decfsz	d1, f&lt;br /&gt;
	goto	$+2&lt;br /&gt;
	decfsz	d2, f&lt;br /&gt;
	goto	Two_mS_Delay_0&lt;br /&gt;
&lt;br /&gt;
			;3 cycles&lt;br /&gt;
	goto	$+1&lt;br /&gt;
	nop&lt;br /&gt;
&lt;br /&gt;
			;4 cycles (including call)&lt;br /&gt;
	return&lt;br /&gt;
&lt;br /&gt;
LookupServe:&lt;br /&gt;
	addwf	PCL,f				;add the offset in W to the PC&lt;br /&gt;
	retlw	b&amp;#039;00000000&amp;#039;		;0&lt;br /&gt;
	retlw	b&amp;#039;00000001&amp;#039;		;1&lt;br /&gt;
	retlw	b&amp;#039;00000011&amp;#039;		;2&lt;br /&gt;
	retlw	b&amp;#039;00000111&amp;#039;		;3&lt;br /&gt;
	retlw	b&amp;#039;00010111&amp;#039;		;4&lt;br /&gt;
	retlw	b&amp;#039;00110111&amp;#039;		;5&lt;br /&gt;
&lt;br /&gt;
	END                       ; directive &amp;#039;end of program&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pictures ==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Image:Ping pong 013 -800x600-.JPG|The prototype Ping Pong Scoreboard&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Paul</name></author>
	</entry>
</feed>