TailChao Posted February 27, 2004 Share Posted February 27, 2004 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.... Quote Link to comment Share on other sites More sharing options...
MrRetroGamer Posted February 27, 2004 Share Posted February 27, 2004 Here is some info on the F8: http://www.antiquetech.com/chips/fairchild_f8.htm or you may be able to get something from here: http://www.fairchildsemi.com/ Either way - good luck! Quote Link to comment Share on other sites More sharing options...
Blackbird Posted March 23, 2004 Share Posted March 23, 2004 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/~lturner/public_html/F8_ins.html Don't have a clue about the system itself. Try looking at some MESS source. Quote Link to comment Share on other sites More sharing options...
MrRetroGamer Posted April 27, 2004 Share Posted April 27, 2004 Anyone have any success with this yet? Quote Link to comment Share on other sites More sharing options...
Blackbird Posted April 27, 2004 Share Posted April 27, 2004 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. Quote Link to comment Share on other sites More sharing options...
MrRetroGamer Posted April 28, 2004 Share Posted April 28, 2004 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.com/s660100106/competition/ Quote Link to comment Share on other sites More sharing options...
Tempest Posted April 28, 2004 Share Posted April 28, 2004 During this process, an easter egg was found in Videocart #20. And that EE was? Tempest Quote Link to comment Share on other sites More sharing options...
Bryan Posted April 28, 2004 Share Posted April 28, 2004 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 Quote Link to comment Share on other sites More sharing options...
ubersaurus Posted April 28, 2004 Share Posted April 28, 2004 Where are these roms at , for that matter? Quote Link to comment Share on other sites More sharing options...
MrRetroGamer Posted April 28, 2004 Share Posted April 28, 2004 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. Quote Link to comment Share on other sites More sharing options...
Blackbird Posted April 28, 2004 Share Posted April 28, 2004 Do you happen to know who, or at least where you saw that someone had made progress in programming for the system? Quote Link to comment Share on other sites More sharing options...
ubersaurus Posted April 28, 2004 Share Posted April 28, 2004 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 Quote Link to comment Share on other sites More sharing options...
MrRetroGamer Posted April 30, 2004 Share Posted April 30, 2004 Sorry for the delay in getting back to everyone, I was having trouble setting up my FTP account on my new domain. 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! 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.net/seanriddle/chanf.html Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted May 1, 2004 Share Posted May 1, 2004 Thanks! Quote Link to comment Share on other sites More sharing options...
EmOneGarand Posted July 13, 2007 Share Posted July 13, 2007 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. Quote Link to comment Share on other sites More sharing options...
EmOneGarand Posted July 13, 2007 Share Posted July 13, 2007 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. Quote Link to comment Share on other sites More sharing options...
e5frog Posted August 8, 2007 Share Posted August 8, 2007 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 Quote Link to comment Share on other sites More sharing options...
EmOneGarand Posted August 8, 2007 Share Posted August 8, 2007 (edited) 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. mycfgame.bmp Edited August 8, 2007 by EmOneGarand Quote Link to comment Share on other sites More sharing options...
e5frog Posted August 8, 2007 Share Posted August 8, 2007 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 Quote Link to comment Share on other sites More sharing options...
EmOneGarand Posted August 9, 2007 Share Posted August 9, 2007 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) mattscfgame.zip Quote Link to comment Share on other sites More sharing options...
e5frog Posted August 9, 2007 Share Posted August 9, 2007 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 Quote Link to comment Share on other sites More sharing options...
e5frog Posted August 9, 2007 Share Posted August 9, 2007 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. Quote Link to comment Share on other sites More sharing options...
e5frog Posted August 10, 2007 Share Posted August 10, 2007 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. Quote Link to comment Share on other sites More sharing options...
e5frog Posted August 10, 2007 Share Posted August 10, 2007 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. Quote Link to comment Share on other sites More sharing options...
e5frog Posted August 10, 2007 Share Posted August 10, 2007 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.