Nukey Shay Posted February 26, 2017 Share Posted February 26, 2017 (edited) Not "for some reason"...wasting 33 cycles pushed the enable/disable code to the non-visible portion of the next scanline (which will become a problem if sprites need to be drawn on the same scanline). As mentioned before, you can prepare some of the conditions beforehand. Stuff like reading the console switches within the kernel to use different colors takes up valuable time you need to actually draw the screen. If conditions absolutely need to be checked per scanline (such as a missile enable), that too can be checked using free cycles from a previous scanline, and then called later from temp ram. Just like what was done with COLUP0. . sta WSYNC stx GRP0 ;3 sta GRP1 ;6 lda $88 ;9 sta COLUP0 ;12 lda $A9 ;15 cpy $A8 ;18 beq DrawM1 ;20 lda #0 ;22 DrawM1: ;21 sta ENAM1 ;24-25 The visible portion of the screen begins at cycle 22...so that code will produce a crooked missile if it is on the far left. . lda $A9 ; cpy $A8 ; beq DrawM1 ; lda #0 ; DrawM1: sta Temp ; sta WSYNC stx GRP0 ;3 sta GRP1 ;6 lda $88 ;9 sta COLUP0 ;12 lda Temp ;15 sta ENAM1 ;18 Cycle 18 is just fine. You'll still need to fill in the missing cycle times for the code leading up to the WSYNC to make sure you don't go over 73 (or 76 if you use cycle-exact branching to skip using WSYNC). Since you are using A for GRP1, that code will need to go between storing Temp and WSYNC. But there usually is not time to be throwing all your stuff in temp ram for later. That is where the vertical delay registers become useful. By enabling them, sprites stored to one register will not be updated onscreen until sprites from the other register is written to. So then it won't matter what cycle you write the delayed sprites, the change won't be onscreen immediately. Edited February 26, 2017 by Nukey Shay Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted February 26, 2017 Share Posted February 26, 2017 "Sleep 33" worked for some reason Space Saving Tip Sleep uses a NOP instruction which takes 1 byte of ROM for every 2 cycles of sleep. If you have an odd number of cycles then the first NOP will be changed to NOP 0 which takes 2 bytes of ROM for 3 cycles of sleep. So sleep#/2 rounded up will be how many bytes of ROM you're using, thus 33/2 = 16.5 = 17 bytes rounded up: SLEEP 33 ;33 33 - 17 bytes You may or may not have noticed the Sleep12: RTS at the end of PosObject. What that's for is so you can do a sleep for 12 cycles using just 3 bytes of ROM instead of 6. So change your program to: jsr Sleep12 ;12 12 - 3 bytes jsr Sleep12 ;12 24 - 3 bytes SLEEP 9 ; 9 33 - 5 bytes And you'll get the same 33 cycles of sleep in just 11 bytes. Another sleep trick is if you have extra RAM (or a temp value that's not currently in use) you can define one of them like this: SEG.U vars ORG $80 ; your RAM usage here Sleep5: ds 1 Then you can do a sleep of 5 cycles in 2 bytes instead of 3 by using a DEC or INC instruction: jsr Sleep12 ;12 12 - 3 bytes jsr Sleep12 ;12 24 - 3 bytes dec Sleep5 ; 5 29 - 2 bytes SLEEP 4 ; 4 33 - 2 bytes So now we're down to 10 bytes from the original 17 for the same 33 cycles of sleep. The labels of Sleep5, Sleep12, and macro name of SLEEP were all chosen to make the program Self Documenting. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 26, 2017 Share Posted February 26, 2017 You don't need spare ram for INC or DEC to waste 5 cycles...addresses $2D, $2E, or $2F are all sufficient. No actual RAM mapped here, but the N and Z flags *will* be cleared. NOP 0 always struck me as odd (pardon the pun), since storing a register to any of those 3 addresses accomplishes the same 3-cycle waste without resorting to "illegal" opcodes. The JSR/RTS to waste 12 is a problem if you have no spare stack RAM or currently using the stack pointer. On the subject of the latter, it's a good cycle-saving method to enable/disable missiles and the ball by setting the stack pointer beforehand: . ldx #ENABL ;2 txs ;2 cpy BallY ;3 php ;3 cpy Missile1Y ;3 php ;3 cpy Missile0Y ;3 php ;3All 3 conditionally displayed in 22 cycles. Don't forget to reset the stack pointer if your program needs it later. Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted February 27, 2017 Author Share Posted February 27, 2017 Today's goal met: Recognizing collisions. I think this was easy in part because when you fire a missile it never touches you, it always starts out below you. That way, it never touches you. Not deliberate, but works nonetheless. This was a simple test to see if I could get collisions between missile1 (pencil) and player1 (waffle). At first it wanted to ignore the code, but as I worked more on it, I got it to actually recognize it. If you shoot the waffle, the y position of it changes to a new position. Part of what I wanted it to do. What I would like it to do is come at you randomly from either the right side or left side of the screen at a random y position. Also, I would like to recognize the collisions between players so if a waffle touches Francis, you lose a life. But I haven't got that far yet. fice20170226.zip Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted February 27, 2017 Author Share Posted February 27, 2017 I'm now wondering whether I should continue work on this. I got lives and waiting a few seconds before pressing fire to start after a life has been lost, but it feels like just an inferior version of Defender. I have 700 bytes left, so I can add stuff, but what can I do to make it different? fice20170227.zip Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted March 13, 2017 Author Share Posted March 13, 2017 Help time. I want to make it so the player doesn't automatically fire his missile at the beginning. I've tried reading various things like the Stella Programmer's Guide, which told me in order to disable INPT4 to write a 1 to bit 6 of VSYNC. I tried adding 64 to the VSYNC total (it was 48). I looked through various games at the miniDig site. I can't figure out how to stop the missile from going off once the player presses fire to begin a game. I've cleaned up my code a little bit so perhaps someone can tell me what to do here? fice20.asm Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted March 14, 2017 Author Share Posted March 14, 2017 I think I figured it out. Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted March 14, 2017 Author Share Posted March 14, 2017 What I did was made a variable called EnableFire which sets whether or not the program allows firing. Another INPT4 check happens to check whether or not EnableFire is 1 or 0. fice20170313.zip Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted March 15, 2017 Author Share Posted March 15, 2017 A short video I made on YouTube. Sorry about the video quality, it was the only way to do it involving a real TV set. Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted April 9, 2017 Author Share Posted April 9, 2017 Added reset switch support. I have about 300 bytes left. I couldn't do this to Cellar-y Celery because without it it had 1 byte left to the game! fice20170409.zip 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.