


	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 h'02'					;	The program counter will be refered to as PC

	cblock h'20'				;	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
		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)
		ship_data
		pc_data				;	used in the display data program counter
		repeat_frame		;	used to determine how many times we will be repeating each 'frame'
		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)
		speed
		laser_x
		laser_y
		shot_fired
		laser_timer
		laser_distance
		top_alien_data
		middle_alien_data
		bottom_alien_data
		temp_ram
		move_timer
		direction
		move_down_timer
		top_alien_line
		middle_alien_line
		bottom_alien_line
		line_map
		lost_life
		level_up
		anim_repeat
		current_level
		shield
		end_timer
		UFO
		do_UFO
		UFO_speed
	endc

	org h'0000'					; 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

advance_level_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'00100100'
	retlw b'00000010'
	retlw b'01001000'
	retlw b'00000000'
	retlw b'00100000'
	retlw b'01000000'
	retlw b'00000010'
	retlw b'00001000'
	retlw b'01000010'
	retlw b'00000001'
	retlw b'01000000'
	retlw b'00000000'
	retlw b'01000100'
	retlw b'10000000'
	retlw b'00100001'
	movlw d'01'			;	and now reset our pc_data variable so that we can
	movwf pc_data		;	draw the track again from the start
	retlw b'00100100'






