vidak Posted January 4, 2018 Share Posted January 4, 2018 This is amazing. I am learning so much from hanging around on these forums. Happy New Year everyone. Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted January 4, 2018 Share Posted January 4, 2018 Another thing that'll free up cycles, at the expense of ROM, is to eliminate the branch by unrolling the loop. Instead of this (assuming the digits are 8 scanlines in height): ldy #7 ScoreKernel: ... 48 pixel logic dey bpl ScoreKernel you'd do this: ldy #7 ... 48 pixel logic dey ... 48 pixel logic dey ... 48 pixel logic dey ... 48 pixel logic dey ... 48 pixel logic dey ... 48 pixel logic dey ... 48 pixel logic dey ... 48 pixel logic Easier way to do that is via a macro: MAC SCOREKERNEL .line SET {1} if .line = 7 ldy #7 endif ... 48 pixel logic if .line > 0 dey endif ENDM then use the macro like this to draw the 8 scanlines: SCOREKERNEL 7 SCOREKERNEL 6 SCOREKERNEL 5 SCOREKERNEL 4 SCOREKERNEL 3 SCOREKERNEL 2 SCOREKERNEL 1 SCOREKERNEL 0 Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted January 4, 2018 Share Posted January 4, 2018 Unrolling the loop would also free up some cycles during the loads because you'd no longer need an indexed load. Just hardcode the ZP address for each load. Honestly, I don't see how this would work without unrolling. Even if you don't use Y for loop maintenance don't you still need it for the indexed loads and that means extra overhead to deal with Y being used for two different things each scan line. Of course, there's always bus stuffing. PM me if you ever want to switch over to the dark side. 3 Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted January 4, 2018 Author Share Posted January 4, 2018 (edited) Thanks, I am trying to avoid an unrolled kernel if possible. As for using Y for indexing, I have some ideas, such as loading Y with INTIM and using TIM64T to load the timer. This would restore Y and handle the loop in 6 cycles, and if I preload Y initially, I should be able to draw a maximum of 7 scanlines. Another option is to simply pull the graphics from the stack, which doesn't need an index. However, this would make it very hard to use the stack pointer for an extra register. Edited January 4, 2018 by JeremiahK Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted January 4, 2018 Share Posted January 4, 2018 What I'm really try to point out is that you have to use Y as the index to load the value for Y into a non indexed location before loading it into Y. In other words you can't do ldy DigitY,y. The tay instruction is no good either, because then you've lost your value for A and you can't load it after you stomp on the index value in Y. Using the stack is even worse because now you've got to deal with the values for X and SP. Instead you must do this which costs 6 more cycles. ; TODO Restore Y with index lda DigitY,y sta DigitYTemp ; TODO Pre load A, X, SP, GRP0, GRP1 etc. ldy Digit0Temp Maybe someone has a clever solution for this, but I haven't thought of a good one yet. 8 grp updates using ld? zp,y and sta zp is (4+3)*8= 56 cycles 2 nusiz1 updates using lda # sta zp is (2+3)*2 = 10cycles restoring Y index is at least ldy ZP = 3 cycles branch taken for loop = 3 cycles Providing the above calculations are correct 72 cycles are already used leaving just 4 more to deal with the ldy zp,y problem. 1 Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted January 4, 2018 Author Share Posted January 4, 2018 (edited) So after a lot of playing around with code, this is the best I have come up with that allows 7-bit-wide number digits. I am 99% sure this will work, but I have another method that only allows 6-bit-wide digits just in case (using VDEL on only P0). Fingers crossed! Edit: Scratch that, I miscalculated the timing on some of the instructions, marked with ***. Looks like you are correct, ZackAttack, I only have 4 cycles to work with for the loop handling here. ; set TIM64T so it will decrement properly from 5-0 during kernel ldy #6 ; 2 66 inital state of Y Board lda #3 ; 2 68 sta NUSIZ1 ; 3 71 set NUSIZ1 for score ldx Lvl,y ; 4 75 txs ; 2 01 LevelDigit->S lda Scr1,y ; 4 05 sta GRP0 ; 3 08 ScoreDigit1->[GRP0] lda Scr2,y ; 4 12 sta GRP1 ; 2 14 ScoreDigit2->[GRP1] / ScoreDigit1->GRP0 *** lda Scr3,y ; 4 18 sta GRP0 ; 2 20 ScoreDigit3->[GRP0] / ScoreDigit2->GRP1 *** ldx Scr4,y ; 4 24 ScoreDigit4->X lda Scr5,y ; 4 28 sta Temp ; 3 31 ScoreDigit5->Temp lda Scr6,y ; 4 35 ScoreDigit6->A ldy Temp ; 3 38 ScoreDigit5->Y stx GRP1 ; 3 41 ScoreDigit4->[GRP1] / ScoreDigit3->GRP0 sty GRP0 ; 3 44 ScoreDigit5->[GRP0] / ScoreDigit4->GRP1 sta GRP1 ; 3 47 ScoreDigit6->[GRP1] / ScoreDigit5->GRP0 tsx ; 2 49 stx GRP1 ; 3 52 LevelDigit->[GRP1] / ScoreDigit6->GRP1 stx GRP1 ; 3 55 LevelDigit->GRP1 lda #4 ; 2 57 sta NUSIZ1 ; 3 60 set NUSIZ1 for level digit ldy INTIM ; 3 63 !!! prepares Y index for the next line !!! bne Board ; 3 66 Edited January 4, 2018 by JeremiahK Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted January 4, 2018 Share Posted January 4, 2018 What you already have working is already impressive. One other idea could be to use non numeric glyphs for the level indicator. Then it doesn't have to look the same as the score and they could be customized to work well with what's available. Perhaps it would add a little more charm to the game? Otherwise, unroll the loop, use a more powerful bank scheme such as 3E, use harmony hardware with ARM co processing, or just leave well enough alone. Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted January 4, 2018 Author Share Posted January 4, 2018 (edited) What I'm really try to point out is that you have to use Y as the index to load the value for Y into a non indexed location before loading it into Y. In other words you can't do ldy DigitY,y. The tay instruction is no good either, because then you've lost your value for A and you can't load it after you stomp on the index value in Y. Using the stack is even worse because now you've got to deal with the values for X and SP. Exactly. Although if I used X as the index instead of Y, I could interact with the stack more easily. I'll have to look into that, maybe there's something there... Ah, never mind. Then I would run into the problem of loading X, since I couldn't do ldx Digit,x What you already have working is already impressive. One other idea could be to use non numeric glyphs for the level indicator. Then it doesn't have to look the same as the score and they could be customized to work well with what's available. Perhaps it would add a little more charm to the game? Otherwise, unroll the loop, use a more powerful bank scheme such as 3E, use harmony hardware with ARM co processing, or just leave well enough alone. I'm OK with sticking with the kernel I have, or doing other graphics than numbers to indicate the level. I just want to see if I can push the hardware to the edge. Edited January 4, 2018 by JeremiahK Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted January 4, 2018 Share Posted January 4, 2018 I just want to see if confirm I can pushed the hardware to the edge. There, I fixed it for you. 1 Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted January 5, 2018 Share Posted January 5, 2018 So after a lot of playing around with code, this is the best I have come up with that allows 7-bit-wide number digits. I am 99% sure this will work, but I have another method that only allows 6-bit-wide digits just in case (using VDEL on only P0). Fingers crossed! Edit: Scratch that, I miscalculated the timing on some of the instructions, marked with ***. Looks like you are correct, ZackAttack, I only have 4 cycles to work with for the loop handling here. ; set TIM64T so it will decrement properly from 5-0 during kernel ldy #6 ; 2 66 inital state of Y Board lda #3 ; 2 68 sta NUSIZ1 ; 3 71 set NUSIZ1 for score ldx Lvl,y ; 4 75 txs ; 2 01 LevelDigit->S lda Scr1,y ; 4 05 sta GRP0 ; 3 08 ScoreDigit1->[GRP0] lda Scr2,y ; 4 12 sta GRP1 ; 2 14 ScoreDigit2->[GRP1] / ScoreDigit1->GRP0 *** lda Scr3,y ; 4 18 sta GRP0 ; 2 20 ScoreDigit3->[GRP0] / ScoreDigit2->GRP1 *** ldx Scr4,y ; 4 24 ScoreDigit4->X lda Scr5,y ; 4 28 sta Temp ; 3 31 ScoreDigit5->Temp lda Scr6,y ; 4 35 ScoreDigit6->A ldy Temp ; 3 38 ScoreDigit5->Y stx GRP1 ; 3 41 ScoreDigit4->[GRP1] / ScoreDigit3->GRP0 sty GRP0 ; 3 44 ScoreDigit5->[GRP0] / ScoreDigit4->GRP1 sta GRP1 ; 3 47 ScoreDigit6->[GRP1] / ScoreDigit5->GRP0 tsx ; 2 49 stx GRP1 ; 3 52 LevelDigit->[GRP1] / ScoreDigit6->GRP1 stx GRP1 ; 3 55 LevelDigit->GRP1 lda #4 ; 2 57 sta NUSIZ1 ; 3 60 set NUSIZ1 for level digit ldy INTIM ; 3 63 !!! prepares Y index for the next line !!! bne Board ; 3 66 I haven't read the whole thread, so I'm kinda jumping in the middle here. Years ago I did a 7 full size digit display (with a little trickery). You can see it here. I'm glad to see you're using INTIM for your loop counter. I have used TIM8T before, but TIM64T also works well. If you are doing a six digit score with another digit (or two) for the lives/level then consider putting the score on the far right and use then extend the spacing with NUSIZx to wrap it around. wrapping around the screen that way gives a very wide spacing. Here are some examples: 2 Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted January 5, 2018 Author Share Posted January 5, 2018 (edited) Thanks, I think I will wrap it around the screen. I had considered it, but I thought it would look funny. Edited January 5, 2018 by JeremiahK Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted January 8, 2018 Author Share Posted January 8, 2018 (edited) Here's the new scoreboard! I also fixed the height of the cat, so it looks exactly like my early plan. nyancat.bin Edited January 8, 2018 by JeremiahK 8 Quote Link to comment Share on other sites More sharing options...
Jinroh Posted January 9, 2018 Share Posted January 9, 2018 Awesome man that looks so rad! <3 You're really mastering the hardware! 1 Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted January 10, 2018 Author Share Posted January 10, 2018 Thank you! Now it's on to the game mechanics, that might take a while... 1 Quote Link to comment Share on other sites More sharing options...
Mountain King Posted January 11, 2018 Share Posted January 11, 2018 This game looks great. 1 Quote Link to comment Share on other sites More sharing options...
Jinroh Posted January 12, 2018 Share Posted January 12, 2018 Thank you! Now it's on to the game mechanics, that might take a while... Yes that's the other half of the battle. ^^ You've a lot of fun things going on so I don't think you'll have a lot of trouble, you're awesome. Carrot Kingdom I'm having most trouble with the design. The kernel, technical things were cake, but I'm not a super great designer. 1 Quote Link to comment Share on other sites More sharing options...
Coolcrab Posted January 17, 2018 Share Posted January 17, 2018 Could you post some screenshots? I can't play games at work unfortunately I'll try the bin asap Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted January 30, 2018 Author Share Posted January 30, 2018 (edited) I have been busy of late trying to apply for my 2nd job so I can get a steady income (I am 21, in case you don't have time to read everybody's profiles) I am glad to say that after almost 11 months since my last job, I now have a new job. I start on the 5th, the day after my Eagles get to play in the Superbowl. Anyways, I decided to put in some more time on this game, and I made a commit for the first time in a couple weeks. It was a small change, just an optimization, but I hope to tackle some bigger issues this week, hopefully working on the controls and food generation. I am planning on supporting both joystick and paddle control. Since the paddles should only need to be read 7 times, I should be able to do that without sacrificing too much game logic space. I have decided to skip the idea of using flicker to have up to 4 food items per row, because the 64-pixel NUSIZ spacing of the objects combined with the 160-pixel display will make it pretty much impossible to make that work well in reality. Instead, there will normally be 2 items per row, with no flicker, except for when the 3rd item needs to spawn. In that case, the center item will not flicker, but the others will for a short time. Oh, and here's the screenshot you asked for over a week ago. I tried to post it before, but I guess it didn't work. Edited January 30, 2018 by JeremiahK 8 Quote Link to comment Share on other sites More sharing options...
vidak Posted January 31, 2018 Share Posted January 31, 2018 It looks amazing. You are 100x the programmer I am. 1 Quote Link to comment Share on other sites More sharing options...
Coolcrab Posted January 31, 2018 Share Posted January 31, 2018 The screenshot looks cool! The game doesn't seem to work on http://javatari.orgthough. Strange. I'll try it on stella when at home. Quote Link to comment Share on other sites More sharing options...
DirtyHairy Posted February 1, 2018 Share Posted February 1, 2018 The screenshot looks cool! The game doesn't seem to work on http://javatari.orgthough. Strange. I'll try it on stella when at home. Give it a spin on https://6502ts.github.io/stellerator--- it works fine there (I should add that it works for me on javatari, too). Quote Link to comment Share on other sites More sharing options...
+Karl G Posted April 2, 2018 Share Posted April 2, 2018 I'm curious on how this project is progressing. I know my 12 year old will freak out at the idea of such a game when it is completed. 1 Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted April 2, 2018 Author Share Posted April 2, 2018 (edited) Glad to know that kids will love the game! Unfortunately, I have not done much, if anything, in the past 2 months. Before, I was unemployed, so I had all the time in the world. Now I thankfully have a job, and since today is my first time having two days off in a row, I am trying to get back into the swing of things. It has given me some time to think about how I want to address different issues, and fix a couple of minor inconsistency flaws in the kernel. I have the important code for the controls done, I just need to connect it to the joystick (and paddle later). Next up is working on the object generation, which will take some time, since I want it to be simple yet flexible to make it easier to implement levels later. Edited April 2, 2018 by JeremiahK 1 Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted April 2, 2018 Author Share Posted April 2, 2018 All right, did a quick-and-simple joystick update. Currently, holding the joystick up or down will make the cat move quickly until it hits the top or bottom row, making it a little hard to just flick through one row at a time. I intend on making it so you need to move one row at a time, returning the joystick to center after each move, unless you hold the fire button, which would function as it is now. Not sure how this is best implemented, but I'll figure it out. nyancat.bin 1 Quote Link to comment Share on other sites More sharing options...
vidak Posted April 3, 2018 Share Posted April 3, 2018 You'll figure it out! What I'd do is use a bit in memory to test if the controller has moved from up or down to centre. So you'd have IF (SavedX = 1) AND (CurrentX = 0) THEN ... 1 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.