Jump to content

Fairchild Channel F Tech/Programming info


41 replies to this topic

#1  

    Moonsweeper

  • 339 posts
  • Joined: 11-November 03
  • Jaja.
  • Location:United States

Posted Thu Feb 26, 2004 7:08 PM

I have fallen to the evil known as "curiosity" and are interested in coding some demos for the fairchild. Does anyone have any information on the structure of the console, the processor's setup, possible Assemblers, etc.
I know it is unlikely, but I'm just curious....

#2  

    River Patroller

  • 2,362 posts
  • Joined: 24-April 01
  • Location:NYC, NY

Posted Thu Feb 26, 2004 8:23 PM

Here is some info on the F8:

http://www.antiquete...airchild_f8.htm

or you may be able to get something from here:

http://www.fairchildsemi.com/

Either way - good luck!

#3  

    Chopper Commander

  • 135 posts
  • Joined: 27-February 03

Posted Mon Mar 22, 2004 7:44 PM

Heh. I meddled in that too, out of curiosity. It was murder to find an assembler, or any info at all on the system... here's a page that I found:

http://www.nyx.net/~lturner/public_html/Fa...irchild_F8.html

And:

http://www.nyx.net/~...tml/F8_ins.html

Don't have a clue about the system itself. Try looking at some MESS source.

#4  

    River Patroller

  • 2,362 posts
  • Joined: 24-April 01
  • Location:NYC, NY

Posted Tue Apr 27, 2004 2:26 PM

Anyone have any success with this yet? :)

#5  

    Chopper Commander

  • 135 posts
  • Joined: 27-February 03

Posted Tue Apr 27, 2004 4:32 PM

I'd like to know as well... if anyone's interested, I can probably give you the assembler with the F8 data file, it's a DOS compiler called Cross-16. The data file can be adapted for Table Assembler (I think), which would probably help alot...

For some reason, every site I looked at said something different as to what the Fairchild's resolution is... the cart size is 2k, though.

#6  

    River Patroller

  • 2,362 posts
  • Joined: 24-April 01
  • Location:NYC, NY

Posted Tue Apr 27, 2004 6:26 PM

I know that there has been recent progress by at least someone. First, I know that in the past, there were only about 4 Channel F roms floating around, but recently almost the complete set has been dumped. Furthermore, someone has recompiled MESS to work properly with these ROMS now, and has also wrote a multicart menu code for this.

During this process, an easter egg was found in Videocart #20.

Additionally, a Swedish collector is offering a bounty of a complete collection of carts to anyone who can program a Tetris game for the Channel F.

Details here:

http://w5.nuinternet...06/competition/

#7  

    The Mad Moderator

  • 19,590 posts
  • Joined: 24-April 01
  • Screaming at Fate
  • Location:Elysium

Posted Tue Apr 27, 2004 8:45 PM

Quote

During this process, an easter egg was found in Videocart #20.

And that EE was?

Tempest

#8 ONLINE  

    Quadrunner

  • 7,370 posts
  • Joined: 12-June 03
  • Cruise Elroy = 4DB7
  • Location:Port St. Lucie, Florida

Posted Tue Apr 27, 2004 9:33 PM

Tempest said:

Quote

During this process, an easter egg was found in Videocart #20.

And that EE was?

Tempest

Yeah, I searched all over for info on it and gave up.

-Bry

#9  

    River Patroller

  • 4,705 posts
  • Joined: 14-August 01
  • Location:Southgate, Michigan

Posted Wed Apr 28, 2004 12:34 AM

Where are these roms at , for that matter?

#10  

    River Patroller

  • 2,362 posts
  • Joined: 24-April 01
  • Location:NYC, NY

Posted Wed Apr 28, 2004 7:52 AM

Here are the instructions I was sent on the Videocart #20 Easter Egg (Video Wizball):

Quote

First, start a game with a target score of 1 (push down to get to the SCORE prompt, twist counter-clockwise until the number is 1) then pull up to start.   It doesn't actually have to be a 1 score game, but you need to finish a game, and that's the shortest game you can play.

Now move your controller forward or backwards, or else the computer will play both sides.  Now win (or lose), and the computer opponent will stop moving.

Shoot him and then let yourself get hit by an object, while you are both gone, pull up to start over.

Now select GAME 43 and SCORE 67, and pull up to start. (Hex 43 = Dec 67)  

The programmer's name appears as a fixed object in the middle of the playfield on which all moving objects will bounce.

The last five bytes in the code are TRACY, the name of the programmers
daughter.

There is also an egg in the Democart code:

Quote

When you get to the end of the demo, hit buttons 1,3 and 4 at the same time. When you release them, the programmer's name is printed.

I will see about getting the ROMS and updated MESS files available to those that want them.

Attached Thumbnails

  • Attached Image: chan0002.jpg


#11  

    Chopper Commander

  • 135 posts
  • Joined: 27-February 03

Posted Wed Apr 28, 2004 4:59 PM

Do you happen to know who, or at least where you saw that someone had made progress in programming for the system?

#12  

    River Patroller

  • 4,705 posts
  • Joined: 14-August 01
  • Location:Southgate, Michigan

Posted Wed Apr 28, 2004 5:29 PM

MrRetroGamer said:

Here are the instructions I was sent on the Videocart #20 Easter Egg (Video Wizball):

Quote

First, start a game with a target score of 1 (push down to get to the SCORE prompt, twist counter-clockwise until the number is 1) then pull up to start.   It doesn't actually have to be a 1 score game, but you need to finish a game, and that's the shortest game you can play.

Now move your controller forward or backwards, or else the computer will play both sides.  Now win (or lose), and the computer opponent will stop moving.

Shoot him and then let yourself get hit by an object, while you are both gone, pull up to start over.

Now select GAME 43 and SCORE 67, and pull up to start. (Hex 43 = Dec 67)  

The programmer's name appears as a fixed object in the middle of the playfield on which all moving objects will bounce.

The last five bytes in the code are TRACY, the name of the programmers
daughter.

There is also an egg in the Democart code:

Quote

When you get to the end of the demo, hit buttons 1,3 and 4 at the same time. When you release them, the programmer's name is printed.

I will see about getting the ROMS and updated MESS files available to those that want them.

Wow. So, would this easter egg be before the Adventure one? I don't know when the democart came out, but it seems like it would be before then.

I'd be interested in those files and roms :P

#13  

    River Patroller

  • 2,362 posts
  • Joined: 24-April 01
  • Location:NYC, NY

Posted Thu Apr 29, 2004 7:16 PM

