antron Posted June 18, 2005 Share Posted June 18, 2005 (edited) It is for a smooth scrolling horizontal platformer. A man (player) is made up of both player graphics side by side centered in the exact center of the screen. New player graphics are filled in every other scanline. A missle is on the right and a missle is on the left. One missle is the monster, one is a wall. The playfield is displayed every other scanline. The wall is also displayed every other scanline. The wall is used as a buffer to make the playfield look like it is scrolling horizontally one pixel at a time. The wall can change its position every other scanline, but only by the value that is in the memory location 'wallshft'. This can be used when the playfield staggers, or wants to incline. The monster can be enabled and change its size and/or position every other scanline. The ball can be enabled and change its position every other scanline. The kernel provided is for the situation when the monster is on the left and the wall is on the right. But notice that the monster can be on the right provided that it is past 6502 cycle 54. And the wall could be on the left provided that it is before cycle 45. I have a kernel for the reverse of all this too, but it is more trivial. RAM usage: 1 byte for the color of the monster. 1 byte for the color of the wall. 1 byte for the value that the wall can be shifted by 2 bytes for sizes and movements each time that you want to use this two scanline kernel 2 bytes for player graphics each time that you want to use this two scanline kernel 6 bytes for the playfield that is displayed when this kernel is used. I will have two versions of this kernel in a row. One that uses one set of playfield values, another that uses another 6 byte set. This way I can have the playfield stagger once while the man is being displayed. The wall will stagger with it with its hmove. The color of the man must be in the Y register. X register is the linecount. The two bytes for sizes and movements are used as such: mmisdata: bit usage 0 must be 0 (not used) 1 enable monster? 2,3 monster size bits 4,5,6,7 monster hmove nibble mlinedata bit usage 0 is it time to end this kernal? 1 enable ball? 2 enable wall? 3 shift wall by the value in shftwall? 4,5,6,7 ball hmove nibble MK1 lda mmisdata,x;4 70 load A with next monster data sta HMM1 ;3 73 prepare to move monster next line sta ENAM1 ;3 76 sta HMOVE ;3 3 asl ;2 5 get monster size bits in position asl ;2 sta NUSIZ1 ;3 10 set monster size for this line inx ;2 x needs to be incremented and inx fit here txs ;2 14 store linecount in S so X can be used later lda #0 ;2 sta ENAM0 ;3 clear missle 0 (right) for this line sta PF0 ;3 22 clear PF0 for this line sta PF1 ;3 clear PF 1for this line sta PF2 ;3 28 clear PF2 for this line lda manL-1,x;4 -1 because inx was called early sta GRP0 ;3 lda manR-1,x;4 sta GRP1 ;3 42 load both player graphics sty COLUP0 ;3 *45* color left side of man sty COLUP1 ;3 *48* color rt side of man lda m1col ;3 sta COLUP1 ;3 *54* recolor for monster on left side (or right side past here) lda pfm10L ;3 sta PF0 ;3 load first left playfield lda pfm11L ;3 sta PF1 ;3 66 load second left playfield lda mlinedata-1,x;4 70 get ball and wall parameters for next line sta HMBL ;3 75 sta ENAM0 ;3 2 enable wall (right side) lsr ;2 notice that bit 0 is in the carry! don't erase it! sta ENABL ;3 7 enable ball for this line and #%00000100;2 9 bne shftwl1 ;2(3) test if wall is shifted SLEEP 3 jmp noshft1 ;3 A is zero shftwl1 lda wallshft ;3 go get the walshift SLEEP 2 noshft1 sta HMM0 ;3 18 shift wall lda pfm12L ;3 sta PF2 ;3 24 load third left playfield lda pfm10R ;3 sta PF0 ;3 30 load first right playfield ldx m1col ;3 33 load monster (left) color early lda pfm11R ;3 sta PF1;3 load second right playfield lda m0col ;3 42 load wall (right) color early sty COLUP0 ;3 *45* recolor left side man sty COLUP1 ;3 *48* color rt side of man after lt man begins but b4 rt side does sta COLUP0 ;3 51 color missle on rt side after lt man ends but b4 rt side of man ends stx COLUP1 ;3 *54* recolor for missle on left side (or right side past here) lda pfm12R ;3 sta PF2 ;3 60 load 3rd right pf tsx ;2 62 get our line counter back bcc MK1 ;2(3or4) time for next kernal? this kernel is written for 4 Edited June 21, 2005 by antron Quote Link to comment Share on other sites More sharing options...
antron Posted June 18, 2005 Author Share Posted June 18, 2005 (edited) The monster is the green. I am just changing its position once, but i could shift and change its size every other scanline. I realize that monster graphics will be limited. The wall is the purple, but would normally be the same color as the wall, for scrolling. The little man is the ball. It can only shift, not change size; parts of it are hiding behind the chair. It is being vertically delayed. The wall and monster can go very deep into the vehicle before they get its color. Usually by then you can get a collision. Edited June 18, 2005 by antron Quote Link to comment Share on other sites More sharing options...
+batari Posted June 18, 2005 Share Posted June 18, 2005 I'm working on a smooth side-scroller too, and I've found some of the same challenges (like the missile and player must share the same color ) Your kernel looks pretty tight, but I did see a place where you could free up 2 cycles using the BIT Absolute trick: bne shftwl1 ;2(3) test if wall is shifted SLEEP 3 jmp noshft1 ;3 00000100 is left in A shftwl1 lda wallshft ;3 go get the walshift SLEEP 2 noshft1 sta HMM0 ;3 18 shift ball could be changed to bne shftwl1 ;2(3) test if wall is shifted .byte 2C shftwl1 lda wallshft ;3 go get the walshift noshft1 sta HMM0 ;3 18 shift ball Though I could be wrong... Quote Link to comment Share on other sites More sharing options...
+batari Posted June 18, 2005 Share Posted June 18, 2005 Though I could be wrong... Yep, I'm wrong... you need to preserve the carry bit. I missed that. But change the .byte 2C to .byte AE (for LDX Abs) and it should work, since you load X after this before you use it again! Quote Link to comment Share on other sites More sharing options...
antron Posted June 18, 2005 Author Share Posted June 18, 2005 (edited) Wow. I didn't know that one. I never even thought about eating opcodes like that. So, would need to have zero out in some ROM location depending on where wallshft is located in RAM? also, my comment is wrong in the code you quoted. The A register was zero, obviously. Edited June 18, 2005 by antron Quote Link to comment Share on other sites More sharing options...
+batari Posted June 18, 2005 Share Posted June 18, 2005 Wow. I didn't know that one. I never even thought about eating opcodes like that. So, would need to have zero out in some ROM location depending on where wallshft is located in RAM? also, my comment is wrong in the code you quoted. The A register was zero, obviously. 876678[/snapback] No need to zero out anything... If you follow what the CPU is doing, when the bne wlshift1 is taken, the CPU sees LDA wallshft, if it's not taken, A remains zero and it sees LDX Absolute, and uses 6 cycles either way. It doesn't matter what gets loaded into X because you don't use X until you do LDX m1col below, which overwrites it anyway. Quote Link to comment Share on other sites More sharing options...
antron Posted June 18, 2005 Author Share Posted June 18, 2005 Yes, I see. Thanks again. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted June 18, 2005 Share Posted June 18, 2005 Yep, I'm wrong... you need to preserve the carry bit. BIT doesn't change the carry bit. Quote Link to comment Share on other sites More sharing options...
+batari Posted June 18, 2005 Share Posted June 18, 2005 (edited) Yep, I'm wrong... you need to preserve the carry bit. BIT doesn't change the carry bit. 876707[/snapback] Yes, you're right, my so called "correction" didn't correct anything ... so I was right the first time. I thought it put bit 6 into the carry, turns out that is the V flag. You can tell I don't use that crazy BIT instruction too often. Looks like either 2C or AE will work, though 2C is the "normal" way to do this trick. Edited June 18, 2005 by batari Quote Link to comment Share on other sites More sharing options...
antron Posted June 19, 2005 Author Share Posted June 19, 2005 The only improvement I would like to make is to have the monster data loaded from ROM. That requires indirect indexed addressing with Y, but my linecount is in X. If this loop is properly aligned the branch at the end is only 3 cycles, not 4. Using the 2 I free with the BIT gobble trick I have 3 to spare. If I make X the man color, and Y the line count I can: store the line count in RAM not S, 1 cycle load the line count from RAM not S, 1 cycle make an indirect indexed load, not an indexed, for the monster data, 1 cycle so it fits. but it is not clear to me how it could be arranged with my other timing requirements (the ones in asterisks) i think i need to get the three cycles together. Quote Link to comment Share on other sites More sharing options...
vdub_bobby Posted June 23, 2005 Share Posted June 23, 2005 I'm working on a smooth side-scroller too, and I've found some of the same challenges (like the missile and player must share the same color ) I was also working on a side-scroller; don't know if you guys saw it at the time. I stopped work on it when I ran into a couple of hurdles, though I am considering picking it up again. The challenge of a 2600 side-scroller was irresistable to me! And to others, too, I guess. Quote Link to comment Share on other sites More sharing options...
Cybergoth Posted June 23, 2005 Share Posted June 23, 2005 Hi there! The challenge of a 2600 side-scroller was irresistable to me! And to others, too, I guess. 879657[/snapback] Every once in a while I think about Ghosts'n'Goblins 2600. If allowed 30Hz flicker on everything, one could do an amazing 2600 conversion job here. Greetings, Manuel Quote Link to comment Share on other sites More sharing options...
Jacob Rose Posted July 6, 2005 Share Posted July 6, 2005 876625[/snapback] Using the ball to build the man character this way is really clever! It reads perfectly, too - when I saw it, I was like, "cool, a little guy riding inside a wheel." Nice work! 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.