
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;										;
;	Car Race version 1.0				;
;	by brad slattery 2008				;
;										;
;	A car game for the 8x8 game system	;
;										;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


	LIST p=16f648a 				;	tell assembler what chip we are using
	include "P16f648a.inc"		;	include the defaults for the chip
	__config 0x3f18				;	sets the configuration settings (oscillator type etc.)

PC equ 0x02					;	The program counter will be refered to as PC

	cblock 0x20				;	start of general purpose registers - this is where we start defining variable names
		counta				;	used in the delay routines
		countb 				;	used in the delay routines
		pc_data				;	used in the display data program counter
		vram_1				;	a video ram location
		vram_2				;	a video ram location
		vram_3				;	a video ram location
		vram_4				;	a video ram location
		vram_5				;	a video ram location
		vram_6				;	a video ram location
		vram_7				;	a video ram location
		vram_8				;	a video ram location
		vtemp_1				;	a temporary video ram location (used when tranfering vram data to the next vram location)
		vtemp_2				;	a temporary video ram location (used when tranfering vram data to the next vram location)
		vtemp_3				;	a temporary video ram location (used when tranfering vram data to the next vram location)
		vtemp_4				;	a temporary video ram location (used when tranfering vram data to the next vram location)
		vtemp_5				;	a temporary video ram location (used when tranfering vram data to the next vram location)
		vtemp_6				;	a temporary video ram location (used when tranfering vram data to the next vram location)
		vtemp_7				;	a temporary video ram location (used when tranfering vram data to the next vram location)
		repeat_frame		;	used to determine how many times we will be repeating each 'frame'
		car_data			;	we need to know where the car is on the screen, this variable holds that data
		button_timer		;	used to help in slowing down the button repeat rate (it prevents the car from moving many times for one button press)
		button_adjust		;	used to help in slowing down the button repeat rate (it prevents the car from moving many times for one button press)
		stop_repeat			;	used to help in slowing down the button repeat rate (it prevents the car from moving many times for one button press)
		level				;	a variable to hold the level data (so we know what level we are on)
		speed				;	we set the initial speed in the setup routine (this determines how fast the car is going)
		collide_flag		;	if we have collided, this will set a flag so we know we have collided.
		pause_timer			;	the pause timer, pauses the screen (for a set amount of time) when we have collided
	endc

	org 0x0000					; org sets the origin, 0x0000 for the 16F628,


	movlw h'07'						
	movwf CMCON 				; turn comparators off (make it like a 16F84)

		bsf STATUS, RP0 			; select bank 1
		movlw b'00000000' 			; set PORTB all outputs
		movwf TRISB					;
		movlw b'00100000' 			; set PORTA all outputs except for bit 5
		movwf TRISA 				;
		bcf STATUS, RP0 			; select bank 0

	goto setup

track_data					;	Here's our track data!
	incf pc_data, 1			;	increment pc_data by one and then
	movf pc_data, w			;	move it into our working register THEN
	addwf PC				;	add this number to our program counter
	nop						;	skip one step...
	retlw b'10000001'		;	now each time this routine is called, we will grab the
	retlw b'10000001'		;	next successive byte of data!
	retlw b'11000001'
	retlw b'11000001'
	retlw b'11100001'
	retlw b'11100001'
	retlw b'11110001'
	retlw b'11110001'
	retlw b'11111001'
	retlw b'11110001'
	retlw b'11100001'
	retlw b'11000011'
	retlw b'10000111'
	retlw b'10001111'
	retlw b'10000111'
	retlw b'10000011'
	retlw b'10110001'
	retlw b'10111001'
	retlw b'10111001'
	retlw b'10111001'
	retlw b'10010001'
	retlw b'10000001'
	retlw b'10000001'
	retlw b'11000011'
	retlw b'11100111'
	retlw b'11000011'
	retlw b'10000001'
	retlw b'10011001'
	retlw b'10011001'
	retlw b'10111101'
	retlw b'10111101'
	retlw b'10011001'
	retlw b'10011001'
	retlw b'10000001'
	retlw b'11000011'
	retlw b'11100111'
	retlw b'11000011'
	retlw b'10000001'
	retlw b'10000001'
	retlw b'10010001'
	retlw b'10110001'
	retlw b'10111001'
	retlw b'10111001'
	retlw b'10011001'
	retlw b'10000001'
	retlw b'10000011'
	retlw b'10000111'
	retlw b'10001111'
	retlw b'10000111'
	retlw b'11000001'
	retlw b'11100001'
	retlw b'11110001'
	retlw b'11111001'
	retlw b'11111101'
	retlw b'11111001'
	retlw b'11110001'
	retlw b'10000001'
	retlw b'10000001'
	retlw b'10110001'
	retlw b'10110001'
	retlw b'10110001'
	rlf level, 1		;	now increment the level by one
	btfsc level, 7		;	have we reached the end of the game yet?
	call end_game		;	if yes, then call end_game routine
	decf speed, 1		;	if not, then decrement our speed variable by one (this speeds up the game)
	movlw h'01'			;	and now reset our pc_data variable so that we can
	movwf pc_data		;	draw the track again from the start
	return				;	return to our main program