Sorry for the delay in getting back to everyone, I was having trouble setting up my FTP account on my new domain. :dunce:

Anyway, go here:

http://retrogamesrus.com/ChannelF/

When prompted, user name is channelf, password is zircon.

You should see 2 files, one is all the ROMs (missing #25) and 2 BIOS files. Any rom number with the letter "g" after it is the German version.

The other file contains 2 recompiled MESS files, so replace the ones you have with these. I have been using the latest version of MESS, don't know if these files will work with older versions. The control keys are a bit tricky, you'll need to take a look at the control map to figure out which keys do what. Just about everything works as far as I can tell.

Good luck and enjoy! :D

Blackbird said:

Do you happen to know who, or at least where you saw that someone had made progress in programming for the system?

Check this guy out: http://members.cox.n...ddle/chanf.html

#14  

    Thrust, Jammed, SWOOPS!

  • 16,625 posts
  • Joined: 25-April 01
  • Always left from right here!
  • Location:Düsseldorf, Germany

Posted Sat May 1, 2004 1:19 AM

Thanks! :thumbsup:

#15  

    Dragonstomper

  • 805 posts
  • Joined: 07-September 06
  • Location:Pennsylvania

Posted Thu Jul 12, 2007 10:29 PM

Thought I'd unearth this old topic because I've been messing around with the Channel F and well.. the VESWiki is gone. I've been looking over Blackbird's Pac-man sorce and wrote my own little demo but for some reason I can't get my sprite to be drawn, it's there alright though as it moves off the screen (causing that black horizontal line). Been looking my code over and over and for the life of me can't figure out why the sprite isn't being drawn in the color I specified and why it's always clear.

#16  

    Dragonstomper

  • 805 posts
  • Joined: 07-September 06
  • Location:Pennsylvania

Posted Fri Jul 13, 2007 1:29 PM

View PostEmOneGarand, on Fri Jul 13, 2007 12:29 AM, said:

Thought I'd unearth this old topic because I've been messing around with the Channel F and well.. the VESWiki is gone. I've been looking over Blackbird's Pac-man sorce and wrote my own little demo but for some reason I can't get my sprite to be drawn, it's there alright though as it moves off the screen (causing that black horizontal line). Been looking my code over and over and for the life of me can't figure out why the sprite isn't being drawn in the color I specified and why it's always clear.
Fixed it, now onto figuring out controls and adding enemy sprites... wish there were more resources.

#17  

    Moonsweeper

  • 345 posts
  • Joined: 03-August 06
  • I built this:
  • Location:Sweden

Posted Wed Aug 8, 2007 12:35 PM

View PostEmOneGarand, on Fri Jul 13, 2007 9:29 PM, said:

View PostEmOneGarand, on Fri Jul 13, 2007 12:29 AM, said:

Thought I'd unearth this old topic because I've been messing around with the Channel F and well.. the VESWiki is gone. I've been looking over Blackbird's Pac-man sorce and wrote my own little demo but for some reason I can't get my sprite to be drawn, it's there alright though as it moves off the screen (causing that black horizontal line). Been looking my code over and over and for the life of me can't figure out why the sprite isn't being drawn in the color I specified and why it's always clear.
Fixed it, now onto figuring out controls and adding enemy sprites... wish there were more resources.


Hi there!

I'm the co-author of Pac-Man on Channel F, I can probably help you... It would be nice to try out your program. Any screenshots?
Isn't the WIKI up again, I got an email from Blackbird a few weeks ago saying he was ready for another go at the game.


Let me know.

e5frog

#18  

    Dragonstomper

  • 805 posts
  • Joined: 07-September 06
  • Location:Pennsylvania

Posted Wed Aug 8, 2007 1:31 PM

View Poste5frog, on Wed Aug 8, 2007 2:35 PM, said:

View PostEmOneGarand, on Fri Jul 13, 2007 9:29 PM, said:

View PostEmOneGarand, on Fri Jul 13, 2007 12:29 AM, said:

Thought I'd unearth this old topic because I've been messing around with the Channel F and well.. the VESWiki is gone. I've been looking over Blackbird's Pac-man sorce and wrote my own little demo but for some reason I can't get my sprite to be drawn, it's there alright though as it moves off the screen (causing that black horizontal line). Been looking my code over and over and for the life of me can't figure out why the sprite isn't being drawn in the color I specified and why it's always clear.
Fixed it, now onto figuring out controls and adding enemy sprites... wish there were more resources.


Hi there!

I'm the co-author of Pac-Man on Channel F, I can probably help you... It would be nice to try out your program. Any screenshots?
Isn't the WIKI up again, I got an email from Blackbird a few weeks ago saying he was ready for another go at the game.


Let me know.

e5frog
Theres not much to it other then the border and the sidebar, can't quite get the sprite to only move when it's reading the controller state and the collision isn't working, likes to go off the screen creating a black bar.

Attached Files


Edited by EmOneGarand, Wed Aug 8, 2007 1:32 PM.


#19  

    Moonsweeper

  • 345 posts
  • Joined: 03-August 06
  • I built this:
  • Location:Sweden

Posted Wed Aug 8, 2007 2:24 PM

View PostEmOneGarand, on Wed Aug 8, 2007 9:31 PM, said:

Theres not much to it other then the border and the sidebar, can't quite get the sprite to only move when it's reading the controller state and the collision isn't working, likes to go off the screen creating a black bar.


In Pac-Man we delete and redraw the sprite every update (and also the monsters).

As the position is stored in two registers (or copied into before being drawn) you can read those registers and compare the value to what the values are at your extreme values. If they're too much or too litte you change the register to the closest extreme value before redrawing again.

Like this:
Read controller
Delete object at current position
Change coordinate registers x, y (or however you set position) according to hand controller movement
Compare new values to extreme points
Change values if outside allowed values
Draw object at new or unchanged position

If you store the old position in other registers and delete object just before you redraw it at the new position you'll get less flicker.

Let's say you have coordinates x: [0,50] and y: [0,50], after a controller movement the x register is 51, you compare it to 50 and result is greater (or compare to 51 and get equal) -> change value back to 50 and the object will stay at that position.

Collisions can be done the same way, compare x and y coordinates, if the coordinates are the same (or within a certain range) there's a collision. I don't know any other way to do it. You could compare one coordinate first, if it isn't close, skip checking the other one.


When the object goes outside the screen it affects (one or both) the "palette setting columns" in the screen memory which apparently gets set to Black/white at that bar/bars.

If you'd like some more detailed help, let me know, I can assist you better if you share your code.

e5frog

#20  

    Dragonstomper

  • 805 posts
  • Joined: 07-September 06
  • Location:Pennsylvania

Posted Wed Aug 8, 2007 9:47 PM

View Poste5frog, on Wed Aug 8, 2007 4:24 PM, said:

View PostEmOneGarand, on Wed Aug 8, 2007 9:31 PM, said:

Theres not much to it other then the border and the sidebar, can't quite get the sprite to only move when it's reading the controller state and the collision isn't working, likes to go off the screen creating a black bar.


In Pac-Man we delete and redraw the sprite every update (and also the monsters).

As the position is stored in two registers (or copied into before being drawn) you can read those registers and compare the value to what the values are at your extreme values. If they're too much or too litte you change the register to the closest extreme value before redrawing again.

Like this:
Read controller
Delete object at current position
Change coordinate registers x, y (or however you set position) according to hand controller movement
Compare new values to extreme points
Change values if outside allowed values
Draw object at new or unchanged position

If you store the old position in other registers and delete object just before you redraw it at the new position you'll get less flicker.

Let's say you have coordinates x: [0,50] and y: [0,50], after a controller movement the x register is 51, you compare it to 50 and result is greater (or compare to 51 and get equal) -> change value back to 50 and the object will stay at that position.

Collisions can be done the same way, compare x and y coordinates, if the coordinates are the same (or within a certain range) there's a collision. I don't know any other way to do it. You could compare one coordinate first, if it isn't close, skip checking the other one.


When the object goes outside the screen it affects (one or both) the "palette setting columns" in the screen memory which apparently gets set to Black/white at that bar/bars.

If you'd like some more detailed help, let me know, I can assist you better if you share your code.

e5frog
Is there a complete build of Pacman? I'd like to see how you guys coded the logic for the ghosts in particular, I've got an enemy sprite defined just don't know how to call it within the game loop

Also heres my source so far (theres a bit of code commented out, havn't gotten those to work with the code yet)

Attached Files



#21  

    Moonsweeper

  • 345 posts
  • Joined: 03-August 06
  • I built this:
  • Location:Sweden

Posted Thu Aug 9, 2007 2:45 AM

View PostEmOneGarand, on Thu Aug 9, 2007 5:47 AM, said:

Is there a complete build of Pacman? I'd like to see how you guys coded the logic for the ghosts in particular, I've got an enemy sprite defined just don't know how to call it within the game loop

Also heres my source so far (theres a bit of code commented out, havn't gotten those to work with the code yet)


Thanks, I'll have a look at it later today.

There is a complete and almost fully working (I've detected some bugs at random times but not been able to reproduce them). I've tried to mimic the same monster-behaviour as the original Pac-man, calculating where to go next according to certain rules. I've tried studying the original code but as we don't use the same type of blocks and coordinates I couldn't use it straight off.

Adding an enemy also needs adding delete and redraw of the enemy, you could use the same sprite-draw routine if you copy the coordinates to a common register before deleting and redrawing it. You need to add enemy-update somewhere before or after updating your own player (if they're supposed to run at the same speed). Using the same technique, erasing, updating coordinates and then redraw. You also need to redraw any graphics that the enemy has collided with after erasing it - as for example other enemies or background graphics will also be deleted.

The enemy coordinates can be set to certain rules or read preset data to move the desired way. A first try could perhaps be just to make the enemy follow player x or/and y coordinates. Like Pac-man it could perhaps aim at a point near the player or similar...

I'll send you some code when I manage to get home to my own computer.

Happy coding!

/ e5frog

#22  

    Moonsweeper

  • 345 posts
  • Joined: 03-August 06
  • I built this:
  • Location:Sweden

Posted Thu Aug 9, 2007 7:07 AM

First thing I noticed was this:

setupShip:
	lisu	4
	lisl	3
	li	SHIP_START_X
	lr	I, A
	li	SHIP_START_Y
	lr	I, A
	
	li	000001
	lr	I, A
	
	li  0
	lr	S, A
	
;setupAlien1:
	;lisu	4
	;lisl	3
	;li	ALIEN1_START_X
	;lr	I, A
	;li	ALIEN1_START_Y
	;lr	I, A
	
	;li	000001
	;lr	I, A
	
	;li	0
	;lr	S, A

You're loading the Alien coordinates into the same registers as the ship's coordinates (lisu 4; lisl 3 -> OCTAL:43)
As it's commented away I don't know if the code is actually updated, just wanted to point it out. ;-)

Same problem in the clearAlien1-routine it loads the same coordinates as the Ship.

If you're only going to have one image for the ship you can remove the animation of it, it saves CPU-time.

Another thought is that as you're using basically a square for the playfield you can remove all the tile-checking and implement boundary-checks instead - as I described earlier. Just check that the x and y coordinates don't pass the highest and lowest allowed values.
The whole checkIntersection-routine can be replaced by a simple boundary check.

To start with, using subroutines are very handy, but as the game progress and you might need to increase speed - removing them and writing it directly into the code speed things up. Also the pushk and popk routines are only necessary when using several subroutines "on top of eachother". These also use a lot of CPU-time.

To reduce sprite-flicker try to do as little as possible between erasing and redrawing the sprites. Perhaps reading the handcontroller can be done before erasing.

Set up a table with all registers you intend to use and for what they are used, like this:

; r0-r31	general-purpose registers
; r33		level number
; r34		(unused)
; r35		pac-man x coordinate
; r36		pac-man y coordinate
; r37		pac-man direction
; r38		animation index

Perhaps writing the numbers octally also will help keeping track of the correct registers. ;-)
Like your Ship coordinates starts at x: OCTAL 43 which is register 35, y: r 36 (octal 44)

You set the ISAR register with lisu (Load ISAR upper) and lisl, then the li A, I increases ISAR when you load A from the register ISAR points to.



I'll try it out in MESS when I get home. ;-)

#23  

    Moonsweeper

  • 345 posts
  • Joined: 03-August 06
  • I built this:
  • Location:Sweden

Posted Fri Aug 10, 2007 11:59 AM

I've assembled it with dasm and tried to run it in MESS, but it didnt start up at all, didn't know why...

... until I remebered that I needed to "even off" the bin-size.

I added these two rows last in the program - evens out to full 1024 byte units:

	org [$800 + [XXXX * $400] -$1]

	.byte 0

XXXX = 2 for a 2kByte file, 4 for a 4kB size file etc.
Blackbird has added his signature last in the code:
.byte "ˇBlackbirdˇ 2006"

But then you need to increase the number of bytes you subtract from the org-statement above (subtracts only 1 byte).



I see the problem now, the Ship (and a good-looking ship it is) continues to float.... I'll check it out.



BTW
Here's the register table for Pac-man, variables are used together with a macro to set ISAR easily:

;---------------------------------------------------------------------------
; Register Reference 
;---------------------------------------------------------------------------

; The registers in the F8 are used as both RAM and registers for
; this game. The reference is as follows:

; score must have a 4 in the octal one's digit, to work with score.add
; registers 020 - 027

; hi-score is backed up in RAM, registers can be 
; used for other things inside the game loop

HISCORE_REG			=	020; #16
ATTACK_COUNTER_REG	=	020; #16
ATTACK_TIMER_REG		=	021; #17
GHOSTS_RELEASED_REG	=	022; #18
GHOST_RELEASE_TIMER_REG =	023; #19

SCORE_REG			=	024; #20

; pacman registers (must be in same octet)
PACMAN_X_REG		=	030; #24
PACMAN_Y_REG		=	031; #25
PACMAN_DIRECTION_REG	=	032; #26
PACMAN_ANIMINDEX_REG	=	033; #27

; ghost registers (must be in same octet)
GHOST_TMP_REG		=	034; #28
GHOST_TMP_X_REG		=	034; #28
GHOST_TMP_Y_REG		=	035; #29
GHOST_TMP_DIR_REG		=	036; #30		b7 nested, b6 nest.out
GHOST_TMP_ANIM_REG	=	037; #31

; ghost registers (040-057)
GHOST_REG		=	040	; #32
GHOST_0_X_REG	=	040	; #32
GHOST_0_Y_REG	=	041	; #33
GHOST_0_DIR_REG	=	042	; #34
GHOST_0_ANIM_REG	=	043	; #35
GHOST_1_X_REG	=	044	; #36
GHOST_1_Y_REG	=	045	; #37
GHOST_1_DIR_REG	=	046	; #38
GHOST_1_ANIM_REG	=	047	; #39
GHOST_2_X_REG	=	050	; #40
GHOST_2_Y_REG	=	051	; #41
GHOST_2_DIR_REG	=	052	; #42
GHOST_2_ANIM_REG	=	053	; #43
GHOST_3_X_REG	=	054	; #44
GHOST_3_Y_REG	=	055	; #45
GHOST_3_DIR_REG	=	056	; #46
GHOST_3_ANIM_REG	=	057	; #47

; level registers (must be in same octet)
LEVEL_NUMBER_REG	=	060	; #48
GHOST_NUMBER_REG	=	061	; #49
PACMAN_LIVES_REG	=	062	; #50		b7 pac collision, b6 player 1/2, b5 2ply game
GHOSTS_SLOW_REG	=	063	; #51		ghost off loop b7-6, slow ghost b5
POWERPELLETS_REG	=	063	; #51		bits 4-0
GHOST_EATABLE_REG	=	064	; #52		b0 G0, b1 G1, b2 G2, b3 G3
						;	upper four bits "is eaten"
SLOW_TIMER_REG	=	065	; #53
GLOBAL_TIMER_REG	=	066	; #54

BONUS_PRIZE_REG	=	067	; #55		keeps track of when bonus prize is plotted
BONUS_PRIZE_ON	=	070	; #56

;---------------------------------------------------------------------------

It helps when you are programming, keeping track of what the registers are used for.

Using the SETISAR dasm-macro by Blackbird makes it easier to set the ISAR:

;-------------------------
; SETISAR
; Original Author: Blackbird
; Sets the ISAR to a register number, using lisu and lisl
	SETISAR	HISCORE_REG
	MAC SETISAR
	lisu	[[{1}] >> 3]
	lisl	[[{1}] & %111]
	ENDM

Then you simply write this in your code:

	SETISAR	HISCORE_REG

instead of

	lisu	2
	lisl	0

Changing the ISAR a lot this helps.

;-)

#24  

    Moonsweeper

  • 345 posts
  • Joined: 03-August 06
  • I built this:
  • Location:Sweden

Posted Fri Aug 10, 2007 12:49 PM

I manged to solve your problem. As I have understood it the Ship is only supposed to move left or right?


There's a lot of unused code that can be removed. ;-)


;-------------------------;
;=========================;
;    Channel Invaders     ;
;    by Matt Alexander    ;
;                         ;
;  code based on Pac-Man  ;
;   source by Blackbird   ;
;=========================;
;-------------------------;


	processor f8

;=========;
; Equates ;
;=========;

;------------;
; BIOS Calls ;
;------------;
clrscrn         =       $00d0                                   ; uses r31
delay           =       $008f
pushk           =       $0107                                   ; used to allow more subroutine stack space
popk            =       $011e
drawchar        =       $0679

;-------------------;
; Color Definitions ;
;-------------------;
red             =       $40
blue            =       $80
green           =       $00
bkg             =       $C0

;-----------------;
; RAM Definitions ;
;-----------------;
ram		= 	$2800					; use Schach RAM to hold pellet info

;--------------------;
; Register Reference ;
;--------------------;

; The registers in the f8 are used as both RAM and registers for
; this game. The reference is as follows:
;
; r0-r31	general-purpose registers
; r33		level number
; r34		(unused)
; r35		pac-man x coordinate
; r36		pac-man y coordinate
; r37		pac-man direction
; r38		animation index

;---------------;
; Object Colors ;
;---------------;

SHIP_COLOR		    =	green
SCRN_BGCOLOR		=	bkg
SCRN_FGCOLOR		=	red
;BULLET_COLOR		=	red
SIDEBAR_COLOR		=	blue
ALIEN1_COLOR		=	green
ALIEN2_COLOR		=	blue
ALIEN3_COLOR		=	red

;------------------;
; Object Variables ;
;------------------;

SHIP_START_X		=	40
SHIP_START_Y		=	40
;ALIEN1_START_X		=	20
;ALIEN1_START_y      =	70

;===================;
; Main Program Code ;
;===================;

;---------------;
; Program Entry ;
;---------------;

	org	$800

cartridgeStart:
	.byte	$55, $00					; cartridge header

cartridgeEntry:
	lis	0						; init the h/w
	outs	1
	outs	4
	outs	5
	outs	0
                
	lisu	4						; r32 = complement flag
	lisl	0
	lr	S, A
                
	li	$c6						; set to three color, grey background
	lr	3, A						; clear screen to grey
	pi	clrscrn						;
	
;---------------;
;main
;---------------;

mainloop:

startLevel:
	; draw the map
	pi	drawMap
	; the sidebar
	pi	drawSidebar
	;pi	drawAlien1
	;pi  setupAlien

setupShip:
	lisu	4
	lisl	3
	li	SHIP_START_X
	lr	I, A
	li	SHIP_START_Y
	lr	I, A
	
	li	000001
	lr	I, A
	
	li  0
	lr	S, A
	
;setupAlien1:
	;lisu	4
	;lisl	3
	;li	ALIEN1_START_X
	;lr	I, A
	;li	ALIEN1_START_Y
	;lr	I, A
	
	;li	000001
	;lr	I, A
	
	;li	0
	;lr	S, A

playLoop:
.clearShip:
	li  SCRN_BGCOLOR
	lr  1, A
	
	lisu	4
	lisl	3
	lr	A, S
	lr	2, A
	
	lisl	4
	lr	A, S
	lr	3, A
	
	lis 0
	lr	4, A
	
	pi drawSprite

;.clearAlien1:
	;li	SCRN_BGCOLOR
	;lr	1, A
	
	;lisu	4
	;lisl	3
	;lr	A, S
	;lr	2, A
	
	;lisl	4
	;lr	A, S
	;lr	3, A
	
	;lis 0
	;lr	4, A
	
	;pi drawSprite

.checkController:
	pi  shipControls
	
.checkDirection:
;	pi  checkIntersection
;	ci  1
;	bnz .checkDirectionEnd
	
	lisu	4
	lisl	5
	lr	A, S
	ns  0
	bnz .checkDirectionEnd
	jmp .drawShip
.checkDirectionEnd:

.updateShipFrame:
	lisu	4
	lisl	6
	lr	A, S
	inc
	ci	4
	bnz .updateShipFrameEnd
	
	li  0
.updateShipFrameEnd:
	lr	S, A
	
.moveShip

	lisu	4
	lisl	5
	lr	A, S
	lr	0, A
	
	ni  000010
	bnz .moveShipLeft
	;right
	lr	A, 0
	ni  000001
	bnz .moveShipRight
	;no movement
	br	.moveShipEnd
	

.moveShipLeft:
	lisl	3
	ds	S
	br	.moveShipEnd
	
.moveShipRight:
	lisl	3
	lr	A, S
	inc
	lr	S, A
	br	.moveShipEnd
.moveShipEnd:





.drawShip:
	lisl	5
	lr	A, S

.drawShipIsDirectionRight:
	ci	000001
	bnz	.drawShipDirectionLeft
	lis	13
	br	.drawShipDirectionEnd

.drawShipDirectionLeft:
	lis	9
	
.drawShipDirectionEnd:
	lr	4, A
	
	lisu	4
	lisl    6
	lr	A, S
	lr	0, A
	lr	A, 4
.drawShipGetAddress:
	ds  0
	bm	.drawShipGetAddressEnd
	inc
	br	.drawShipGetAddress
.drawShipGetAddressEnd:
	lr	4, A
	
.drawShipSprite
	li  SHIP_COLOR
	lr	1, A
	lisu	4
	lisl	3
	lr	A, I
	lr	2, A
	lr	A, S
	lr	3, A
	pi	drawSprite
	
;.checkAlien:
	;pi	alienCheck

;.alienClearedCheck:
	;dci ram
	
	;li 35
	;lr 0, A

;.alienClearedLoop:
	;ds	0
	;bm	.alienClearedEmpty
	
	;lm
	;ci	0
	;bnz .alienClearedEnd
	;br	.alienClearedLoop
;.alienClearedEnd:

.playLoopDelay:
	lis 10
	lr  5, A
	pi	delay
	
	jmp playLoop
.playLoopEnd:
	jmp mainloop

endGame:
	li	4
	lr	0, A
	
.endGameLoop:
	li	$ff
	lr	1, A
	li	250
	lr	2, A
	li	58
	lr	3, A

.endGameLoops1:
	li	$5f
	lr	5, A
	pi	delay
	
	li	$0
	lr	1, A
	li	250
	lr	2, A
	li	58
	lr	3, A

.endGameLoop2:
	ds	3
	bm	.endGameLoop2End
	pi	plot
	br	.endGameLoop2

.endGameLoop2End:
	
	li	$5f
	lr	5, A
	pi	delay
	
.endGameLoopCheck:
	ds	0
	bnz	.endGameLoop
	
.endGameEnd:
	jmp mainloop

;------------------
;Alien routines
;------------------

;nada

;------------------
;------------------

;controls
readController:
	; see one of the hand controllers is moved
	clr
	outs	0
	outs	4
	ins	4
	com							; un-invert port data
	ni	$cf						; mask off twists, since we don't use them
	bnz	.readControllerEnd
	outs	1
	ins	1
	com
	ni	$cf

	lr	0, A

.readControllerEnd:
	pop
	
shipControls:
	lr	K, P
	pi	pushk
	
	pi  readController
	
	;left
	lr	A, 0
	ni	000010
	bnz .shipControlsCheckLeft
	;right
	lr	A, 0
	ni	000001
	bnz .shipControlsCheckRight
	;no direction
	clr
	br	.shipControlsCheckEnd
	
.shipControlsCheckLeft:
	li	000010
	br	.shipControlsCheckEnd
.shipControlsCheckRight:
	li	000001
	
.shipControlsCheckEnd:
	
	lisu	4
	lisl	5
	
	lr	S, A						; store direction in O:45
	
.shipControlsEnd:

	pi	popk
	pk
	



;background crap

plot:
	; set the color using r1
	lr	A, 1
	outs	1

	; set the column using r2
	lr	A, 2
	ai	4
	com
	outs	4

	; set the row using r3
	lr	A, 3
	ai	4
	com
	outs	5

	; transfer data to the screen memory
	li	$60
	outs	0
	li	$50
	outs	0

	; delay until it's fully updated
	lis	6
.plotDelay:	
	ai	$ff
	bnz	.plotDelay

	pop							; return from the subroutine

drawTile:
	; registers reference:
	; r1 = reserved (plot color)
	; r2 = reserved (plot x)
	; r3 = reserved (plot y)
	; r4 = color 1
	; r5 = color 2
	; r6 = x
	; r7 = y
	; r8 = loop1 (row)
	; r9 = loop2 (column)
	; r10 = bitmask
	; r11 = graphics byte

	; save the return address
	lr	K, P
	pi	pushk

	; get the tile address
	dci	tiles
	; add the offset
	lr	A, 5
	inc							; make sure we hit 0
	lr	0, A
	lis	3						; three bytes for each tile
.drawTileAddressLoop:
	ds	0
	bz	.drawTileAddressLoopEnd
	adc
	br	.drawTileAddressLoop
.drawTileAddressLoopEnd:
	; got the tile data, now get the graphics address
	lm
	lr	Qu, A
	lm
	lr	Ql, A
	lr	DC, Q

	; rearrange the registers
	lr	A, 4
	lr	7, A
	lr	A, 3
	lr	6, A
	lr	A, 2
	lr	5, A
	lr	A, 1
	lr	4, A

	; start row loop
	li	8
	lr	8, A
.drawTileRow:
	; setup the bit mask
	li	%10000000					; we only want the left-most pixel
	lr	10, A						; store it in r10
	; and get the graphics byte
	lm							; load the pixel and increase the DC
	lr	11, A						; store it in r11

	; start column loop
	li	8
	lr	9, A
.drawTileColumn:

	; find out the x address
	lr	A, 9						; load the new offset
	com							; and subtract it from 8
	inc							; via 2's complement
	ai	8						; subtract A from 8, ignore carry
	as	6						; add the tile's real x offset
	lr	2, A						; save it for the subroutine call
	; and the y address
	lr	A, 8						; load the new offset
	com							; and subtract it from 8
	inc							; via 2's complement
	ai	8						; subtract A from 8, ignore carry
	as	7						; add the tile's real y offset
	lr	3, A						; save it for the subroutine call

	; initially load color 2
	lr	A, 5
	lr	1, A
	; see if the pixel is on or off
	lr	A, 11						; load the byte
	ns	10						; mask it with the bitmask
	bnz	.drawTilePixel					; if the pixel's off, use color 1
	; conditionally load color 1
	lr	A, 4
	lr	1, A

.drawTilePixel:
	pi	plot

.drawTileRollBitmask:
	; roll the bitmask
	lr	A, 10
	sr	1
	lr	10, A

.drawTileCheckLoops:
	; check column loop
	ds	9
	bnz	.drawTileColumn

	; check row loop
	ds	8
	bnz	.drawTileRow

	pi	popk
	pk							; return from the subroutine

drawMap:
	; this function uses several reserve registers
	; because the functions called need the immediate ones
	; r17 (21o) = x counter
	; r18 (22o) = y counter

	; load the return address into memory
	lr	K, P
	pi	pushk

	; load the map address into DC1
	dci	maze_map
	xdc

	; clear address offset
	lisu	2
	lisl	5
	clr
	lr	S, A

	lisl	1						; 
	lis	7						; load r17 with 7 rows of tiles
	lr	S, A						;
.drawMapRow:

	lisl	2						;
	lis	10						; load r18 with 10 tiles per row
	lr	S, A						;
.drawMapColumn:

	; this is the start of drawing an individual tile

	; note of reference to drawTile:
	; r1 = color 1
	; r2 = color 2
	; r3 = x (to screen)
	; r4 = y (to screen)
	; r5 = tile number

	lisl	2						; load register r20
	lr	A, S
	lr	0, A						; set r0 as our row counter
	li	0						; clear A to the first pixel
.drawMapGetX:
	ds	0
	bz	.drawMapSaveX
	ai	8
	br	.drawMapGetX

.drawMapSaveX:
	com							; we want to display the tiles from
	inc							; top to bottom, so we inverse
	ai	72						; both coordinates
	lr	3, A						; store the x coordinate in r3

	lisl	1						; load register r19
	lr	A, S
	lr	0, A						; set r0 as our column counter
	li	0						; clear A to zero
.drawMapGetY:
	ds	0
	bz	.drawMapSaveY
	ai	8
	br	.drawMapGetY

.drawMapSaveY:
	com							; we want to display the tiles from
	inc							; top to bottom, so we inverse
	ai	48						; both coordinates
	lr	4, A						; store the y coordinate in r4

.drawMapSetupRegisters:

	; this block of code gets the next tile number
	; and increases the data offset

	; swap DC0 and DC1
	xdc
	; get and save the next tile byte
	lm
	lr	5, A
	; swap back
	xdc

	; set the colors
	; color 1
	li	SCRN_BGCOLOR
	lr	1, A						; r1
	; color 2
	li	SCRN_FGCOLOR
	lr	2, A						; r2

	; finally, call the tile function
	pi	drawTile

.drawMapCheckLoops:
	; check column loop
	lisu	2
	lisl	2
	ds	D						; r18
	bnz	.drawMapColumn

	; check row loop
	ds	S						; r17
	bnz	.drawMapRow

.drawMapReturn:
	; return to the program flow
	pi	popk
	pk							; return from the subroutine
	
drawSprite:
	; registers reference:
	; r1 = reserved (plot color)
	; r2 = reserved (plot x)
	; r3 = reserved (plot y)
	; r4 = color
	; r6 = x
	; r7 = y
	; r8 = loop1 (row)
	; r9 = loop2 (column)
	; r10 = bitmask
	; r11 = graphics byte

	; save the return address
	lr	K, P
	pi	pushk

	; get the tile address
	dci	sprites
	; add the offset
	lr	A, 4
	inc							; make sure we hit 0
	lr	0, A
	lis	2						; two bytes for each sprite
.drawSpriteAddressLoop:
	ds	0
	bz	.drawSpriteAddressLoopEnd
	adc
	br	.drawSpriteAddressLoop
.drawSpriteAddressLoopEnd:
	; got the sprite data, now get the graphics address
	lm
	lr	Qu, A
	lm
	lr	Ql, A
	lr	DC, Q

	; rearrange the registers
	lr	A, 3
	lr	7, A
	lr	A, 2
	lr	6, A
	lr	A, 1
	lr	4, A

	; start row loop
	li	5
	lr	8, A
.drawSpriteRow:
	; setup the bit mask
	li	%10000000					; we only want the left-most pixel
	lr	10, A						; store it in r10
	; and get the graphics byte
	lm							; load the pixel and increase the DC
	lr	11, A						; store it in r11

	; start column loop
	li	5
	lr	9, A
.drawSpriteColumn:

	; find out the x address
	lr	A, 9						; load the new offset
	com							; and subtract it from 5
	inc							; via 2's complement
	ai	5						; subtract A from 5, ignore carry
	as	6						; add the tile's real x offset
	lr	2, A						; save it for the subroutine call
	; and the y address
	lr	A, 8						; load the new offset
	com							; and subtract it from 5
	inc							; via 2's complement
	ai	5						; subtract A from 5, ignore carry
	as	7						; add the tile's real y offset
	lr	3, A						; save it for the subroutine call

	; see if the pixel is on or off
	lr	A, 11						; load the byte
	ns	10						; mask it with the bitmask
	bz	.drawSpriteRollBitmask				; if the pixel's off, don't draw anything
	; conditionally load color 1
	lr	A, 4
	lr	1, A

.drawSpritePixel:
	pi	plot

.drawSpriteRollBitmask:
	; roll the bitmask
	lr	A, 10
	sr	1
	lr	10, A

.drawSpriteCheckLoops:
	; check column loop
	ds	9
	bnz	.drawSpriteColumn

	; check row loop
	ds	8
	bnz	.drawSpriteRow

.drawSpriteEnd:
	pi	popk
	pk							; return from the subroutine
	
;--------------;
; Draw Sidebar ;
;--------------;

; draws the right sidebar rectangle

drawSidebar:
	; save return address
	lr	K, P

	; set sidebar color
	li	SIDEBAR_COLOR
	lr	1, A

	; start row loop
	li	57
	lr	3, A
.drawSidebarRow:
	li	101
	lr	2, A
.drawSidebarColumn:
	pi	plot

.drawSidebarCheck:
	ds	2
	lr	A, 2
	xi	%01010000
	bnz	.drawSidebarColumn
	ds	3
	bp	.drawSidebarRow

;.drawSidebarText:
	;dci	scoreGraphic.parameters
	;pi	blitGraphic
	;dci	highGraphic.parameters
	;pi	blitGraphic

.drawSidebarEnd:
	pk

drawScore:
	; save return address
	lr	K, P
	pi	pushk

	; load colors
	li	SIDEBAR_COLOR
	lr	1, A
	li	blue
	lr	2, A

	; load position
	li	78
	lr	10, A
	lis	6
	lr	11, A

	; set number counter
	lis	8
	lr	0, A
	; and ISAR
	lisu	7
	lisl	4

.drawScoreLoop:
	; set DC
	dci	numberGraphics

	; load size
	lis	3
	lr	5, A
	lis	5
	lr	6, A

	; load position
	lr	A, 10
	lr	3, A
	lr	A, 11
	lr	4, A

	; see if the tile is even or odd
	lis	1
	ns	0
	bz	.drawScoreShiftByte				; if even, branch

	; get lower half-byte
	lis	%1111
	ns	I						; set ISAR to next byte
	br	.drawScoreDrawDigit
.drawScoreShiftByte:
	; get upper half-byte
	lr	A, S
	sr	4

.drawScoreDrawDigit:
	; add tile offset
	sl	1
	adc
	; and draw the number
	;pi	blit

	; increase x position
	lis	4
	as	10
	lr	10, A						; each tile is three pixels + one pixel space

	; decrease the counter
	ds	0
	bz	.drawScoreEnd					; reached the end, break
	; check to see if we're on tile 4
	lis	4
	xs	0
	bnz	.drawScoreLoop

.drawScoreChangeRow:
	li	82
	lr	10, A
	lis	12
	lr	11, A
	br	.drawScoreLoop

.drawScoreEnd:
	; return from subroutine
	pi	popk
	pk


;-----------;
; Tile Data ;
;-----------;

; format:
; two bytes for the address of the tile
; one byte for the boundaries of the tile (00 + up + down + left + right)

tiles:
	; these are regular tiles
	; which can be used in any map

	; tile 0
	.word	tilePic_0
	.byte	001111

	; tile 1
	.word	tilePic_1
	.byte	000101

	; tile 2
	.word	tilePic_2
	.byte	000111

	; tile 3
	.word	tilePic_3
	.byte	000011

	; tile 4
	.word	tilePic_4
	.byte	000110

	; tile 5
	.word	tilePic_5
	.byte	001001

	; tile 6
	.word	tilePic_6
	.byte	001110

	; tile 7
	.word	tilePic_7
	.byte	001011

	; tile 8
	.word	tilePic_8
	.byte	001101

	

;---------------;
; Tile Graphics ;
;---------------;

tilePic_0:
	.byte	000000
	.byte	000000
	.byte	000000
	.byte	000000
	.byte	000000
	.byte	000000
	.byte	000000
	.byte	000000

tilePic_1:
	.byte	000000
	.byte	111111
	.byte	%01000000
	.byte	%01001111
	.byte	%01010000
	.byte	%01010000
	.byte	%01010000
	.byte	%01010000

tilePic_2:
	.byte	000000
	.byte	%11111111
	.byte	000000
	.byte	%11111111
	.byte	000000
	.byte	000000
	.byte	000000
	.byte	000000

tilePic_3:
	.byte	000000
	.byte	%11111110
	.byte	000001
	.byte	%11111001
	.byte	000101
	.byte	000101
	.byte	000101
	.byte	000101

tilePic_4:
	.byte	000101
	.byte	000101
	.byte	000101
	.byte	000101
	.byte	000101
	.byte	000101
	.byte	000101
	.byte	000101

tilePic_5:
	.byte	000101
	.byte	000101
	.byte	000101
	.byte	000101
	.byte	%11111001
	.byte	000001
	.byte	%11111110
	.byte	000000

tilePic_6:
	.byte	%11111111
	.byte	%10010011
	.byte	111000
	.byte	%01101100
	.byte	%11000111
	.byte	000000
	.byte	%11111111
	.byte	000000

tilePic_7:
	.byte	%01010001
	.byte	%01010001
	.byte	%01010000
	.byte	%01010000
	.byte	%01001111
	.byte	%01000000
	.byte	111111
	.byte	000000

tilePic_8:
	.byte	%01010000
	.byte	%01010000
	.byte	%01010000
	.byte	%01010000
	.byte	%01010000
	.byte	%01010000
	.byte	%01010000
	.byte	%01010000



;------------;
; Level Data ;
;------------;

maze_map:
	; level map
	.byte	1,  2,  2,  2,  2,  2,  2,  2,  2,  3
	.byte	8,  0,  0,  0,  0,  0,  0,  0,  0,  4
	.byte	8,  0,  0,  0,  0,  0,  0,  0,  0,  4
	.byte	8,  0,  0,  0,  0,  0,  0,  0,  0,  4
	.byte	8,  0,  0,  0,  0,  0,  0,  0,  0,  4
	.byte	8,  0,  0,  0,  0,  0,  0,  0,  0,  4
	.byte	7,  6,  6,  6,  6,  6,  6,  6,  6,  5


	
;----------------;
; Ship Sprites   ;
;----------------;

sprites:
	.word	clearSprite					; sprite 0

	.word	.shipSpritesLeft				; sprite 1
	.word	.shipSpritesLeft+5				; sprite 2
	.word	.shipSpritesLeft+10				; sprite 3
	.word	.shipSpritesLeft+15				; sprite 4

	.word	.shipSpritesRight				; sprite 5
	.word	.shipSpritesRight+5				; sprite 6
	.word	.shipSpritesRight+10			; sprite 7
	.word	.shipSpritesRight+15			; sprite 8

	.word	.shipSpritesUp
	.word	.shipSpritesUp+5				
	.word	.shipSpritesUp+10			
	.word	.shipSpritesUp+15	

	.word	.shipSpritesDown
	.word	.shipSpritesDown+5				
	.word	.shipSpritesDown+10			
	.word	.shipSpritesDown+15

	.word	.alien1SpritesUp
	.word	.alien1SpritesUp+5
	.word	.alien1SpritesUp+10
	.word	.alien1SpritesUp+15

	.word	.alien1SpritesDown
	.word	.alien1SpritesDown+5
	.word	.alien1SpritesDown+10
	.word	.alien1SpritesDown+15
	
	.word	.alien1SpritesLeft
	.word	.alien1SpritesLeft+5
	.word	.alien1SpritesLeft+10
	.word	.alien1SpritesLeft+15
	
	.word	.alien1SpritesRight
	.word	.alien1SpritesRight+5
	.word	.alien1SpritesRight+10
	.word	.alien1SpritesRight+15

clearSprite:
	; 5x5 block to clear
	; a drawn sprite
	.byte	%11111100
	.byte	%11111100
	.byte	%11111100
	.byte	%11111100
	.byte	%11111100

shipSprites:
.shipSpritesLeft:
	; sprite 0
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11111000
	.byte	%10101000

	; sprite 1
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11011000
	.byte	%10101000

	; sprite 2
	.byte	100000
	.byte	100000
	.byte	%01110000
	.byte	%11011000
	.byte	%10101000

	; sprite 3
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11011000
	.byte	%10101000

.shipSpritesRight:
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11111000
	.byte	%10101000

	; sprite 1
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11011000
	.byte	%10101000

	; sprite 2
	.byte	100000
	.byte	100000
	.byte	%01110000
	.byte	%11011000
	.byte	%10101000

	; sprite 3
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11011000
	.byte	%10101000
	
.shipSpritesUp:
	; sprite 0
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11111000
	.byte	%10101000

	; sprite 1
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11011000
	.byte	%10101000

	; sprite 2
	.byte	100000
	.byte	100000
	.byte	%01110000
	.byte	%11011000
	.byte	%10101000

	; sprite 3
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11011000
	.byte	%10101000
.shipSpritesDown:
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11111000
	.byte	%10101000

	; sprite 1
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11011000
	.byte	%10101000

	; sprite 2
	.byte	100000
	.byte	100000
	.byte	%01110000
	.byte	%11011000
	.byte	%10101000

	; sprite 3
	.byte	100000
	.byte	100000
	.byte	%01010000
	.byte	%11011000
	.byte	%10101000
	
alien1Sprites:
.alien1SpritesUp:
	;sprite 1
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %01001000
	
	;sprite 2
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %10000100

	;sprite 3
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %01001000

	;sprite 4
	.byte   110000
    .byte   %01111000
    .byte   %11001100
	.byte   %11111100
	.byte   110000

.alien1SpritesDown:
	;sprite 1
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %01001000
	
	;sprite 2
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %10000100

	;sprite 3
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %01001000

	;sprite 4
	.byte   110000
    .byte   %01111000
    .byte   %11001100
	.byte   %11111100
	.byte   110000

.alien1SpritesLeft:
	;sprite 1
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %01001000
	
	;sprite 2
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %10000100

	;sprite 3
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %01001000

	;sprite 4
	.byte   110000
    .byte   %01111000
    .byte   %11001100
	.byte   %11111100
	.byte   110000

.alien1SpritesRight:
	;sprite 1
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %01001000
	
	;sprite 2
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %10000100

	;sprite 3
	.byte   110000
    .byte   %01111000
    .byte   %10110100
	.byte   %11111100
	.byte   %01001000

	;sprite 4
	.byte   110000
    .byte   %01111000
    .byte   %11001100
	.byte   %11111100
	.byte   110000

;score
scoreGraphic.parameters:
	.byte	red			; color 1
	.byte	bkg			; color 2
	.byte	78			; x position
	.byte	1			; y position
	.byte	19			; width
	.byte	4			; height
	.word	scoreGraphic.data	; address for the graphics

scoreGraphic.data:
	.byte	%01100110, %01001100, %11111001, 010101
	.byte	%01010001, %10100010, %10110011, %01100011
	.byte	100101, %01110000

highGraphic.parameters:
	.byte	red			; color 1
	.byte	bkg			; color 2
	.byte	78			; x position
	.byte	19			; y position
	.byte	16			; width
	.byte	4			; height
	.word	highGraphic.data	; address for the graphics

highGraphic.data:
	.byte	%10101110, %01101010
	.byte	%10100100, %10001010
	.byte	%11100100, %10101110
	.byte	%10101110, %01101010

numberGraphics:
	.byte	%11110110, %11011110				; 0
	.byte	%01011001, 101110				; 1
	.byte	%11100111, %11001110				; 2
	.byte	%11100111, %10011110				; 3
	.byte	%10110111, %10010010				; 4
	.byte	%11110011, %10011110				; 5
	.byte	%11110011, %11011110				; 6
	.byte	%11100100, %10010010				; 7
	.byte	%11110111, %11011110				; 8
	.byte	%11110111, %10011110				; 9

	org [$800 + [2 * $400] -$1]

	.byte 0



It compiles allright and ship moves right or left only when you hold joystick that way.
To better understand the code you could try and add more comments.

#25  

    Moonsweeper

  • 345 posts
  • Joined: 03-August 06
  • I built this:
  • Location:Sweden

Posted Fri Aug 10, 2007 1:31 PM

To set the boundaries you can add a check here:

.moveShipLeft:
	lisl	3
	ds	S
	br	.moveShipEnd
	
.moveShipRight:
	lisl	3
	lr	A, S
	inc
	lr	S, A
	br	.moveShipEnd
.moveShipEnd:

Like this:
.moveShipLeft:
	lisl	3
	li	5			; load A with 5 (minimum x-coordinate)
	xs	S			; exclusive or with scratchpad -> returns zero if equal 
	bz	.moveShipEnd
	ds	S
	br	.moveShipEnd
	
.moveShipRight:
	lisl	3
	lr	A, S
	inc
	lr	S, A
	br	.moveShipEnd
.moveShipEnd:


Same procedure with the moveShipRight. ;-)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users