kisrael Posted January 23, 2021 Share Posted January 23, 2021 I was toying around trying to make a clock in bB (see below for the old font I was going to use) and realized I was running out of time (ironically). I guess I could try doinking around with vblank but as I was thinking about optimizations, I started trying to visualize what bB was doing for player graphics... (basically I started thinking, wait, why wouldn't a tall player take up all the ram) - I guess when you set player0: that's setting a pointer into the definition of ROM that the kernel then reads... anway, I'm still not sure if the Playfield clock I was thinking of is going to be feasible (I was thinking about making it a sidebar inside another animation) setting "that many" pixels adds up! Quote Link to comment Share on other sites More sharing options...
bogax Posted January 23, 2021 Share Posted January 23, 2021 (edited) I don't think you're describing what you want very well Here's a 2 digit count down timer that uses player0 in RAM Pressing joy0fire resets the counter to 100 and it proceeds to count down by seconds to 00 You could put the numbers in ROM and it would be faster and save the four variables it uses It would be 400 bytes of ROM for 100 numbers dim time = t.s dim d0 = temp2 dim d1 = temp3 COLUPF = $2C player0x = 80 : player0y = 44 player0height = 4 player0pointerlo = $EA : player0pointerhi = $00 ; set player0pointer to point to variable w COLUP0 = $1C gosub update_player loop COLUP0 = $1C drawscreen if joy0fire && !f then t = 100 : s = 0 ; set time to 99 if joy0fire then f = 255 else f = 0 if !(t | s) then loop ; if time = 0 skip decremting the timer temp1 = time time = time - 0.017 ; decrement time by ~1/60 if time > 99 then t = 0 : s = 0 ; if underflow, set time to 0 if temp1 = time then loop ; if the decrement didn't change the integer part of time skip updating the display temp1 = time / 16 dec temp1 = (time & $0F) + 0 + dnib[temp1] ; convert to bcd gosub update_player goto loop update_player d0 = temp1 & 15 d1 = temp1 / 16 z = l0[d1] & $F0 : z = (l0[d0] & $0F) | z y = l1[d1] & $F0 : y = (l1[d0] & $0F) | y x = l2[d1] & $F0 : x = (l2[d0] & $0F) | x w = l3[d1] & $F0 : w = (l3[d0] & $0F) | w return data l0 $77, $22, $77, $77, $55, $77, $33, $77, $77, $77 end data l1 $55, $66, $33, $33, $77, $66, $66, $11, $77, $55 end data l2 $55, $22, $66, $11, $11, $11, $55, $22, $55, $33 end data l3 $77, $22, $77, $77, $11, $66, $77, $22, $77, $66 end data dnib $00, $16, $32, $48, $64, $80, $96 end count_down_timer.bas count_down_timer.bas.bin Edited January 23, 2021 by bogax goofed up the BCD conversion Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted January 23, 2021 Share Posted January 23, 2021 Is this related at all? randomterrain.com/atari-2600-memories-batari-basic-commands.html#akmme_racing_timer Quote Link to comment Share on other sites More sharing options...
+Karl G Posted January 24, 2021 Share Posted January 24, 2021 11 hours ago, kisrael said: I started trying to visualize what bB was doing for player graphics... (basically I started thinking, wait, why wouldn't a tall player take up all the ram) - I guess when you set player0: that's setting a pointer into the definition of ROM that the kernel then reads... Yeah, that is exactly how setting the players works under the hood. The player graphics is read from a pointer. The pointer points to the portion of ROM with the player definition. When the player graphics are updated, the pointer is updated to point to the area of ROM with the new player graphics. 1 Quote Link to comment Share on other sites More sharing options...
kisrael Posted January 24, 2021 Author Share Posted January 24, 2021 Thanks for the feedback. Sorry if i was unclear- @Karl G got to the small question I was actually asking The rest of the ramble was noticing that it sems like there's not time to set to dozens and dozens of playfield pixels in the overscan + vblank... even with a minimal 3x4 font, that mans each charcter is like 8-12 pixels to set, so that's going to eat up a lot of time. (and I suspected that even a "once every minute timing glitch" would result in drift in the atari as a 60 FPS clock....) Quote Link to comment Share on other sites More sharing options...
+Karl G Posted January 24, 2021 Share Posted January 24, 2021 7 hours ago, kisrael said: Thanks for the feedback. Sorry if i was unclear- @Karl G got to the small question I was actually asking The rest of the ramble was noticing that it sems like there's not time to set to dozens and dozens of playfield pixels in the overscan + vblank... even with a minimal 3x4 font, that mans each charcter is like 8-12 pixels to set, so that's going to eat up a lot of time. (and I suspected that even a "once every minute timing glitch" would result in drift in the atari as a 60 FPS clock....) You're probably right that there's not enough time to create a playfield-based display one playfield pixel at a time. Probably you would need to set the playfield variables directly to save cycles, setting multiple pixels at once from stored data. Quote Link to comment Share on other sites More sharing options...
bogax Posted January 25, 2021 Share Posted January 25, 2021 I guess the answer then is that every thing is precalculated and kept in ROM In the case of a player you just set a pointer to a table in ROM In the case of the playfield the table in ROM gets copied to RAM But you don't have to do it that way According to RT's page you get 1675 cycles in vblank If your clock needed to update every frame and you used 4 digits of 8 bytes each ie 128 pixels, probably not enough time to do a pixel at a time. If your clock only needs to update once a second it probably is enough time. The code I posted takes around 150 cycles to compose the two 3 x 4 digits but it doesn't do a pixel at a time as for accuracy I don't think glitching would be a problem but crystals aren't all that accurate to begin with a really good crystal would be like +-1 second a day I calculate the code I posted at 106 seconds for the 100 second count down I measured it to be 105 in Stella Quote Link to comment Share on other sites More sharing options...
bogax Posted January 26, 2021 Share Posted January 26, 2021 (edited) Here is another clock It counts up seconds to one hour It uses a brute force approach with every thing in 300 bytes of tables/ROM It's more accurate and uses 16 fractional bits (of a second) for the increment it takes about 110 cycles (not counting drawscreen) for the loop in the worst case, ie rollover to 00 00 set optimization noinlinedata dim frames = t.s dim seconds_lo = player0pointerlo dim seconds_hi = player0pointerhi dim minutes_lo = player1pointerlo dim minutes_hi = player1pointerhi dim seconds = seconds_hi.seconds_lo dim minutes = minutes_hi.minutes_lo def frame_time = 4.274 def reset_seconds = seconds_lo = Pxtlo : seconds_hi = Pxthi def reset_minutes = minutes_lo = Pxtlo : minutes_hi = Pxthi const max = 60 * 5 const rollover = Pxtbl + max const Pxthi = >Pxtbl const Pxtlo = <Pxtbl const rollover_hi = >rollover const rollover_lo = <rollover player0x = 79 : player1x = 70 player0y = 40 : player1y = 40 player0height = 4 : player1height = 4 reset_seconds reset_minutes loop COLUP0 = $1C : COLUP1 = $1C drawscreen temp1 = t frames = frames + frame_time if t > temp1 then loop seconds = seconds + 0.02 if seconds_lo <> rollover_lo then loop ; the player height and the bytes per page are coprime ; so rollover_lo only occurs once per cycle reset_seconds minutes = minutes + 0.02 if minutes_lo <> rollover_lo then loop reset_minutes goto loop data Pxtbl $77, $55, $55, $55, $77, $71, $51, $51, $51, $71 $77, $54, $57, $51, $77, $77, $51, $57, $51, $77 $71, $51, $57, $55, $75, $77, $51, $57, $54, $77 $77, $55, $57, $54, $77, $71, $51, $51, $51, $77 $77, $55, $57, $55, $77, $77, $51, $57, $55, $77 $17, $15, $15, $15, $17, $11, $11, $11, $11, $11 $17, $14, $17, $11, $17, $17, $11, $17, $11, $17 $11, $11, $17, $15, $15, $17, $11, $17, $14, $17 $17, $15, $17, $14, $17, $11, $11, $11, $11, $17 $17, $15, $17, $15, $17, $17, $11, $17, $15, $17 $77, $45, $75, $15, $77, $71, $41, $71, $11, $71 $77, $44, $77, $11, $77, $77, $41, $77, $11, $77 $71, $41, $77, $15, $75, $77, $41, $77, $14, $77 $77, $45, $77, $14, $77, $71, $41, $71, $11, $77 $77, $45, $77, $15, $77, $77, $41, $77, $15, $77 $77, $15, $75, $15, $77, $71, $11, $71, $11, $71 $77, $14, $77, $11, $77, $77, $11, $77, $11, $77 $71, $11, $77, $15, $75, $77, $11, $77, $14, $77 $77, $15, $77, $14, $77, $71, $11, $71, $11, $77 $77, $15, $77, $15, $77, $77, $11, $77, $15, $77 $17, $15, $75, $55, $57, $11, $11, $71, $51, $51 $17, $14, $77, $51, $57, $17, $11, $77, $51, $57 $11, $11, $77, $55, $55, $17, $11, $77, $54, $57 $17, $15, $77, $54, $57, $11, $11, $71, $51, $57 $17, $15, $77, $55, $57, $17, $11, $77, $55, $57 $77, $15, $75, $45, $77, $71, $11, $71, $41, $71 $77, $14, $77, $41, $77, $77, $11, $77, $41, $77 $71, $11, $77, $45, $75, $77, $11, $77, $44, $77 $77, $15, $77, $44, $77, $71, $11, $71, $41, $77 $77, $15, $77, $45, $77, $77, $11, $77, $45, $77 end hour_clock.bas hour_clock.bas.bin Edited January 26, 2021 by bogax tweaked the frame_time Quote Link to comment Share on other sites More sharing options...
bogax Posted January 26, 2021 Share Posted January 26, 2021 (edited) I realized I should be doing an increment or a reset of seconds/minutes, not both since I'm going for speed And now the table needs padding to page align Shaves 36 cycles so worst case is ~80 cycles set optimization noinlinedata dim frames = t.s dim seconds_lo = player0pointerlo dim seconds_hi = player0pointerhi dim minutes_lo = player1pointerlo dim minutes_hi = player1pointerhi dim seconds = seconds_hi.seconds_lo dim minutes = minutes_hi.minutes_lo def frame_time = 4.274 def reset_seconds = seconds_lo = Pxtlo : seconds_hi = Pxthi def reset_minutes = minutes_lo = Pxtlo : minutes_hi = Pxthi def inc_seconds = seconds = seconds + 0.02 def inc_minutes = minutes = minutes + 0.02 const max = 59 * 5 const rollover = Pxtbl + max const Pxthi = >Pxtbl const Pxtlo = <Pxtbl const rollover_hi = >rollover const rollover_lo = <rollover player0x = 79 : player1x = 70 player0y = 40 : player1y = 40 player0height = 4 : player1height = 4 reset_seconds reset_minutes loop COLUP0 = $1C : COLUP1 = $1C drawscreen temp1 = t frames = frames + frame_time if t > temp1 then loop if seconds_lo <> rollover_lo then inc_seconds : goto loop ; the player height and the bytes per page are coprime ; so rollover_lo only occurs once per cycle reset_seconds if minutes_lo <> rollover_lo then inc_minutes : goto loop reset_minutes goto loop data table_padding ; padding to align player definitions with a page boundary $00 end data Pxtbl $77, $55, $55, $55, $77, $71, $51, $51, $51, $71 $77, $54, $57, $51, $77, $77, $51, $57, $51, $77 $71, $51, $57, $55, $75, $77, $51, $57, $54, $77 $77, $55, $57, $54, $77, $71, $51, $51, $51, $77 $77, $55, $57, $55, $77, $77, $51, $57, $55, $77 $17, $15, $15, $15, $17, $11, $11, $11, $11, $11 $17, $14, $17, $11, $17, $17, $11, $17, $11, $17 $11, $11, $17, $15, $15, $17, $11, $17, $14, $17 $17, $15, $17, $14, $17, $11, $11, $11, $11, $17 $17, $15, $17, $15, $17, $17, $11, $17, $15, $17 $77, $45, $75, $15, $77, $71, $41, $71, $11, $71 $77, $44, $77, $11, $77, $77, $41, $77, $11, $77 $71, $41, $77, $15, $75, $77, $41, $77, $14, $77 $77, $45, $77, $14, $77, $71, $41, $71, $11, $77 $77, $45, $77, $15, $77, $77, $41, $77, $15, $77 $77, $15, $75, $15, $77, $71, $11, $71, $11, $71 $77, $14, $77, $11, $77, $77, $11, $77, $11, $77 $71, $11, $77, $15, $75, $77, $11, $77, $14, $77 $77, $15, $77, $14, $77, $71, $11, $71, $11, $77 $77, $15, $77, $15, $77, $77, $11, $77, $15, $77 $17, $15, $75, $55, $57, $11, $11, $71, $51, $51 $17, $14, $77, $51, $57, $17, $11, $77, $51, $57 $11, $11, $77, $55, $55, $17, $11, $77, $54, $57 $17, $15, $77, $54, $57, $11, $11, $71, $51, $57 $17, $15, $77, $55, $57, $17, $11, $77, $55, $57 $77, $15, $75, $45, $77, $71, $11, $71, $41, $71 $77, $14, $77, $41, $77, $77, $11, $77, $41, $77 $71, $11, $77, $45, $75, $77, $11, $77, $44, $77 $77, $15, $77, $44, $77, $71, $11, $71, $41, $77 $77, $15, $77, $45, $77, $77, $11, $77, $45, $77 end hour_clock_02.bas hour_clock_02.bas.bin Edited January 26, 2021 by bogax 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.