setup						;	Okay, lets get everything setup, ready to play the game!
	movlw b'11011010'		;	This basically disables all 74373 outputs, and closes
	movwf PORTA				;	all 74373 latches.
	clrf vram_1				;	these next lines clear our video ram.
	clrf vram_2				;	if we didnt clear them, then we would get random
	clrf vram_3				;	dots on our screen and would more than likely crash
	clrf vram_4				;	as soon as we started playing! (experiment with not
	clrf vram_5				;	clearing all these vrams and see what happens!)
	clrf vram_6				;	....
	clrf vram_7				;	....
	clrf vram_8				;	....
	clrf stop_repeat		;	clear all 8 bits in stop repeat (even though we only use two.)
	clrf pc_data			;	clear pc_data (so we start from the top)
	clrf collide_flag		;	clear the collide_flag variable
	movlw b'00010000'		;	set the start position of our car
	movwf car_data			;	(almost in the middle of the screen)
	movlw d'08'				;	set our button repsonse delay (the higher the number,
	movwf button_adjust		;	the longer you have to wait to be able to push the button again)
	movlw d'01'				;	setup our level counter (start from level
	movwf level				;	one of course...)
	movlw d'10'				;	setup our game scrolling speed.
	movwf speed				;	(the higher the number, the slower the scroll speed)
	movlw d'200'			;	setup our crash pause timer
	movwf pause_timer		;	the higher the number, the longer the pause...


begin							;	Our main program!
	call display				;	call the display routine
	btfss collide_flag, 0		;	check the collide_flag bit 0, if it is set, we wont update the vram (pauses the screen)
	call fill_vram				;	call the fill video ram routine
	goto begin					;	do it all again!


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;																	;
;	This next routine basically takes care of drawing the actual	;
;	graphics on the screen. You will notice that there are eight 	;
;	"sections" here and they basically look the same except for		;
;	minor differences. Thats because they are all doing the same	;
;	thing - activating a certain row of cathodes and then grabbing	;
;	the anode data in order to turn the leds on. The only			;
;	difference between them is that each section activates a		;
;	different row of cathodes and also grabs it's data to be		;
;	displayed from a different vram location.						;
;																	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


display	
				movf speed, w					;	We need to set the speed that our game is running at,
				movwf repeat_frame				;	so we grab that data from speed and copy it to our frame_rate
