Jump to content
Posted Thu Nov 23, 2017 3:17 PM
Posted Fri Nov 24, 2017 11:23 PM
Using your suggestions, and adding a few more changes, I have come up with this plan for the kernel:
.KernelLoop ; 14 cycles to prepare rainbow colors lda RamBowGfx,y ; 4 sta COLUBK ; 3 lda RamBowGfx+1,y ; 4 sta COLUPF ; 3 ; 8 cycles to prepare cat face graphics lda (CatFaceGfx),y ; 5 sta GRP0 ; 3 ; 8 cycles to prepare tart graphics lda (TartGfxPtr),y ; 5 sta PF1 ; 3 ; 5 cycles to set tart color lda #COL_CAT_TART ; 2 (25) sta COLUPF ; 3 (28) MUST end on cycle 28 ; 6 cycles to clear PF/BK colors to black ; x is pre-loaded with 0, the color black stx COLUBK ; 3 (31) MUST end on cycle 31 stx COLUPF ; 3 (34) ; 14 cycles to prepare 1st food item graphics lda (FoodGfxPtr1),y ; 5 sta GRP1 ; 3 lda FoodColor1 ; 3 sta COLUP1 ; 3 ; 14 cycles to prepare 2nd food item graphics lda (FoodGfxPtr2),y ; 5 sta GRP1 ; 3 lda FoodColor2 ; 3 sta COLUP1 ; 3 ; 5 cycles to finish the loop dey ; 2 bne .KernelLoop ; 3 ; 74 cycles total, 2 to spare. Quite a tight squeeze!
This wouldn't draw the rear paws, but that is fine with me as long as everything else in intact. The pop-tart would be drawn with PF1.
Note that the background color will be changed from dark blue to black. This is neccesary, as it makes the face color the same as the background color. Also, it will help with the flickering food items, avoiding the classic yellow "ghost" effect from Atari's Pac-Man.
The 11 cycles for the tart color writing and PF/BK color resetting need to be perfectly aligned, but all the rest of the cycles can be re-arranged to allow the 3 kernel versions. Each version would write the food item graphics at different times, depending on where they are on the screen.
Edited by JeremiahK, Fri Nov 24, 2017 11:37 PM.
Posted Fri Nov 24, 2017 11:35 PM
Also, this example uses rainbow color graphics that are pre-loaded into RAM to save 1 cycle per read (2 reads). Since there are 2 cycles to spare, it may be possible to read from ROM instead (using pointers), using every cycle, as long as it is still possible to rearrange the writes to the food item graphics. This would be optimal for obvious reasons.
Edited by JeremiahK, Fri Nov 24, 2017 11:38 PM.
Posted Sat Nov 25, 2017 1:18 AM
Posted Sun Nov 26, 2017 11:25 PM
I have finished a working test demo of the kernel, and it can draw the cat and rainbow properly, along with food items. Note that the food items are not actually drawn correctly (they are both the same), but it is actually updating the graphics and color for player 1 twice per scanline. I just wanted to share this with you all.
Please keep in mind that this is not at all final. Ignore the crazy playfield bars and bland grey colors. Also, good luck if you try to look at the code (it's a mess right now). There is no engine controling the movement of the food items, their position is just set to modulus 64 of the frame count to show that they can move. I would have added a simple way to animate the rainbow, but it would need to be re-written anyway, so I didn't bother.
I also had some fun today making the food item graphics. There are 16 items total, one blank, six fruits (yummy items), six veggies (yucky items, health loss), two high point-value items, and a health item. The kernel currently flickers the food items so I could test the look on a real 2600, and they look pretty good if I do say so myself.
Posted Mon Dec 11, 2017 7:17 PM
You've got a bug in your code.
As a developer, you should always do this in Stella:
and you'll now be able to recreate the bug. Most likely what's up is somewhere in your code is an LDA $XX instruction that's supposed to be an LDA #$XX instruction.
Tracking down and fixing your bug should help you to understand why we suggested this to you in the past (there's some nice screenshots there showing exactly what to check)
Posted Tue Dec 12, 2017 12:51 AM
Thank you so much! I will look at that tomorrow. I remember you telling me about that before, and I thought I had done it, but I guess I forgot.
EDIT: Wow, I only had the box checked for "Randomize zero page/RAM".
Edited by JeremiahK, Tue Dec 12, 2017 10:47 AM.
Posted Tue Dec 12, 2017 11:57 AM
I am sifting through all the code, trying to find the bug.
I created a file to declare constants for the TIA values I am using that can be ORed together during assembly. This way, instead of having something confusing like this:
lda #%00010001 sta CTRLPF lda #%00010011 sta NUSIZ0 sta NUSIZ1
I can have something much easier to read, like this:
lda #BALL_SIZE_2 | PF_REFLECT sta CTRLPF lda #MSL_SIZE_2 | THREE_CLOSE sta NUSIZ0 sta NUSIZ1
Is this the correct syntax for doing this?
Posted Tue Dec 12, 2017 12:18 PM
If the problem is a load ZP in place of what was supposed to be a load # you could probably find it with a regex search pretty quickly. Something like ld[a-z] [^#]\d should find all the loads that are loading an arbitrary address instead of an immediate value. Of course this is assuming you've used labels for all your addresses and won't intentionally be doing lda $f000 instead of lda MyData.
It would be cool if you could configure dasm to error out when a load is attempted with a number instead of a label and it's not an immediate addressing mode.
Posted Tue Dec 12, 2017 12:28 PM
OK, so I just found the bug. In the rows before and after the cat's rows, I had temporarily set it up to draw 14 empty scanlines, but instead of loading Y with #14, I was loading it with 14, exactly as you suspected. This obviously screwed up the scanline count bigtime.
I'm just amazed that the code worked at all. The bug has been there for months. I had even been testing it on real hardware, and never had an issue. Thanks again for bringing this to my attention!
Edited by JeremiahK, Tue Dec 12, 2017 12:30 PM.
Posted Tue Dec 12, 2017 12:45 PM
Thanks. I love Stella's debugger, it actually helped me solve this problem. I noticed that the Y register was being set way too high in the "waste time and draw nothing" loop, so it was pretty obvious.
Posted Tue Dec 12, 2017 6:03 PM
Here's a new update. There are now two moving food items being drawn on each row, including the row with the cat. The row beneath the cat is blank, but ignore that for now.
Right now Player0's position is only being set once, before the first row. It will eventually be reset every row, making it possible to have each row's food items uniquely aligned.
I have discovered a strange issue, however. I am storing each row's food position in RAM as the number of color clocks to skip before drawing the first copy of the player. The position can be in the range of 0-88. This morning, it worked perfectly, so that a position of 0 would put the first player copy at the extreme left edge of the screen, while a position of 88 would do the opposite for the second player copy. Now, the player is shifted one color clock to the right for some reason. I can't imagine why this happened, as I didn't touch the player positioning code. I thought it might have been caused by a page boundary that moved, but I would expect a shift of 3 color clocks, not 1.
Edited by JeremiahK, Tue Dec 12, 2017 6:12 PM.
Posted Tue Dec 12, 2017 11:51 PM
I found out the answer to the timing bug. It turns out that there is a way for 1 CPU cycle to move a player by 1 color clock. I was using a cycle-73 HMOVE to avoid the comb lines, and it got bumped back to a cycle-72 HMOVE. Simple as that.
Posted Wed Dec 13, 2017 2:10 AM
It seems you don't set PF1 quite right the first line about half of the time. There's plenty of NOPs before that loop, so shouldn't be difficult to adjust I assume
Posted Wed Dec 13, 2017 6:38 PM
I have added player repositioning before every row, so now each one can have a unique food position and speed. I'm not doing anything fancy for the speeds right now, it's just a simple subtraction or shift from the previous row's position. It would be nice to have multiple row speeds as a game option, but if I want fine speed control, I will have to use more RAM.
I think I will take a break from adding features to the spaghetti dinner my code has become, and start optimizing it, managing pages, and otherwise cleaning it up. Code, polish, rinse, repeat.
Posted Wed Dec 13, 2017 7:22 PM
It would be nice to have multiple row speeds as a game option, but if I want fine speed control, I will have to use more RAM.
You can pull off 8 speeds by using superfluous bits within your pointers. Per your source you're using $F000 as the start of your cartridge. If one of your pieces of graphic data were to be located at say $F456, then due to how the Atari's designed these 8 values all point to that same image:
This is known as mirrored memory, and it's not just the ROM that's mirrored - everything in the 2600 shows up in multiple locations. Kroko posted some handy files in this topic.
If you look at those values in binary you'll see them as:
and can see that the upper 3 bits are unique, while the rest are all the same. So you can use those upper 3 bits to select from 8 different speeds and not need any extra RAM.
To retrieve the speed you'd do this:
lda FoodGfxPtr1+1 ; get the high-byte of pointer lsr ; 5 bit shifts right lsr lsr lsr lsr ; at this point A has the value of 0-7
If you want to set the speed to 2, you'd do this:
lda FoodGfxPtr1+1 ; get the high-byte of pointer and #%00011111 ; remove the current speed sta FoodGfxPtr1+1 ; save the graphic pointer (lower 5 bits) lda #2 ; set speed to 2 asl ; 5 bit shifts left asl asl asl asl ora FoodGfxPtr1+1 ; merge the speed (upper 3 bits of the accumulator) with the graphic pointer (lower 5 bits of RAM) sta FoodGfxPtr1+1 ; and save
Posted Wed Dec 13, 2017 7:26 PM
Why wouldn't you just load #2 << 5?
Posted Wed Dec 13, 2017 7:50 PM
Why wouldn't you just load #2 << 5?
lda FoodGfxPtr1+1 ; get the high-byte of pointer and #%00011111 ; remove the current speed sta FoodGfxPtr1+1 ; save the graphic pointer (lower 5 bits) lda #2 << 5 ; set speed to 2 (DASM shifts it to upper 3 bits at compile time) ora FoodGfxPtr1+1 ; merge the speed (upper 3 bits of the accumulator) with the graphic pointer (lower 5 bits of RAM) sta FoodGfxPtr1+1 ; and save
clc lda FoodGfxPtr1+1 adc #%00100000 sta FoodGfxPtr1+1
sec lda FoodGfxPtr1+1 sbc #%00100000 sta FoodGfxPtr1+1
Posted Wed Dec 13, 2017 7:53 PM
Gotcha, could be confusing for newer programmers, is all.
Atari Systems →
Atari 2600 →
Gaming General →
Classic Gaming General →
Intellivision / Aquarius →
Atari Systems →
Atari 7800 →
Game Programming →
Homebrew Discussion →
0 members, 0 guests, 0 anonymous users