Jump to content

Photo

Fairchild Channel F Tech/Programming info


41 replies to this topic

#1 TailChao OFFLINE  

TailChao

    Moonsweeper

  • 405 posts
  • Bup?
  • 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 MrRetroGamer OFFLINE  

MrRetroGamer

    River Patroller

  • 2,386 posts
  • 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 Blackbird OFFLINE  

Blackbird

    Chopper Commander

  • 135 posts

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/~...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 MrRetroGamer OFFLINE  

MrRetroGamer

    River Patroller

  • 2,386 posts
  • Location:NYC, NY

Posted Tue Apr 27, 2004 2:26 PM

Anyone have any success with this yet? :)

#5 Blackbird OFFLINE  

Blackbird

    Chopper Commander

  • 135 posts

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 MrRetroGamer OFFLINE  

MrRetroGamer

    River Patroller

  • 2,386 posts
  • 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 Tempest OFFLINE  

Tempest

    Monochrome Martinet

  • 25,666 posts
  • Location:Accardi-By-The-Sea

Posted Tue Apr 27, 2004 8:45 PM

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


And that EE was?

Tempest

#8 Bryan ONLINE  

Bryan

    Quadrunner

  • 10,309 posts
  • Cruise Elroy = 4DB7
  • Location:Coming Soon to Michigan!

Posted Tue Apr 27, 2004 9:33 PM

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 ubersaurus ONLINE  

ubersaurus

    River Patroller

  • 4,926 posts
  • Location:Maryland

Posted Wed Apr 28, 2004 12:34 AM

Where are these roms at , for that matter?

#10 MrRetroGamer OFFLINE  

MrRetroGamer

    River Patroller

  • 2,386 posts
  • 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):

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:

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

  • chan0002.jpg


#11 Blackbird OFFLINE  

Blackbird

    Chopper Commander

  • 135 posts

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 ubersaurus ONLINE  

ubersaurus

    River Patroller

  • 4,926 posts
  • Location:Maryland

Posted Wed Apr 28, 2004 5:29 PM

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

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:

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 MrRetroGamer OFFLINE  

MrRetroGamer

    River Patroller

  • 2,386 posts
  • 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

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 Thomas Jentzsch OFFLINE  

Thomas Jentzsch

    Thrust, Jammed, SWOOPS!, Boulder Dash, THREE·S, Star Castle

  • 22,106 posts
  • Always left from right here!
  • Location:Düsseldorf, Germany

Posted Sat May 1, 2004 1:19 AM

Thanks! :thumbsup:

#15 EmOneGarand OFFLINE  

EmOneGarand

    Dragonstomper

  • 880 posts
  • 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 EmOneGarand OFFLINE  

EmOneGarand

    Dragonstomper

  • 880 posts
  • Location:Pennsylvania

Posted Fri Jul 13, 2007 1: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.

Fixed it, now onto figuring out controls and adding enemy sprites... wish there were more resources.

#17 e5frog ONLINE  

e5frog

    Dragonstomper

  • 736 posts
  • Good.
  • Location:Sweden

Posted Wed Aug 8, 2007 12:35 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.

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 EmOneGarand OFFLINE  

EmOneGarand

    Dragonstomper

  • 880 posts
  • Location:Pennsylvania

Posted Wed Aug 8, 2007 1:31 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.

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 e5frog ONLINE  

e5frog

    Dragonstomper

  • 736 posts
  • Good.
  • Location:Sweden

Posted Wed Aug 8, 2007 2:24 PM

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 EmOneGarand OFFLINE  

EmOneGarand

    Dragonstomper

  • 880 posts
  • Location:Pennsylvania

Posted Wed Aug 8, 2007 9:47 PM

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 e5frog ONLINE  

e5frog

    Dragonstomper

  • 736 posts
  • Good.
  • Location:Sweden

Posted Thu Aug 9, 2007 2:45 AM

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 e5frog ONLINE  

e5frog

    Dragonstomper

  • 736 posts
  • Good.
  • Location:Sweden

Posted Thu Aug 9, 2007 7:07 AM

First thing I noticed was this:

[codebox]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[/codebox]

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:

[codebox]; 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[/codebox]

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 e5frog ONLINE  

e5frog

    Dragonstomper

  • 736 posts
  • Good.
  • 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 e5frog ONLINE  

e5frog

    Dragonstomper

  • 736 posts
  • Good.
  • 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. ;-)


[codebox];-------------------------;
;=========================;
; 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[/codebox]



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 e5frog ONLINE  

e5frog

    Dragonstomper

  • 736 posts
  • Good.
  • 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. ;-)




0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users