loop		btfss collide_flag, 0				;	checks to see if we have collided (it wont draw the car if we have hit a wall)
				call car						;	Call the car routine (this will draw our car on the screen)
				call show_level					;	Call the show_level routine (this will show what level you are on)
				movf vram_1, w					;	Now we grab the first COLUMN of data from vram_1.
				movwf PORTB						;	then we copy it to PORTB
				bsf PORTA, 4					;	now that its in PORTB we need to latch it to the COLUMN memory.
				bcf PORTA, 4					;	so the latch was opened, now we need to close it (the data will now stay there)
					movlw b'10000000'			;	This now activates the top row of cathodes by moving
					movwf PORTB					;	'10000000' to PORTB, 	
					bsf PORTA, 2				;	then latching it onto the green data latch
					bcf PORTA, 2				;	then closing the latch (the data is now held there)
				bcf PORTA, 6					;	Now that all our data is ready, we can enable our 74373 outputs.
				bcf PORTA, 3					;	PORTA, 6 is the COLUMN data enable - PORTA, 3 is the green data enable
				call delay						;	Call the delay (to hold that one row ON for a split second)
				bsf PORTA, 6					;	Now disable both outputs (remember PORTA, 6 is the COLUMN data
				bsf PORTA, 3					;	and PORTA, 3 is the green data)
										

				movf vram_2, w					;	Now we grab the second COLUMN of data from vram_2.
				movwf PORTB						;	then we copy it to PORTB
				bsf PORTA, 4					;	now that its in PORTB we need to latch it to the COLUMN memory.
				bcf PORTA, 4					;	so the latch was opened, now we need to close it (the data will now stay there)
					movlw b'01000000'			;	This now activates the top row of cathodes by moving
					movwf PORTB					;	'01000000' to PORTB, 	
					bsf PORTA, 2				;	then latching it onto the green data latch
					bcf PORTA, 2				;	then closing the latch (the data is now held there)
				bcf PORTA, 6					;	Now that all our data is ready, we can enable our 74373 outputs.
				bcf PORTA, 3					;	PORTA, 6 is the COLUMN data enable - PORTA, 3 is the green data enable
				call delay						;	Call the delay (to hold that one row ON for a split second)
				bsf PORTA, 6					;	Now disable both outputs (remember PORTA, 6 is the COLUMN data
				bsf PORTA, 3					;	and PORTA, 3 is the green data)

				movf vram_3, w					;	Now we grab the third COLUMN of data from vram_3.
				movwf PORTB						;	then we copy it to PORTB
				bsf PORTA, 4					;	now that its in PORTB we need to latch it to the COLUMN memory.
				bcf PORTA, 4					;	so the latch was opened, now we need to close it (the data will now stay there)
					movlw b'00100000'			;	This now activates the top row of cathodes by moving
					movwf PORTB					;	'00100000' to PORTB, 	
					bsf PORTA, 2				;	then latching it onto the green data latch
					bcf PORTA, 2				;	then closing the latch (the data is now held there)
				bcf PORTA, 6					;	Now that all our data is ready, we can enable our 74373 outputs.
				bcf PORTA, 3					;	PORTA, 6 is the COLUMN data enable - PORTA, 3 is the green data enable
				call delay						;	Call the delay (to hold that one row ON for a split second)
				bsf PORTA, 6					;	Now disable both outputs (remember PORTA, 6 is the COLUMN data
				bsf PORTA, 3					;	and PORTA, 3 is the green data)

				movf vram_4, w					;	Now we grab the fourth COLUMN of data from vram_4.
				movwf PORTB						;	then we copy it to PORTB
				bsf PORTA, 4					;	now that its in PORTB we need to latch it to the COLUMN memory.
				bcf PORTA, 4					;	so the latch was opened, now we need to close it (the data will now stay there)
					movlw b'00010000'			;	This now activates the top row of cathodes by moving
					movwf PORTB					;	'00010000' to PORTB, 	
					bsf PORTA, 2				;	then latching it onto the green data latch
					bcf PORTA, 2				;	then closing the latch (the data is now held there)
				bcf PORTA, 6					;	Now that all our data is ready, we can enable our 74373 outputs.
				bcf PORTA, 3					;	PORTA, 6 is the COLUMN data enable - PORTA, 3 is the green data enable
				call delay						;	Call the delay (to hold that one row ON for a split second)
				bsf PORTA, 6					;	Now disable both outputs (remember PORTA, 6 is the COLUMN data
				bsf PORTA, 3					;	and PORTA, 3 is the green data)
	
				movf vram_5, w					;	Now we grab the fifth COLUMN of data from vram_5.
				movwf PORTB						;	then we copy it to PORTB
				bsf PORTA, 4					;	now that its in PORTB we need to latch it to the COLUMN memory.
				bcf PORTA, 4					;	so the latch was opened, now we need to close it (the data will now stay there)
				movlw b'00001000'				;	This now activates the top row of cathodes by moving
				movwf PORTB						;	'00001000' to PORTB, 	
				bsf PORTA, 2					;	then latching it onto the green data latch
				bcf PORTA, 2					;	then closing the latch (the data is now held there)
				bcf PORTA, 6					;	Now that all our data is ready, we can enable our 74373 outputs.
				bcf PORTA, 3					;	PORTA, 6 is the COLUMN data enable - PORTA, 3 is the green data enable
				call delay						;	Call the delay (to hold that one row ON for a split second)
				bsf PORTA, 6					;	Now disable both outputs (remember PORTA, 6 is the COLUMN data
				bsf PORTA, 3					;	and PORTA, 3 is the green data)
	
				movf vram_6, w					;	Now we grab the sixth COLUMN of data from vram_6.
				movwf PORTB						;	then we copy it to PORTB
				bsf PORTA, 4					;	now that its in PORTB we need to latch it to the COLUMN memory.
				bcf PORTA, 4					;	so the latch was opened, now we need to close it (the data will now stay there)
					movlw b'00000100'			;	This now activates the top row of cathodes by moving
					movwf PORTB					;	'00000100' to PORTB, 	
					bsf PORTA, 2				;	then latching it onto the green data latch
					bcf PORTA, 2				;	then closing the latch (the data is now held there)
				bcf PORTA, 6					;	Now that all our data is ready, we can enable our 74373 outputs.
				bcf PORTA, 3					;	PORTA, 6 is the COLUMN data enable - PORTA, 3 is the green data enable
				call delay						;	Call the delay (to hold that one row ON for a split second)
				bsf PORTA, 6					;	Now disable both outputs (remember PORTA, 6 is the COLUMN data
				bsf PORTA, 3					;	and PORTA, 3 is the green data)

				movf vram_7, w					;	Now we grab the seventh COLUMN of data from vram_7.
				movwf PORTB						;	then we copy it to PORTB
				bsf PORTA, 4					;	now that its in PORTB we need to latch it to the COLUMN memory.
				bcf PORTA, 4					;	so the latch was opened, now we need to close it (the data will now stay there)
					movlw b'00000010'			;	This now activates the top row of cathodes by moving
					movwf PORTB					;	'00000010' to PORTB, 	
					bsf PORTA, 2				;	then latching it onto the green data latch
					bcf PORTA, 2				;	then closing the latch (the data is now held there)
				bcf PORTA, 6					;	Now that all our data is ready, we can enable our 74373 outputs.
				bcf PORTA, 3					;	PORTA, 6 is the COLUMN data enable - PORTA, 3 is the green data enable
				call delay						;	Call the delay (to hold that one row ON for a split second)
				bsf PORTA, 6					;	Now disable both outputs (remember PORTA, 6 is the COLUMN data
				bsf PORTA, 3					;	and PORTA, 3 is the green data)

				movf vram_8, w					;	Now we grab the eigth COLUMN of data from vram_8.
				movwf PORTB						;	then we copy it to PORTB
				bsf PORTA, 4					;	now that its in PORTB we need to latch it to the COLUMN memory.
				bcf PORTA, 4					;	so the latch was opened, now we need to close it (the data will now stay there)
					movlw b'00000001'			;	This now activates the top row of cathodes by moving
					movwf PORTB					;	'00000001' to PORTB, 	
					bsf PORTA, 2				;	then latching it onto the green data latch
					bcf PORTA, 2				;	then closing the latch (the data is now held there)
				bcf PORTA, 6					;	Now that all our data is ready, we can enable our 74373 outputs.
				bcf PORTA, 3					;	PORTA, 6 is the COLUMN data enable - PORTA, 3 is the green data enable
				call delay						;	Call the delay (to hold that one row ON for a split second)
				bsf PORTA, 6					;	Now disable both outputs (remember PORTA, 6 is the COLUMN data
				bsf PORTA, 3					;	and PORTA, 3 is the green data)
					btfsc stop_repeat, 1		;	Check to see if the stop repeat bit 1 has been set,
					call button_time			;	if it has, then call the button_time routine (which will decrement the timer by one)
					call check_collision		;	if it has not been set, then keep going here and call the check_collision routine
	decfsz repeat_frame							;	then decrease repeat_frame by one, 
		goto loop								;	if its not zero then draw it all again!
	return										;	if it is zero, then go back to where we came from...