setup						;	Okay, lets get everything setup, ready to play the game!
	clrf shot_fired
	clrf laser_x
	movlw d'07'
	movwf laser_distance
	movlw b'00000010'
	movwf laser_y
	movlw b'11011010'		;	This basically disables all 74373 outputs, and closes
	movwf PORTA				;	all 74373 latches.
	clrf stop_repeat		;	clear all 8 bits in stop repeat (even though we only use two.)
	movlw b'00010000'		;	set the start position of our car
	movwf ship_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'25'
	movwf laser_timer
	movlw d'30'
	movwf UFO_speed
	clrf do_UFO
	movlw b'10000000'
	movwf UFO
	movlw d'50'
	movwf end_timer
	clrf lost_life
	movlw b'00000001'
	movwf current_level
	movlw d'255'
	movwf move_down_timer
	movlw b'00010101'
	movwf direction
	movlw d'120'
	movwf move_timer
	movlw d'16'				;	set our button repsonse delay (the higher the number,
	movwf button_adjust

next_level
	movlw b'01011010'
	movwf shield
	clrf temp_ram
	movlw b'01111110'
	movwf top_alien_data
	movwf middle_alien_data
	movwf bottom_alien_data
	movlw b'00000001'
	movwf line_map
	movlw b'01000000'
	movwf top_alien_line
	movlw b'00100000'
	movwf middle_alien_line
	movlw b'00010000'
	movwf bottom_alien_line
	clrf level_up
	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				;	....







begin
	call ship				;	call the display routine
	call draw_UFO
	call shields
	call laser
	call draw_aliens
	call hit_aliens
continue
	call check_aliens
	btfss lost_life, 0
	call move_aliens
	call game_status
	btfsc level_up, 0
	call level_anim
	btfsc lost_life, 0
	goto hold_end
	goto begin
	goto next_level					;	do it all again!


hold_end
	call long_delay
	btfsc lost_life, 0
	decfsz end_timer, f
	goto begin
	goto setup

ship
	btfsc stop_repeat, 1
	call button_time
	call joystick			;	First of all, call the joystick to see if we're moving.
	movf ship_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


draw_UFO
	btfss do_UFO, 0
	return
	movlw b'10000000'
	movwf PORTB
	bsf PORTA, 0
	bcf PORTA, 0
	movf UFO, w
	movwf PORTB
	bsf PORTA, 4
	bcf PORTA, 4
	bcf PORTA, 1
	bcf PORTA, 6
	call delay
	bsf PORTA, 1
	bsf PORTA, 6
	decfsz UFO_speed, f
	return
	bcf STATUS, C
	rrf UFO, f
	movlw d'30'
	movwf UFO_speed
	btfss STATUS, C
	return
	bcf do_UFO, 0
	movlw b'10000000'
	movwf UFO
	return




shields
	movlw b'00000010'
	movwf PORTB
	bsf PORTA, 2
	bcf PORTA, 2
	movf shield, w
	movwf PORTB
	bsf PORTA, 4
	bcf PORTA, 4
	bcf PORTA, 3
	bcf PORTA, 6
	call delay
	bsf PORTA, 3
	bsf PORTA, 6
	return



laser
	btfss shot_fired, 0			;	check to see if a shot has been fired
	return						;	if not, then just return

	movf laser_x, w
	movwf PORTB
	bsf PORTA, 4
	bcf PORTA, 4
	movf laser_y, w
	movwf PORTB
	bsf PORTA, 2
	bcf PORTA, 2
	bcf PORTA, 3
	bcf PORTA, 6
	call delay
	bsf PORTA, 3
	bsf PORTA, 6

	decfsz laser_timer, f
	return
	bcf STATUS, C
	rlf laser_y, f
	movlw d'25'
	movwf laser_timer
	decfsz laser_distance, f
	return
reset_shot
	movlw b'00000010'
	movwf laser_y	
	movlw d'07'
	movwf laser_distance	
	bcf shot_fired, 0
	return


draw_aliens
	movf top_alien_line, w
	movwf PORTB
	bsf PORTA, 0
	bcf PORTA, 0
	movf top_alien_data, w
	movwf PORTB
	bsf PORTA, 4
	bcf PORTA, 4
	bcf PORTA, 1
	bcf PORTA, 6
	call delay
	bsf PORTA, 1
	bsf PORTA, 6


	movf middle_alien_line, w
	movwf PORTB
	bsf PORTA, 2
	bcf PORTA, 2
	movf middle_alien_data, w
	movwf PORTB
	bsf PORTA, 4
	bcf PORTA, 4
	bcf PORTA, 3
	bcf PORTA, 6
	call delay
	bsf PORTA, 3
	bsf PORTA, 6

	movf bottom_alien_line, w
	movwf PORTB
	bsf PORTA, 0
	bcf PORTA, 0
	bsf PORTA, 2
	bcf PORTA, 2
	movf bottom_alien_data, w
	movwf PORTB
	bsf PORTA, 4
	bcf PORTA, 4
	bcf PORTA, 1
	bcf PORTA, 3
	bcf PORTA, 6
	call delay
	bsf PORTA, 1
	bsf PORTA, 3
	bsf PORTA, 6
	return


alien_line_change
	decfsz move_down_timer, f
	return
	bsf do_UFO, 0
	bcf STATUS, C
	rlf line_map, f
	rrf top_alien_line, f
	rrf middle_alien_line, f
	rrf bottom_alien_line, f
	btfsc current_level, 0
	movlw d'255'
	btfsc current_level, 1
	movlw d'225'
	btfsc current_level, 2
	movlw d'200'
	btfsc current_level, 3
	movlw d'180'
	btfsc current_level, 4
	movlw d'155'
	btfsc current_level, 5
	movlw d'120'
	btfsc current_level, 6
	movlw d'100'
	btfsc current_level, 7
	movlw d'80'
	movwf move_down_timer
	return


hit_aliens	
	btfss laser_y, 7
	goto skip_UFO
	movf laser_x,w
	andwf UFO, w
	xorwf UFO, f	
skip_UFO
	movf laser_x, w
	andwf shield, w
	xorwf shield, f
	btfsc line_map, 0
	call map_0
	btfsc line_map, 1
	call map_1
	btfsc line_map, 2
	call map_2
	btfsc line_map, 3
	call map_3
	btfsc line_map, 4
	call map_4
	btfsc line_map, 5
	call map_5
	btfsc line_map, 6
	call map_6
	goto continue

map_0
	btfss shot_fired, 0
	return
	btfsc laser_y, 4
	call hit_bottom
	btfsc laser_y, 5
	call hit_middle
	btfsc laser_y, 6
	call hit_top
	goto continue

map_1
	btfss shot_fired, 0
	return
	btfsc laser_y, 3
	call hit_bottom
	btfsc laser_y, 4
	call hit_middle
	btfsc laser_y, 5
	call hit_top
	goto continue

map_2
	btfss shot_fired, 0
	return
	btfsc laser_y, 2
	call hit_bottom
	btfsc laser_y, 3
	call hit_middle
	btfsc laser_y, 4
	call hit_top
	goto continue

map_3
	btfss shot_fired, 0
	return
	btfsc laser_y, 1
	call hit_bottom
	btfsc laser_y, 2
	call hit_middle
	btfsc laser_y, 3
	call hit_top
	goto continue

map_4
	movf ship_data, w
	andwf bottom_alien_data, w
	btfss STATUS, Z
	bsf lost_life, 0
	btfss shot_fired, 0
	return
	btfsc laser_y, 0
	call hit_bottom
	btfsc laser_y, 1
	call hit_middle
	btfsc laser_y, 2
	call hit_top
	goto continue

map_5
	movf ship_data, w
	andwf middle_alien_data, w
	btfss STATUS, Z
	bsf lost_life, 0
	btfss shot_fired, 0
	return
	btfsc laser_y, 0
	call hit_middle
	btfsc laser_y, 1
	call hit_top
	goto continue

map_6
	movf ship_data, w
	andwf top_alien_data, w
	btfss STATUS, Z
	bsf lost_life, 0
	btfss shot_fired, 0
	return
	btfsc laser_y, 0
	call hit_top
	goto continue



hit_bottom
	movf laser_x, w
	andwf bottom_alien_data, w			; first we and the answer to see if anything will get removed or not.
	movwf temp_ram
	btfss STATUS, Z
	call reset_shot
	movf temp_ram, w
	xorwf bottom_alien_data, f
	goto continue

hit_middle
	movf laser_x, w
	andwf middle_alien_data, w			; first we and the answer to see if anything will get removed or not.
	movwf temp_ram
	btfss STATUS, Z
	call reset_shot
	movf temp_ram, w
	xorwf middle_alien_data, f	
	goto continue

hit_top
	movf laser_x, w
	andwf top_alien_data, w			; first we and the answer to see if anything will get removed or not.
	movwf temp_ram
	btfss STATUS, Z
	call reset_shot
	movf temp_ram, w
	xorwf top_alien_data, f	
	goto continue


check_aliens
	btfsc top_alien_data, 0
	call top_go_left
	btfsc top_alien_data, 7
	call top_go_right
	btfsc middle_alien_data, 0
	call middle_go_left
	btfsc middle_alien_data, 7
	call middle_go_right
	btfsc bottom_alien_data, 0
	call bottom_go_left
	btfsc bottom_alien_data, 7
	call bottom_go_right
	return

top_go_left
	call alien_line_change
	bcf direction, 1
	bsf direction, 0
	return

top_go_right
	bcf direction, 0
	bsf direction, 1
	return

middle_go_left
	bcf direction, 3
	bsf direction, 2
	return

middle_go_right
	bcf direction, 2
	bsf direction, 3
	return

bottom_go_left
	bcf direction, 5
	bsf direction, 4
	return

bottom_go_right
	bcf direction, 4
	bsf direction, 5
	return

move_aliens
	decfsz move_timer, f
	return
	bcf STATUS, C
	btfsc direction, 0
	rlf top_alien_data, f
	btfsc direction, 1
	rrf top_alien_data, f
	btfsc direction, 2
	rlf middle_alien_data, f
	btfsc direction, 3
	rrf middle_alien_data, f
	btfsc direction, 4
	rlf bottom_alien_data, f
	btfsc direction, 5
	rrf bottom_alien_data, f
	btfsc current_level, 0
	movlw d'120'
	btfsc current_level, 1
	movlw d'20'
	btfsc current_level, 2
	movlw d'100'
	btfsc current_level, 3
	movlw d'90'
	btfsc current_level, 4
	movlw d'80'
	btfsc current_level, 5
	movlw d'70'
	btfsc current_level, 6
	movlw d'60'
	btfsc current_level, 7
	movlw d'50'
	movwf move_timer
	return






game_status
	movf top_alien_data, w
	iorwf middle_alien_data, w
	iorwf bottom_alien_data, w
	btfss STATUS, Z
	return
	bsf level_up, 0
	rlf current_level, f
	return





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 shoot			;	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 ship_data, 0
	return
	btfsc stop_repeat, 0		;	First we check if the stop_repeat bit is set
	return
	bcf STATUS, C				; THIS ENSURES THAT YOU DON'T GET EXTRA SHIPS COMING IN!
	rrf ship_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 ship_data, 7
	return
	btfsc stop_repeat, 0		;	First we check if the stop_repeat bit is set
	return
	bcf STATUS, C				; THIS ENSURES THAT YOU DON'T GET EXTRA SHIPS COMING IN!
	rlf ship_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

shoot
	btfsc shot_fired, 0
	return
	call reset_shot
	bsf shot_fired, 0
	movf ship_data, w
	movwf laser_x
	return

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...


level_anim
				movlw d'100'
				movwf anim_repeat
next_frame	
				call fill_vram
				movlw d'04'
				movwf repeat_frame				;	so we grab that data from speed and copy it to our frame_rate
loop	
				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)
	decfsz repeat_frame, f							;	then decrease repeat_frame by one, 
		goto loop
	decfsz anim_repeat, f
		goto next_frame
	goto setup


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)

		call advance_level_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



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


long_delay									;	This first delay is a rather fast one.
			movlw d'100'					;	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_long	decfsz counta, 1				;	the decimal value.
			goto again_long					;
			decfsz countb, 1			;
			goto again_long					;	once counta and countb have reached zero
	return								;	it will return to the main program


	end									;	That's it!