show_level					;	This next routine shows us a running commentary of what level we are on.
	movf level, w			;	copy our level data into the w register.
	movwf PORTB				;	then copy this data to PORTB.
	bsf PORTA, 0			;	open up the red 74373 latch
	bcf PORTA, 0			;	now close the latch (our 8 bits of data will now be held on our output.)
	bsf PORTA, 2			;	open up the green 74373 latch	
	bcf PORTA, 2			;	now close the latch (our 8 bits of data will now be held on our output.)
	movlw b'10000000'		;	this 8 bits of data basically activates the very right hand column
	movwf PORTB				;	of our screen (which means our level dot will be displayed here)
	bsf PORTA, 4			;	open up the COLUMN 74373 latch
	bcf PORTA, 4			;	now close the latch (our 8 bits of data will now be held on our output.)
	bcf PORTA, 1			;	Now that all screen memory latches have their info, we can then enable
	bcf PORTA, 3			;	all outputs, which means our screen will actually display something!
	bcf PORTA, 6			;	1=red output, 3=green output and 6=COLUMN output
	call delay				;	now call the delay, which will hold that data on screen for a split second.
	bsf PORTA, 1			;	alright, now the screen has displayed what we want,
	bsf PORTA, 3			;	we then disable all outputs.
	bsf PORTA, 6			;	and,
	return					;	then return to our main program...



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;																	;
;	The key point to remember in this check_collision routine,		;
;	is that if we check the Z bit in STATUS, then we are			;
;	checking to see if our answer is ZERO or not. If the answer		;
;	IS zero, then the status bit Z will be set (it will be a 1)		;
;	this tells us 'YES THE ANSWER IS ZERO'. If the Z bit is a '0'	;
;	then it is telling us 'NO, THE ANSWER IS NOT ZERO'				;
;																	;
;	So, in this next bit, we are anding two 8-bit numbers. In this	;
;	case, the answer can either be '0' or a number above zero.		;
;	we don't care exactly what number it comes to, we just want to	;
;	know if the answer is zero or not. (A zero means we have not	;
;	hit anything, while anything above zero means we have hit a		;
;	wall.															;
;																	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


check_collision				;	Here we are going to check if we have hit a wall or not...
	movf car_data, w		;	Copy our car data into the w register,
	andwf vram_8, w			;	then and our car_data with vram_8
	btfss STATUS, Z			;	If the answer is NOT zero (status bit is NOT set) then -	
	goto collided			;	goto collided routine
	return					;	otherwise, just return from where we came from...


collided						;	The only time we come here is if weve hit a wall!
	bsf collide_flag, 0			;	set bit 0 of the collide_flag variable (make it a '1')
	decfsz pause_timer, 1		;	decrement the pause timer by 1, 
	return						;	if it is not yet zero, then go back to where we came from
	goto setup					;	if it is zero, then reset the game (back to setup)


car							;	This routine draws the car on the screen
	call joystick			;	First of all, call the joystick to see if we're moving.
	movf car_data, w		;	Copy the contents of car_data to the w register,
	movwf PORTB				;	then copy this data from w to PORTB.
	bsf PORTA, 4			;	open the COLUMN data latch to allow the 8 bits to go through
	bcf PORTA, 4			;	now close the latch and this will hold the 8 bits on the 74373 output.
	movlw b'00000001'		;	now copy these 8 bits to the w register
	movwf PORTB				;	and then from the w register to PORTB
	bsf PORTA, 0			;	Now open the 74373 latches connected to the red LEDs
	bcf PORTA, 0			;	then close the latches and now we hold onto that data.
	bcf PORTA, 1			;	enable the red LEDs 74373 output and also
	bcf PORTA, 6			;	enable the COLUMN 74373 output (this will output all that data to the screen)
	call delay				;	call the delay - this will hold that info on the screen for a split second,
	bsf PORTA, 1			;	then when the delay is finished, disable both 74373 outputs
	bsf PORTA, 6			;	which will turn off those leds.
	return					;	now were finished, return to the main program


joystick
	call port_b_input		;	First we need to make PORTB an input before we can check anything.
	bcf PORTA, 7			;	Now we need to enable the 74373 connected to all the buttons
	btfss PORTB, 2			;	Check the left button. if it is a 0 (which means it's pressed)
	call go_left			;	then call the go_left routine, if its a 1 then jump to the next line.
	btfss PORTB, 3			;	Check the right button. if it is a 0 (which means it's pressed)
	call go_right			;	then call the go_right routine, if its a 1 then jump to the next line.
	btfss PORTB, 5			;	Check the 'B' button, if it is a 0 (which means it's pressed)
	call go_right			;	then call the go_right routine, if its a 1 then jump to the next line.
	btfss PORTB, 6			;	Check the 'Reset' button, if it is a 0 (which means it's pressed)
	goto setup				;	Then goto setup (reset the game) if its a 1, then jump to the next line.
	bsf PORTA, 7			;	disable the 74373 connected to the buttons.
	call port_b_output		;	make PORTB an output again
	return					;	and finally, return back to the main program!


port_b_input					;	This routine makes all of PORTB into inputs
   		bsf 	STATUS,	RP0		;	which allows us to then read from the
		movlw	b'11111111'		;	Joystick.
		movwf	TRISB			;
		bcf		STATUS,	RP0		;
	return						;	Now return to where we can from...

port_b_output					;	This routine makes all of PORTB outputs again
  	 	bsf 	STATUS,	RP0		;	If we didnt make PORTB an output again, then
		movlw	b'00000000'		;	we could never display any data on our screen!
		movwf	TRISB			;
		bcf		STATUS,	RP0		;
	return						;	Now return to where we can from...


go_left
	btfsc stop_repeat, 0		;	First we check if the stop_repeat bit is set
	return						;	if it is set then we return to the main program
	rrf car_data, 1				;	If it is not set then the car will move across one space.
	bsf stop_repeat, 1			;	Now that we have moved one space we want to prevent our
	bsf stop_repeat, 0			;	car from moving another space straight away. so we set
	movf button_adjust, w		;	the stop_repeat bits which will remain set untill the
	movwf button_timer			;	specified time period is complete. Without this, the car
	return						;	would move way to fast for us to be able to play the game

go_right
	btfsc stop_repeat, 0		;	First we check if the stop_repeat bit is set
	return						;	if it is set then we return to the main program
	rlf car_data, 1				;	If it is not set then the car will move across one space.
	bsf stop_repeat, 1			;	Now that we have moved one space we want to prevent our
	bsf stop_repeat, 0			;	car from moving another space straight away. so we set
	movf button_adjust, w		;	the stop_repeat bits which will remain set untill the
	movwf button_timer			;	specified time period is complete. Without this, the car
	return						;	would move way to fast for us to be able to play the game

button_time						;	This routine decrements the button_timer by one
	decfsz button_timer, 1		;	(we can change the value of button_timer in the setup routine)
	return						;	If the timer has not yet reached zero, then it returns to the main program
	bcf stop_repeat ,0			;	If the timer has reached zero, then we clear the stop_repeat bits
	bcf stop_repeat, 1			;	this then allows us to press a button again!
	return						;	Now return to where we can from...


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;																	;
;	This next routine displays #1 to let you know that you have		;
;	completed the game.												;
;																	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


end_game

	goto setup


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;																	;
;	This next section basically 'fills' the	video ram locations		;
;	with the data from the previous video ram location - This is	;
;	how we get the screen to scroll. It also grabs a new byte of	;
;	data from the track data table to display in video ram 1.		;							
;																	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fill_vram
		movf vram_1, 0		;	Copy vram_1 into vtemp_1 to use as a backup
		movwf vtemp_1		;	storage location. (just before we overwrite vram_1)
		movf vram_2, 0		;	Copy vram_1 into vtemp_2 to use as a backup
		movwf vtemp_2		;	storage location. (just before we overwrite vram_2)
		movf vram_3, 0		;	Copy vram_1 into vtemp_3 to use as a backup
		movwf vtemp_3		;	storage location. (just before we overwrite vram_3)
		movf vram_4, 0		;	Copy vram_1 into vtemp_4 to use as a backup
		movwf vtemp_4		;	storage location. (just before we overwrite vram_4)
		movf vram_5, 0		;	Copy vram_1 into vtemp_5 to use as a backup
		movwf vtemp_5		;	storage location. (just before we overwrite vram_5)
		movf vram_6, 0		;	Copy vram_1 into vtemp_6 to use as a backup
		movwf vtemp_6		;	storage location. (just before we overwrite vram_6)
		movf vram_7, 0		;	Copy vram_7 into vtemp_7 to use as a backup
		movwf vtemp_7		;	storage location. (just before we overwrite vram_7)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;																	;
;	Did you notice that we don't need to make a backup of vram_8?	;
;	That's because there are only 8 lines on the screen. So after 	;
;	we display the 8th line, it is then shifted out of the screen.	;
;																	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;																	;
;	Now that we have backed up our old vram data, we then need to	;
;	copy them to the next successive vram location - this basically	;
;	shifts everything on the screen down one space. It also grabs	;
;	a brand new byte of data and copies it into vram_1 (which		;
;	means it will be displayed at the top of the screen, before		;
;	It gets shifted again...										;
;																	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

		call track_data		;	Call track_data routine and return with a byte of data in the w register
		movwf vram_1		;	then copy the new byte of data to the first vram location
		movf vtemp_1, 0		;	copy what was in vram_1 into vram_2 (remember how we made
		movwf vram_2		;	a backup of vram_1 and called it vtemp_1.)
		movf vtemp_2, 0		;	copy what was in vram_2 into vram_3 (remember how we made
		movwf vram_3		;	a backup of vram_2 and called it vtemp_2.)
		movf vtemp_3, 0		;	copy what was in vram_3 into vram_4 (remember how we made
		movwf vram_4		;	a backup of vram_3 and called it vtemp_3.)
		movf vtemp_4, 0		;	copy what was in vram_4 into vram_5 (remember how we made
		movwf vram_5		;	a backup of vram_4 and called it vtemp_4.)
		movf vtemp_5, 0		;	copy what was in vram_5 into vram_6 (remember how we made
		movwf vram_6		;	a backup of vram_5 and called it vtemp_5.)
		movf vtemp_6, 0		;	copy what was in vram_6 into vram_7 (remember how we made
		movwf vram_7		;	a backup of vram_6 and called it vtemp_6.)
		movf vtemp_7, 0		;	copy what was in vram_7 into vram_8 (remember how we made
		movwf vram_8		;	a backup of vram_7 and called it vtemp_7.)
	return					;	Now that we're all done here, go back to our main program.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;																	;
;	Heres the delay routines!										;
;																	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

delay									;	This first delay is a rather fast one.
			movlw d'03'					;	You can make the delay longer by
			movwf counta				;	increasing the decimal value. Or you
			movwf countb				;	can make the delay shorter by decreasing
again	decfsz counta, 1				;	the decimal value.
			goto again					;
			decfsz countb, 1			;
			goto again					;	once counta and countb have reached zero
	return								;	it will return to the main program


	end									;	That's it!
